Files
waste-go/web/src/components/MessagePane.tsx

69 lines
2.3 KiB
TypeScript
Raw Normal View History

import { useEffect, useRef, useState } from 'react'
import { useWaste } from '../store'
export function MessagePane() {
const { messages, activeRoom, activeNetworkId, localPeer, connectedPeers, send } = useWaste()
const [draft, setDraft] = useState('')
const bottomRef = useRef<HTMLDivElement>(null)
const roomMessages = messages[activeRoom] ?? []
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:')) {
// Find peer ID from room name — stored as full ID in room key after "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 ?? fromId.slice(0, 8)
}
return (
<main className="message-pane">
<div className="message-pane-header">
{activeRoom.startsWith('dm:') ? `@ ${activeRoom.slice(3, 11)}` : `# ${activeRoom}`}
</div>
<div className="messages">
{roomMessages.map((msg, i) => {
const mine = msg.from === localPeer?.id
return (
<div key={msg.mid ?? i} className={`message ${mine ? 'mine' : ''}`}>
<span className="message-alias">{aliasFor(msg.from)}</span>
<span className="message-text">{msg.text}</span>
<span className="message-ts">{new Date(msg.ts).toLocaleTimeString()}</span>
</div>
)
})}
<div ref={bottomRef} />
</div>
<form className="compose" onSubmit={submit}>
<input
value={draft}
onChange={e => setDraft(e.target.value)}
placeholder={`Message ${activeRoom}`}
autoComplete="off"
/>
<button type="submit" disabled={!draft.trim()}>Send</button>
</form>
</main>
)
}