feat(chat): stop an in-flight answer — Send becomes Stop, the partial is kept and persisted, the model stream is torn down
This commit is contained in:
+17
-2
@@ -125,7 +125,23 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<form class="composer" id="composer">
|
||||
<!-- Composer (phase 48, 2026-08-29, TODO.md L3): one button, two
|
||||
roles — #send-btn reads "Send" when idle and morphs into the
|
||||
enabled "Stop" control (.is-stop, rose treatment) while a turn
|
||||
is in flight; a click or Enter in flight aborts the fetch
|
||||
(AbortController in app.js) and the partial is kept + persisted
|
||||
with the optional `stopped` marker, rendered as the .stopped-note
|
||||
meta-row note by app.js — live and on restore. The spinner span
|
||||
stays in the markup (contract marker, reduced-motion pin) but
|
||||
never shows: the Stop label + treatment carry the in-flight
|
||||
state.
|
||||
`novalidate`: the input is cleared after send, so a `required`
|
||||
constraint would silently block the Stop click/Enter — the
|
||||
browser's constraint validation runs before the `submit` event
|
||||
and would never reach handleSend's in-flight guard. The
|
||||
`!text` guard in app.js is the real empty-input check (same
|
||||
precedent as the tuning form's noValidate). -->
|
||||
<form class="composer" id="composer" novalidate>
|
||||
<label class="visually-hidden" for="message-input">Ask Brain of Reese a question</label>
|
||||
<textarea
|
||||
id="message-input"
|
||||
@@ -133,7 +149,6 @@
|
||||
rows="1"
|
||||
placeholder="Ask me about the homelab…"
|
||||
autocomplete="off"
|
||||
required
|
||||
></textarea>
|
||||
<button type="submit" class="send-btn" id="send-btn">
|
||||
<span class="spinner" aria-hidden="true" hidden></span>
|
||||
|
||||
Reference in New Issue
Block a user