import { useEffect, useRef } from 'react'; import { useThreadStore } from '../stores/thread.ts'; import { useMessageStore } from '../stores/message.ts'; import ReactMarkdown from 'react-markdown'; import remarkGfm from 'remark-gfm'; interface ThreadPanelProps { threadId: string; threadName: string; onClose: () => void; } function formatTime(iso: string): string { const date = new Date(iso); return `${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`; } export function ThreadPanel({ threadId, threadName, onClose }: ThreadPanelProps) { const messages = useThreadStore((s) => s.messagesByThread[threadId] || []); const fetchMessages = useThreadStore((s) => s.fetchThreadMessages); const sendMessage = useThreadStore((s) => s.sendThreadMessage); const addMessage = useThreadStore((s) => s.addThreadMessage); const removeMessage = useMessageStore((s) => s.removeMessage); const bottomRef = useRef(null); const inputRef = useRef(null); useEffect(() => { fetchMessages(threadId); }, [threadId, fetchMessages]); useEffect(() => { bottomRef.current?.scrollIntoView({ behavior: 'auto' }); }, [messages]); // Listen for gateway messages scoped to this thread channel. useEffect(() => { const handler = (e: MessageEvent) => { try { const event = JSON.parse(e.data); if (event.type === 'MESSAGE_CREATE' && event.data?.channel_id === threadId) { addMessage(event.data); } if (event.type === 'MESSAGE_DELETE' && event.data?.channel_id === threadId) { removeMessage(threadId, event.data.id); } } catch { // ignore } }; window.addEventListener('message', handler); return () => window.removeEventListener('message', handler); }, [threadId, addMessage, removeMessage]); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); const value = inputRef.current?.value.trim(); if (!value) return; await sendMessage(threadId, value); if (inputRef.current) inputRef.current.value = ''; }; return (
→ {threadName}
{messages.map((m) => (
[{formatTime(m.created_at)}]{' '} <{m.author_username}>{' '} }}> {m.content}
))}
{'>'}
); }