From aa56ae04ea895aac81e98ee02b07ac8f3d27d1dd Mon Sep 17 00:00:00 2001 From: Adam Malczewski Date: Mon, 22 Jun 2026 03:13:56 +0900 Subject: fix(composer): single context-aware button — Send/Queue/Stop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit One button to the right of the text input: - idle → Send (starts a turn) - generating + text → Queue (steers via chat.queue) - generating + empty → Stop (aborts via POST /stop) --- src/features/chat/ui/Composer.svelte | 42 +++++++++++++++++------------------- 1 file changed, 20 insertions(+), 22 deletions(-) (limited to 'src/features') diff --git a/src/features/chat/ui/Composer.svelte b/src/features/chat/ui/Composer.svelte index 5952eca..7030153 100644 --- a/src/features/chat/ui/Composer.svelte +++ b/src/features/chat/ui/Composer.svelte @@ -37,12 +37,16 @@ const usage = $derived(computeContextUsage(contextSize, MAX_CONTEXT)); const hasUsage = $derived(contextSize !== undefined); - // While a turn is generating, the send button becomes a "Queue" button that - // enqueues a steering message (`chat.queue`) instead of starting a new turn - // (`chat.send`). Falls back to `onSend` when no `onQueue` is wired. - const steering = $derived(status === "running" && onQueue !== undefined); - const submitLabel = $derived(steering ? "Queue" : "Send"); - const placeholder = $derived(steering ? "Steer the conversation..." : "Type a message..."); + // One button, three modes: + // - idle → "Send" (starts a turn via chat.send) + // - running + text → "Queue" (steers via chat.queue) + // - running + empty → "Stop" (aborts via POST /stop) + const buttonMode = $derived.by<"send" | "queue" | "stop">(() => { + if (status === "running" && !hasText && onStop !== undefined) return "stop"; + if (status === "running" && hasText && onQueue !== undefined) return "queue"; + return "send"; + }); + const placeholder = $derived(status === "running" ? "Steer the conversation..." : "Type a message..."); // As the window fills, escalate color: calm → warning → danger. function fillClass(pct: number): string { @@ -76,7 +80,7 @@ function handleSubmit(): void { const trimmed = text.trim(); if (trimmed.length === 0) return; - if (steering) { + if (buttonMode === "queue") { onQueue?.(trimmed); } else { onSend(trimmed); @@ -99,7 +103,7 @@ handleSubmit(); }} > - +
- - {#if status === "running" && onStop} + {#if buttonMode === "stop"} + {:else} + {/if}
-- cgit v1.2.3