refactor(stream): simplify FilterChips by dropping the 1.5s scroll watcher
All checks were successful
Deploy to Frontend Servers / deploy (push) Successful in 38s
All checks were successful
Deploy to Frontend Servers / deploy (push) Successful in 38s
The defensive rAF + scroll loop and its touching guard were added to fight an iOS sticky-relayout quirk, but the module-level lastScrollLeft plus the useLayoutEffect mount restore already cover the common case. The watch loop also interfered with a fresh slide gesture immediately after a filter tap. Strip it out together with the surrounding inline comments so the component is the minimum needed: gold active state on click and a remount-surviving scroll position.
This commit is contained in:
35
.unipi/docs/fix/2026-06-03-filter-chips-simplify-fix.md
Normal file
35
.unipi/docs/fix/2026-06-03-filter-chips-simplify-fix.md
Normal file
@@ -0,0 +1,35 @@
|
||||
---
|
||||
title: "FilterChips simplify — strip comments and remove 1.5s watch window"
|
||||
type: quick-fix
|
||||
date: 2026-06-03
|
||||
---
|
||||
|
||||
# FilterChips simplify — strip comments and remove 1.5s watch window
|
||||
|
||||
## Bug
|
||||
The previous `FilterChips` carried too much defensive machinery (long inline comments, a 1.5s post-mount `requestAnimationFrame` + `scroll`-event watch window that re-applied `lastScrollLeft` whenever the bar snapped to 0). The watch window could interfere with a fresh slide gesture right after a filter tap, and the surrounding prose made the component hard to read.
|
||||
|
||||
## Root Cause
|
||||
Over-engineering: the iOS-quirk watch loop and its `touching` guard were added defensively but were not strictly needed once `lastScrollLeft` was lifted out to a module-level slot and restored synchronously in `useLayoutEffect`. The extra event listeners were also a source of friction when the user immediately slid the bar after tapping a chip.
|
||||
|
||||
## Fix
|
||||
Reduce `FilterChips` to just the essentials:
|
||||
|
||||
- Module-level `lastScrollLeft` (kept) — survives the `AnimatePresence` remount that happens when `?type=…` changes.
|
||||
- `useLayoutEffect` on mount (kept) — restores `scrollLeft = lastScrollLeft` before paint so the new instance starts where the user left off.
|
||||
- Desktop wheel-to-horizontal handler (kept) — necessary for mice without horizontal wheels.
|
||||
- Save effect on `touchend` / `pointerup` / `wheel` (kept) — captures the user's final scroll position, deferred by one rAF so iOS momentum settles before recording.
|
||||
- Removed: the ~1.5s rAF + `scroll` watch loop and its `touching` flag.
|
||||
- Removed: all explanatory inline comments — the code is short enough to be self-evident now.
|
||||
|
||||
### Files Modified
|
||||
- `src/components/messageStream/FilterChips.tsx` — stripped the 1.5s watch effect and every prose comment; kept the mount-restore and user-input save flow.
|
||||
|
||||
## Verification
|
||||
- `npx tsc --noEmit` — clean.
|
||||
- `npm run format:check` — clean.
|
||||
- `npm test` — 49/49 passing.
|
||||
- Behavior expected on device: tapping a filter highlights it in gold; sliding the bar after the tap is no longer pulled back to the previous position.
|
||||
|
||||
## Notes
|
||||
- If the iOS sticky/scroll-to-top quirk actually re-surfaces in production, the fallback would be to move the bar out of the `AnimatePresence`-keyed subtree (so it never unmounts), rather than re-introducing the watch loop.
|
||||
Reference in New Issue
Block a user