diff --git a/src/components/MainLayout.tsx b/src/components/MainLayout.tsx index 3f2d259e..9828497c 100644 --- a/src/components/MainLayout.tsx +++ b/src/components/MainLayout.tsx @@ -80,7 +80,7 @@ function MainLayoutInner() { {/* Main layout - three column on desktop */} -
+
{/* Desktop left sidebar - hidden below sidebar breakpoint */}
diff --git a/src/pages/VinesFeedPage.tsx b/src/pages/VinesFeedPage.tsx index b7e30171..9587f708 100644 --- a/src/pages/VinesFeedPage.tsx +++ b/src/pages/VinesFeedPage.tsx @@ -624,11 +624,9 @@ export function VinesFeedPage() { [events], ); - // Reset active index when tab or vine list changes significantly + // Reset active index when tab changes useEffect(() => { setActiveIndex(0); - const container = containerRef.current; - if (container) container.scrollTop = 0; }, [tab]); const activeVine = vines[activeIndex]; @@ -656,20 +654,10 @@ export function VinesFeedPage() { }; }, [commentsOpen]); - // Snap-scroll to a specific vine index - const scrollToIndex = useCallback((index: number) => { - const container = containerRef.current; - if (!container) return; - const target = container.children[index] as HTMLElement | undefined; - if (!target) return; - target.scrollIntoView({ behavior: 'smooth', block: 'start' }); - }, []); - - // Update active index based on intersection + // Sync activeIndex when CSS snap settles (touch swipe, mouse wheel, trackpad) useEffect(() => { const container = containerRef.current; if (!container) return; - const observer = new IntersectionObserver( (entries) => { for (const entry of entries) { @@ -681,30 +669,30 @@ export function VinesFeedPage() { }, { root: container, threshold: 0.5 }, ); - - const kids = Array.from(container.children); - kids.forEach((child) => observer.observe(child)); + Array.from(container.children).forEach((child) => observer.observe(child)); return () => observer.disconnect(); }, [vines]); // Keyboard arrow navigation useEffect(() => { const handleKey = (e: KeyboardEvent) => { + const container = containerRef.current; + if (!container) return; if (e.key === 'ArrowDown') { e.preventDefault(); const next = Math.min(activeIndex + 1, vines.length - 1); + container.scrollTo({ top: next * container.clientHeight, behavior: 'smooth' }); setActiveIndex(next); - scrollToIndex(next); } else if (e.key === 'ArrowUp') { e.preventDefault(); const prev = Math.max(activeIndex - 1, 0); + container.scrollTo({ top: prev * container.clientHeight, behavior: 'smooth' }); setActiveIndex(prev); - scrollToIndex(prev); } }; window.addEventListener('keydown', handleKey); return () => window.removeEventListener('keydown', handleKey); - }, [activeIndex, vines.length, scrollToIndex]); + }, [activeIndex, vines.length]); // ── Loading state ──────────────────────────────────────────────────────── if (isLoading) { @@ -765,26 +753,24 @@ export function VinesFeedPage() { {/* ── Scroll container ────────────────────────────────────────── */} -
-
- {vines.map((event, i) => ( -
- -
- ))} -
+
+ {vines.map((event, i) => ( +
+ +
+ ))}
{/* ── Mobile comments panel — full overlay, xl:hidden ─────────── */}