import { useEffect, useMemo, useState } from 'react'; import { useConversations } from '../hooks/use-conversations'; import { useAdapter } from '../provider'; import { ConversationList } from './conversation-list'; import { ChannelBrowser } from './channel-browser'; import { NewConversation } from './new-conversation'; import { Thread } from './thread'; import { ThreadPane } from './thread-pane'; /** * The drop-in messenger: sectioned conversation list (Channels / Direct messages) + open thread, * with a channel browser when the adapter supports channels. Owns only selection + browse state; * all data flows through the injected adapter via the hooks. */ export function Messenger() { const { conversations, loading, error, refetch } = useConversations(); const adapter = useAdapter(); const channelsSupported = typeof adapter.browseChannels === 'function'; const directorySupported = typeof adapter.directory === 'function'; const [selected, setSelected] = useState(null); const [browsing, setBrowsing] = useState(false); const [composing, setComposing] = useState(false); // "New message" people picker open const [activeRoot, setActiveRoot] = useState(null); // open thread pane's root message useEffect(() => { if (browsing || composing) return; if (selected && conversations.some((c) => c.threadId === selected)) return; setSelected(conversations[0]?.threadId ?? null); }, [conversations, selected, browsing, composing]); // Switching conversations (or into browse/compose) closes any open thread pane. useEffect(() => setActiveRoot(null), [selected, browsing, composing]); const channels = useMemo(() => conversations.filter((c) => c.membership === 'channel'), [conversations]); const dms = useMemo(() => conversations.filter((c) => c.membership !== 'channel'), [conversations]); const selectedConversation = useMemo(() => conversations.find((c) => c.threadId === selected) ?? null, [conversations, selected]); function pick(threadId: string): void { setBrowsing(false); setComposing(false); setSelected(threadId); } function openBrowse(): void { setComposing(false); setBrowsing(true); } function openCompose(): void { setBrowsing(false); setComposing(true); } return (
{browsing ? ( { refetch(); pick(threadId); }} /> ) : composing ? ( { refetch(); pick(threadId); }} /> ) : ( { refetch(); setSelected(null); }} /> )}
{!browsing && !composing && selected && activeRoot ? ( setActiveRoot(null)} /> ) : null}
); }