import { useEffect, useRef, useState } from "react"; import { useParams } from "react-router-dom"; import { useConversationStore, type ConversationMessage } from "../stores/conversation.ts"; import { useAuthStore } from "../stores/auth.ts"; import ReactMarkdown from "react-markdown"; import remarkGfm from "remark-gfm"; function formatTime(iso: string): string { const date = new Date(iso); const hours = date.getHours().toString().padStart(2, "0"); const minutes = date.getMinutes().toString().padStart(2, "0"); return `${hours}:${minutes}`; } function renderDMContent(content: string) { return ( , code: ({ ...props }) => , pre: ({ ...props }) =>
,
        blockquote: ({ ...props }) => 
, p: ({ ...props }) => , }} > {content} ); } export function DMChat() { const { conversationId } = useParams<{ conversationId: string }>(); const activeId = useConversationStore((s) => s.activeConversationId); const setActive = useConversationStore((s) => s.setActiveConversation); const conversations = useConversationStore((s) => s.conversations); const messagesByConv = useConversationStore((s) => s.messagesByConversation); const fetchMessages = useConversationStore((s) => s.fetchMessages); const sendMessage = useConversationStore((s) => s.sendMessage); const fetchConversations = useConversationStore((s) => s.fetchConversations); const currentUser = useAuthStore((s) => s.user); const [input, setInput] = useState(""); const [error, setError] = useState(null); const bottomRef = useRef(null); const id = conversationId || activeId; const conversation = conversations.find((c) => c.id === id); const messages = id ? messagesByConv[id] || [] : []; useEffect(() => { fetchConversations(); }, [fetchConversations]); useEffect(() => { if (id) { setActive(id); fetchMessages(id); setError(null); } }, [id, setActive, fetchMessages]); useEffect(() => { bottomRef.current?.scrollIntoView({ behavior: "auto" }); }, [messages]); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (!id || !input.trim()) return; setError(null); try { await sendMessage(id, input.trim()); setInput(""); } catch (err) { setError(err instanceof Error ? err.message : "Failed to send"); } }; const selfDM = conversation && conversation.members.length === 1 && conversation.members[0].id === currentUser?.id; const title = selfDM ? "Notes" : conversation ? conversation.type === "group_dm" ? conversation.name || conversation.members.map((m) => m.username).join(", ") : conversation.members.find((m) => m.id !== currentUser?.id)?.username || "DM" : id ? "[LOADING...]" : "[NO CONVERSATION]"; return (
@ {title}
{!id &&

[select a conversation]

} {id && messages.length === 0 &&

[no messages]

} {messages.map((msg: ConversationMessage) => (
[{formatTime(msg.created_at)}]{" "} <{msg.author_username}>{" "} {renderDMContent(msg.content)}
))}
{error && (

ERR: {error}

)}
{">"} setInput(e.target.value)} placeholder="type a message..." className="terminal-input w-full" disabled={!id} />
); }