"use client"; /** * FeedFollowButton — the inline Follow / Follow back affordance shown in a * home-feed PostCard header for authors the viewer doesn't already follow. * * Follows are request-based, so a tap sends a request and the control settles * into a non-interactive "Requested" pill (matching the profile action row). * Anonymous taps route through the auth gate first. */ import { useState } from "react"; import { Clock, UserPlus } from "lucide-react"; import { toast } from "sonner"; import { relationships, SocialError } from "@/lib/social"; import { useAuthGate } from "@/components/auth/auth-gate"; export function FeedFollowButton({ handle, followsYou, requested = false, }: { handle: string; /** The author already follows the viewer → label becomes "Follow back". */ followsYou: boolean; /** Server-truth: the viewer already has a pending follow request to this * author (e.g. sent in a prior session or on the profile page). */ requested?: boolean; }) { const { requireAuth } = useAuthGate(); const [justRequested, setJustRequested] = useState(false); const [busy, setBusy] = useState(false); // Show "Requested" when the server already knows about a pending request or // the viewer just sent one in this session. const showRequested = requested || justRequested; async function follow() { if (busy || showRequested) return; if (!(await requireAuth())) return; setBusy(true); try { await relationships.follow(handle); setJustRequested(true); } catch (err) { toast.error( err instanceof SocialError ? err.message : "Could not follow", { duration: 3000 }, ); } finally { setBusy(false); } } if (showRequested) { return ( Requested ); } return ( ); }