import { useEffect } from "react"; import { useTranslation } from "react-i18next"; import { useQueryClient } from "@tanstack/react-query"; import { ChevronDown, ChevronUp, X } from "lucide-react"; import { closeChat, toggleMinimize, useDockChats, type DockChat } from "../lib/chatDock"; import { useUnlocked } from "../lib/messaging"; import { onMessage } from "../lib/messagesSocket"; import * as e2ee from "../lib/e2ee"; import Avatar from "./Avatar"; import ChatThread from "./ChatThread"; // The Messenger-style floating chat dock: open conversations live here, bottom-right, across // page navigation. Always mounted (for human users) so it also owns the app-wide live-message // subscription and restores this device's unlock state on load. export default function ChatDock({ meId }: { meId: number }) { const qc = useQueryClient(); const chats = useDockChats(); const unlocked = useUnlocked(); // Restore the per-device unlocked key once, app-wide. useEffect(() => { e2ee.loadFromDevice(meId); }, [meId]); // Live delivery: any pushed message refreshes the conversation list, unread badge, and the // affected thread (re-decrypts). Drives both the dock and the Messages page. useEffect( () => onMessage((m) => { qc.invalidateQueries({ queryKey: ["conversations"] }); qc.invalidateQueries({ queryKey: ["message-unread"] }); const partner = m.sender_id === meId ? m.recipient_id : m.sender_id; qc.invalidateQueries({ queryKey: ["thread", partner] }); }), [qc, meId] ); if (chats.length === 0) return null; return (