fix(web): harden typed SPA chat lifecycle

Co-Authored-By: Claude Haiku 4.5 <[email protected]>
This commit is contained in:
shaggy (mosaic-dev box)
2026-08-10 00:24:20 -05:00
co-authored by Claude Haiku 4.5
parent b2e005f2b4
commit caebf9ef70
20 changed files with 1778 additions and 125 deletions
+8 -2
View File
@@ -4,6 +4,10 @@ interface ComposerProps {
onSend: (input: { content: string; provider?: string; modelId?: string }) => void;
onStop: () => void;
streaming: boolean;
/** True from local send time through server turn startup/ack and
* throughout streaming — a superset of `streaming` that also covers the
* pre-ack window where a second send could otherwise slip through. */
sending: boolean;
hasConversation: boolean;
}
@@ -11,14 +15,16 @@ export function Composer({
onSend,
onStop,
streaming,
sending,
hasConversation,
}: ComposerProps): ReactElement {
const [content, setContent] = useState('');
const [provider, setProvider] = useState('');
const [modelId, setModelId] = useState('');
const busy = streaming || sending;
function submit(): void {
if (streaming) return;
if (busy) return;
const trimmed = content.trim();
if (!trimmed) return;
onSend({
@@ -72,7 +78,7 @@ export function Composer({
/>
<button
type="submit"
disabled={!content.trim() || streaming}
disabled={!content.trim() || busy}
className="rounded px-3 py-2 text-sm font-medium"
>
Send