"use client"; /** * /u/[handle]/posts — public Instagram-style scroll feed. * * Mirrors /u/me/posts but read-only (no Delete / Update background). The * grid thumbnail on /u/[handle] links here with a `#post-` hash so * the feed scrolls to the tapped post on mount. */ import { use, useEffect, useRef, useState } from "react"; import { notFound } from "next/navigation"; import { profile, SocialError, type Post } from "@/lib/social"; import { PostScrollCard } from "@/components/social/post-scroll-card"; export default function PublicPostsFeedPage(props: { params: Promise<{ handle: string }>; }) { const { handle } = use(props.params); const [feed, setFeed] = useState([]); const [loading, setLoading] = useState(true); const [missing, setMissing] = useState(false); const scrolledToHashRef = useRef(false); useEffect(() => { let cancelled = false; setLoading(true); profile .feed(handle, 60) .then((rows) => { if (cancelled) return; setFeed(rows ?? []); }) .catch((err) => { if (err instanceof SocialError && err.status === 404) { setMissing(true); } }) .finally(() => !cancelled && setLoading(false)); return () => { cancelled = true; }; }, [handle]); useEffect(() => { if (loading || feed.length === 0 || scrolledToHashRef.current) return; if (typeof window === "undefined") return; const hash = window.location.hash; if (!hash) return; scrolledToHashRef.current = true; requestAnimationFrame(() => { const el = document.getElementById(hash.slice(1)); if (el) el.scrollIntoView({ block: "start", behavior: "auto" }); }); }, [loading, feed.length]); if (missing) notFound(); return (
{loading ? (

Loading…

) : feed.length === 0 ? (

No posts yet.

) : ( feed.map((p) => ) )}
); }