v0.0.32 - Convert send button to stop button during agent runs (remove separate stop-btn)
This commit is contained in:
+2
-2
@@ -11,9 +11,9 @@
|
||||
#ifndef SOVEREIGN_BROWSER_VERSION_H
|
||||
#define SOVEREIGN_BROWSER_VERSION_H
|
||||
|
||||
#define SB_VERSION "v0.0.31"
|
||||
#define SB_VERSION "v0.0.32"
|
||||
#define SB_VERSION_MAJOR 0
|
||||
#define SB_VERSION_MINOR 0
|
||||
#define SB_VERSION_PATCH 31
|
||||
#define SB_VERSION_PATCH 32
|
||||
|
||||
#endif /* SOVEREIGN_BROWSER_VERSION_H */
|
||||
|
||||
+14
-4
@@ -378,10 +378,6 @@ html.dark .skill-badge-unsaved {
|
||||
#composer-host {
|
||||
flex: 1; min-width: 0;
|
||||
}
|
||||
#stop-btn {
|
||||
flex-shrink: 0; min-width: 80px; margin-left: 0;
|
||||
}
|
||||
|
||||
/* The shared post-composer library wraps the host element: it inserts a
|
||||
* .post-composer-wrapper around #composer-host and appends the send
|
||||
* button as a SIBLING of the host (inside the wrapper). So the send
|
||||
@@ -408,6 +404,20 @@ html.dark .skill-badge-unsaved {
|
||||
#input-area .post-composer-send-btn:disabled {
|
||||
opacity: 0.5; cursor: not-allowed;
|
||||
}
|
||||
/* Stop-mode: the send button transforms into a stop button while the
|
||||
* agent is running. Use a distinct (red-ish) style to signal that
|
||||
* clicking it will cancel the agent. */
|
||||
#input-area .post-composer-send-btn.is-stop-mode {
|
||||
border-color: var(--danger, #c33);
|
||||
color: var(--danger, #c33);
|
||||
background: transparent;
|
||||
}
|
||||
#input-area .post-composer-send-btn.is-stop-mode:hover,
|
||||
#input-area .post-composer-send-btn.is-stop-mode:focus {
|
||||
background: var(--danger, #c33);
|
||||
color: #fff;
|
||||
border-color: var(--danger, #c33);
|
||||
}
|
||||
|
||||
/* ── Responsive: narrow sidebar viewport (< 400px) ──────────────
|
||||
* When the chat page is loaded in the agent sidebar (~350px wide),
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
</div>
|
||||
<div id="input-area">
|
||||
<div id="composer-host"></div>
|
||||
<button id="stop-btn" class="btn btn-del" style="display:none" onclick="cancelAgent()">Stop</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
+16
-6
@@ -467,7 +467,6 @@ function clearStatusMessage() {
|
||||
* fallback. Posts status messages as system bubbles in the chat
|
||||
* window instead of updating a status bar. */
|
||||
function applyStatus(s) {
|
||||
var stopBtn = document.getElementById('stop-btn');
|
||||
var map = {idle:'Idle', thinking:'Thinking...',
|
||||
tool_call:'Calling tool', complete:'Complete',
|
||||
error:'Error', cancelled:'Cancelled'};
|
||||
@@ -492,13 +491,24 @@ function applyStatus(s) {
|
||||
}
|
||||
|
||||
var running = (s.state === 'thinking' || s.state === 'tool_call');
|
||||
if (stopBtn) stopBtn.style.display = running ? '' : 'none';
|
||||
if (composerApi && typeof composerApi.setDisabled === 'function') {
|
||||
/* Disable while running OR when no chat is selected. The composer
|
||||
* must never be enabled if there is no active conversation. */
|
||||
/* Convert the send button into a stop button while the agent is
|
||||
* running, instead of showing a separate stop button. The user can't
|
||||
* send again anyway while the agent is working. */
|
||||
if (composerApi) {
|
||||
var hasChat = (currentConvId !== null && currentConvId !== undefined &&
|
||||
String(currentConvId) !== '');
|
||||
composerApi.setDisabled(running || !hasChat);
|
||||
if (running) {
|
||||
if (typeof composerApi.setStopMode === 'function') {
|
||||
composerApi.setStopMode(cancelAgent);
|
||||
}
|
||||
} else {
|
||||
if (typeof composerApi.clearStopMode === 'function') {
|
||||
composerApi.clearStopMode();
|
||||
}
|
||||
if (typeof composerApi.setDisabled === 'function') {
|
||||
composerApi.setDisabled(!hasChat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* On transition to complete/error/cancelled, fetch final
|
||||
|
||||
@@ -264,6 +264,15 @@ window.mountComposer = function mountComposer(hostEl, options = {}) {
|
||||
sendButton.textContent = 'Send';
|
||||
sendButton.disabled = true;
|
||||
|
||||
/* Stop-mode state: when active, the send button transforms into a
|
||||
* stop button (different label, click handler, and styling). This is
|
||||
* used by the agent chat to let the user cancel an in-progress agent
|
||||
* run without needing a separate stop button. */
|
||||
let stopModeActive = false;
|
||||
let stopModeHandler = null;
|
||||
const sendLabel = 'Send';
|
||||
const stopLabel = 'Stop';
|
||||
|
||||
if (layout === 'inline') {
|
||||
wrapper.classList.add('post-composer-wrapper--inline');
|
||||
if (showPreview) wrapper.appendChild(previewEl);
|
||||
@@ -733,6 +742,11 @@ window.mountComposer = function mountComposer(hostEl, options = {}) {
|
||||
}
|
||||
|
||||
async function onSendClick() {
|
||||
/* In stop mode, the button acts as Stop — route to the stop handler. */
|
||||
if (stopModeActive) {
|
||||
if (stopModeHandler) stopModeHandler();
|
||||
return;
|
||||
}
|
||||
if (sendButton.disabled) return;
|
||||
if (!onSubmit) return;
|
||||
|
||||
@@ -827,6 +841,27 @@ window.mountComposer = function mountComposer(hostEl, options = {}) {
|
||||
externallyDisabled = !!disabled;
|
||||
updateSendButtonVisibility();
|
||||
},
|
||||
/* Convert the send button into a stop button. The provided handler
|
||||
* is called when the user clicks the (now stop) button. The text
|
||||
* area is NOT disabled — the user can type their next message while
|
||||
* the agent runs, but the button acts as Stop until clearStopMode()
|
||||
* is called. */
|
||||
setStopMode(handler) {
|
||||
stopModeActive = true;
|
||||
stopModeHandler = typeof handler === 'function' ? handler : null;
|
||||
sendButton.textContent = stopLabel;
|
||||
sendButton.classList.add('is-stop-mode');
|
||||
sendButton.disabled = false;
|
||||
sendButton.classList.add('is-visible');
|
||||
},
|
||||
/* Revert the stop button back to a send button. */
|
||||
clearStopMode() {
|
||||
stopModeActive = false;
|
||||
stopModeHandler = null;
|
||||
sendButton.textContent = sendLabel;
|
||||
sendButton.classList.remove('is-stop-mode');
|
||||
updateSendButtonVisibility();
|
||||
},
|
||||
show() {
|
||||
showComposer();
|
||||
},
|
||||
|
||||
@@ -264,6 +264,15 @@ export function mountComposer(hostEl, options = {}) {
|
||||
sendButton.textContent = 'Send';
|
||||
sendButton.disabled = true;
|
||||
|
||||
/* Stop-mode state: when active, the send button transforms into a
|
||||
* stop button (different label, click handler, and styling). This is
|
||||
* used by the agent chat to let the user cancel an in-progress agent
|
||||
* run without needing a separate stop button. */
|
||||
let stopModeActive = false;
|
||||
let stopModeHandler = null;
|
||||
const sendLabel = 'Send';
|
||||
const stopLabel = 'Stop';
|
||||
|
||||
if (layout === 'inline') {
|
||||
wrapper.classList.add('post-composer-wrapper--inline');
|
||||
if (showPreview) wrapper.appendChild(previewEl);
|
||||
@@ -733,6 +742,11 @@ export function mountComposer(hostEl, options = {}) {
|
||||
}
|
||||
|
||||
async function onSendClick() {
|
||||
/* In stop mode, the button acts as Stop — route to the stop handler. */
|
||||
if (stopModeActive) {
|
||||
if (stopModeHandler) stopModeHandler();
|
||||
return;
|
||||
}
|
||||
if (sendButton.disabled) return;
|
||||
if (!onSubmit) return;
|
||||
|
||||
@@ -827,6 +841,21 @@ export function mountComposer(hostEl, options = {}) {
|
||||
externallyDisabled = !!disabled;
|
||||
updateSendButtonVisibility();
|
||||
},
|
||||
setStopMode(handler) {
|
||||
stopModeActive = true;
|
||||
stopModeHandler = typeof handler === 'function' ? handler : null;
|
||||
sendButton.textContent = stopLabel;
|
||||
sendButton.classList.add('is-stop-mode');
|
||||
sendButton.disabled = false;
|
||||
sendButton.classList.add('is-visible');
|
||||
},
|
||||
clearStopMode() {
|
||||
stopModeActive = false;
|
||||
stopModeHandler = null;
|
||||
sendButton.textContent = sendLabel;
|
||||
sendButton.classList.remove('is-stop-mode');
|
||||
updateSendButtonVisibility();
|
||||
},
|
||||
show() {
|
||||
showComposer();
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user