diff --git a/components/feed/new-users-strip.tsx b/components/feed/new-users-strip.tsx index 474d6832..e7c27fdb 100644 --- a/components/feed/new-users-strip.tsx +++ b/components/feed/new-users-strip.tsx @@ -18,7 +18,14 @@ export function NewUsersStrip({ users }: { users: UserSummary[] }) { // Mouse drag-to-scroll. Touch/trackpad use native overflow scrolling, so we // only engage for mouse; `moved` suppresses the click that would otherwise // fire after a drag (and navigate to a profile). - const drag = useRef({ down: false, startX: 0, startScroll: 0, moved: false }); + const drag = useRef({ + down: false, + startX: 0, + startScroll: 0, + moved: false, + pointerId: -1, + captured: false, + }); if (users.length === 0) return null; @@ -26,26 +33,41 @@ export function NewUsersStrip({ users }: { users: UserSummary[] }) { if (e.pointerType !== "mouse") return; const el = scrollRef.current; if (!el) return; + // Record the start but DON'T capture yet — capturing here would retarget + // the click to this container, so a plain click on a card never reaches + // the (no navigation). We capture only once a real drag starts. drag.current = { down: true, startX: e.clientX, startScroll: el.scrollLeft, moved: false, + pointerId: e.pointerId, + captured: false, }; - el.setPointerCapture(e.pointerId); } function onPointerMove(e: React.PointerEvent) { if (!drag.current.down) return; const el = scrollRef.current; if (!el) return; const dx = e.clientX - drag.current.startX; - if (Math.abs(dx) > 4) drag.current.moved = true; - el.scrollLeft = drag.current.startScroll - dx; + if (Math.abs(dx) > 4) { + drag.current.moved = true; + // Capture now so the drag keeps tracking even if the pointer leaves + // the strip; a click (no movement) never gets here, so it navigates. + if (!drag.current.captured) { + el.setPointerCapture(drag.current.pointerId); + drag.current.captured = true; + } + } + if (drag.current.moved) el.scrollLeft = drag.current.startScroll - dx; } - function onPointerUp(e: React.PointerEvent) { + function onPointerUp() { if (!drag.current.down) return; drag.current.down = false; - scrollRef.current?.releasePointerCapture(e.pointerId); + if (drag.current.captured) { + scrollRef.current?.releasePointerCapture(drag.current.pointerId); + drag.current.captured = false; + } } function onClickCapture(e: React.MouseEvent) { if (drag.current.moved) { @@ -76,7 +98,7 @@ export function NewUsersStrip({ users }: { users: UserSummary[] }) { onPointerUp={onPointerUp} onPointerCancel={onPointerUp} onClickCapture={onClickCapture} - className="-mx-5 flex gap-3 overflow-x-auto px-5 py-1 snap-x scroll-px-5 cursor-grab active:cursor-grabbing [scrollbar-width:none] [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden" + className="-mx-5 flex gap-3 overflow-x-auto px-5 py-1 snap-x scroll-px-5 cursor-grab select-none active:cursor-grabbing [scrollbar-width:none] [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden" > {users.map((u) => (