"use client"; /** * /u/me/posts — the owner's Instagram-style scroll feed. * * Reached by tapping a thumbnail from the /u/me Posts grid. The clicked * post's id arrives as a `#post-` hash, and `scroll-mt-*` on each * card spaces it below the sticky header so the anchor lands cleanly. * * Owner controls (Delete + Update background) are mounted per-card. */ import { useEffect, useRef, useState } from "react"; import { useAuth } from "@/components/auth/auth-provider"; import { PostScrollCard } from "@/components/social/post/post-scroll-card"; import { ConfirmModal } from "@/components/ui/confirm-modal"; import { posts, SocialError, type Post } from "@/lib/social"; export default function MyPostsFeedPage() { const { user } = useAuth(); const [feed, setFeed] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [pendingDelete, setPendingDelete] = useState(null); const scrolledToHashRef = useRef(false); useEffect(() => { if (!user) return; posts .mine() .then((rows) => setFeed(rows ?? [])) .catch((err) => setError( err instanceof SocialError ? err.message : "Could not load posts.", ), ) .finally(() => setLoading(false)); }, [user]); // Hash anchor: when the feed mounts, jump to the post identified in the // URL hash. Defer one tick so the cards have laid out and `scroll-mt-*` // can position the anchor below the sticky header. 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]); async function performDelete() { const id = pendingDelete; if (!id) return; const prev = feed; setFeed((rows) => rows.filter((p) => p.id !== id)); try { await posts.delete(id); } catch (err) { setFeed(prev); const msg = err instanceof SocialError ? err.message : "Could not delete."; setError(msg); // Re-throw so ConfirmModal surfaces the failure and stays open. throw new Error(msg); } } function onPostUpdated(updated: Post) { setFeed((rows) => rows.map((p) => (p.id === updated.id ? updated : p))); } if (!user) return null; return (
{error ? (

{error}

) : loading ? (

Loading…

) : feed.length === 0 ? (

No posts yet.

) : ( feed.map((p) => ( setPendingDelete(id)} onUpdated={onPostUpdated} /> )) )} setPendingDelete(null)} title="Delete this post?" message="The post will be removed permanently from your feed and from any collections it's in. This can't be undone." confirmLabel="Delete post" onConfirm={performDelete} />
); }