useMessages
Per-ticket message stream. Subscribes to realtime updates while mounted, sends new messages, and
cleans up on unmount. Pair with useTyping for the indicators.
Usage
TicketThread.tsx
import { useMessages, useTyping } from '@cstar.help/react';
import { useState } from 'react';
export function TicketThread({ ticketId }) {
const { messages, isLoading, send } = useMessages(ticketId);
const { typingAgents } = useTyping(ticketId);
const [draft, setDraft] = useState('');
if (isLoading) return <p>Loading...</p>;
return (
<div>
{messages.map((m) => (
<p key={m.id}>
<strong>{m.sender_name}:</strong> {m.content}
</p>
))}
{typingAgents.length > 0 && (
<p className="typing">
{typingAgents.map((a) => a.agentName).join(', ')} typing…
</p>
)}
<input value={draft} onChange={(e) => setDraft(e.target.value)} />
<button onClick={async () => {
await send({ content: draft });
setDraft('');
}}>
Send
</button>
</div>
);
} What it returns
messages: array. Auto-updates when new messages arrive over realtime.isLoading: boolean.error: Error | null.send(params): Promise. Optimistic insert plus server confirm.refresh(): Promise.