fix(layout): remove min-h-screen from main wrapper to prevent outer-page scroll on vines
This commit is contained in:
@@ -80,7 +80,7 @@ function MainLayoutInner() {
|
||||
<MobileDrawer open={drawerOpen} onOpenChange={setDrawerOpen} />
|
||||
|
||||
{/* Main layout - three column on desktop */}
|
||||
<div className={cn("flex justify-center min-h-screen mx-auto max-w-[1200px]", wrapperClassName)}>
|
||||
<div className={cn("flex justify-center mx-auto max-w-[1200px]", wrapperClassName)}>
|
||||
{/* Desktop left sidebar - hidden below sidebar breakpoint */}
|
||||
<div className="hidden sidebar:block">
|
||||
<LeftSidebar />
|
||||
|
||||
+26
-40
@@ -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() {
|
||||
<VinesTabBar tab={tab} onTabChange={setTab} hasUser={!!user} />
|
||||
|
||||
{/* ── Scroll container ────────────────────────────────────────── */}
|
||||
<div className="relative flex-1">
|
||||
<div
|
||||
ref={containerRef}
|
||||
className={cn("vine-slide-height sidebar:h-[calc(100vh-3rem)] snap-y snap-mandatory", commentsOpen ? "overflow-hidden" : "overflow-y-scroll")}
|
||||
style={{ scrollbarWidth: 'none', msOverflowStyle: 'none' }}
|
||||
>
|
||||
{vines.map((event, i) => (
|
||||
<div
|
||||
key={event.id}
|
||||
className="w-full vine-slide-height sidebar:h-[calc(100vh-3rem)] snap-start snap-always flex-shrink-0"
|
||||
>
|
||||
<VineCard
|
||||
event={event}
|
||||
isActive={i === activeIndex}
|
||||
isNearActive={Math.abs(i - activeIndex) <= 1}
|
||||
onCommentClick={handleCommentClick}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div
|
||||
ref={containerRef}
|
||||
className="vine-slide-height sidebar:h-[calc(100vh-3rem)] snap-y snap-mandatory overflow-y-scroll"
|
||||
style={{ scrollbarWidth: 'none', msOverflowStyle: 'none', overscrollBehavior: 'none' }}
|
||||
>
|
||||
{vines.map((event, i) => (
|
||||
<div
|
||||
key={event.id}
|
||||
className="w-full vine-slide-height sidebar:h-[calc(100vh-3rem)] snap-start snap-always flex-shrink-0"
|
||||
>
|
||||
<VineCard
|
||||
event={event}
|
||||
isActive={i === activeIndex}
|
||||
isNearActive={Math.abs(i - activeIndex) <= 1}
|
||||
onCommentClick={handleCommentClick}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* ── Mobile comments panel — full overlay, xl:hidden ─────────── */}
|
||||
|
||||
Reference in New Issue
Block a user