"use client"; /** * Pick a thread to forward a message into. * * The destination list is the caller's own inbox, so there is no way to name a * thread they aren't in — and the BFF re-checks both memberships anyway, since * a client-supplied conversation id proves nothing. */ import { useEffect, useState } from "react"; import { X } from "lucide-react"; import { toast } from "sonner"; import { UserAvatar } from "@/components/ui/user-avatar"; import { chat, conversationTitle, groupAvatarUrl, type ChatMessage, type InboxItem, } from "@/lib/chat"; export function ForwardDialog({ message, onClose, }: { message: ChatMessage; onClose: () => void; }) { const [threads, setThreads] = useState([]); const [busy, setBusy] = useState(null); const [state, setState] = useState<"loading" | "ready" | "error">("loading"); useEffect(() => { let cancelled = false; chat .inbox("chats") .then((rows) => { if (cancelled) return; setThreads(rows ?? []); setState("ready"); }) .catch(() => !cancelled && setState("error")); return () => { cancelled = true; }; }, []); useEffect(() => { const onKey = (e: KeyboardEvent) => e.key === "Escape" && onClose(); window.addEventListener("keydown", onKey); return () => window.removeEventListener("keydown", onKey); }, [onClose]); const forward = async (to: InboxItem) => { setBusy(to.id); try { await chat.forward(to.id, message.id); toast.success(`Forwarded to ${conversationTitle(to)}`); onClose(); } catch { toast.error("Could not forward the message"); } finally { setBusy(null); } }; return (

Forward to…

{state === "error" ? (

Could not load your chats.

) : state === "loading" ? (

Loading…

) : threads.length === 0 ? (

You have no other chats yet.

) : (
    {threads.map((t) => (
  • ))}
)}
); }