// App-wide store of open floating chat windows (the Messenger-style dock, bottom-right). // A window can be opened from anywhere (e.g. a conversation's "pop out" button) and stays // open across page navigation. Plain external store so any component can read/drive it. import { useSyncExternalStore } from "react"; export interface DockChat { partnerId: number; name: string; avatar: string | null; minimized: boolean; } const MAX_OPEN = 3; // keep the dock from overflowing the corner let chats: DockChat[] = []; const subs = new Set<() => void>(); function emit(next: DockChat[]): void { chats = next; for (const s of subs) s(); } export function openChat(partner: { id: number; name: string; avatar_url: string | null }): void { const existing = chats.find((c) => c.partnerId === partner.id); if (existing) { // Re-opening focuses it: ensure expanded and move to the front. emit([ { ...existing, minimized: false }, ...chats.filter((c) => c.partnerId !== partner.id), ]); return; } const next = [ { partnerId: partner.id, name: partner.name, avatar: partner.avatar_url, minimized: false }, ...chats, ].slice(0, MAX_OPEN); emit(next); } export function closeChat(partnerId: number): void { emit(chats.filter((c) => c.partnerId !== partnerId)); } export function toggleMinimize(partnerId: number): void { emit(chats.map((c) => (c.partnerId === partnerId ? { ...c, minimized: !c.minimized } : c))); } export function useDockChats(): DockChat[] { return useSyncExternalStore( (cb) => { subs.add(cb); return () => subs.delete(cb); }, () => chats, () => chats ); }