import { useEffect, useRef, useState } from 'react' import { useWaste } from '../store' const today = new Date() today.setHours(0, 0, 0, 0) const todayMs = today.getTime() function formatTs(ts: number): string { const d = new Date(ts) const time = d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', hour12: false }) if (ts >= todayMs) return time return d.toLocaleDateString([], { month: 'short', day: 'numeric' }) + ' ' + time } export function MessagePane() { const { messages, historyCutoff, activeRoom, activeNetworkId, localPeer, connectedPeers, knownPeers, send } = useWaste() const [draft, setDraft] = useState('') const bottomRef = useRef(null) const roomMessages = messages[activeRoom] ?? [] const cutoff = historyCutoff[activeRoom] ?? 0 // Find the index of the first live message (ts > cutoff). // The divider appears just before this index, or at the top if all are history. const firstLiveIdx = cutoff > 0 ? roomMessages.findIndex(m => m.ts > cutoff) : -1 // If all messages are history (no live yet), put divider at the start. const dividerIdx = cutoff > 0 ? (firstLiveIdx === -1 ? 0 : firstLiveIdx) : -1 useEffect(() => { bottomRef.current?.scrollIntoView({ behavior: 'smooth' }) }, [roomMessages.length]) function submit(e: React.FormEvent) { e.preventDefault() const text = draft.trim() if (!text || !activeNetworkId) return if (activeRoom.startsWith('dm:')) { const toPeerID = activeRoom.slice(3) const peer = connectedPeers.find(p => p.id.startsWith(toPeerID) || p.id === toPeerID) if (peer) { send({ type: 'send_message', network_id: activeNetworkId, room: activeRoom, body: text, to: peer.id }) } } else { send({ type: 'send_message', network_id: activeNetworkId, room: activeRoom, body: text }) } setDraft('') } function aliasFor(fromId: string) { if (fromId === localPeer?.id) return localPeer.alias return connectedPeers.find(p => p.id === fromId)?.alias ?? knownPeers[fromId] ?? fromId.slice(0, 8) } const roomLabel = activeRoom.startsWith('dm:') ? `@ ${activeRoom.slice(3, 11)}…` : `# ${activeRoom}` return (
{roomLabel}
{dividerIdx === 0 && (
earlier messages
)} {roomMessages.map((msg, i) => { const mine = msg.from === localPeer?.id const alias = aliasFor(String(msg.from)) const ts = formatTs(msg.ts) return (
{i === dividerIdx && dividerIdx > 0 && (
earlier messages
)}
{ts} {alias} {msg.text}
) })}
setDraft(e.target.value)} placeholder={`Message ${roomLabel}`} autoComplete="off" />
) }