repl: route newTab through setActiveTab so toolbar buttons sync
newTab() used to mutate state.activeTabId directly, skipping setActiveTab's auto-pause hook AND the toolbar button-state sync. Opening a new tab during a running eval left the send button disabled on the brand-new (idle) tab — fox would land on a tab he couldn't type into. Now newTab pushes the tab onto state.tabs, then awaits setActiveTab which handles both the outgoing-tab auto-pause (if applicable) and the incoming-tab button sync. Verified end-to-end headless: with COOP/COEP enabled, switching from a c-tier eval to a new tab now correctly snapshots the source tab's state, leaves the send button enabled on tab 2, and on switch-back the resumed eval re-fires from the snapshot.
This commit is contained in:
parent
0b711abd61
commit
ca27d03c60
3 changed files with 54 additions and 15 deletions
|
|
@ -146,13 +146,15 @@ function relock() {
|
|||
}
|
||||
|
||||
// ─── Tabs ───────────────────────────────────────────────────────────
|
||||
function newTab(name) {
|
||||
async function newTab(name) {
|
||||
const id = state.nextTabId++;
|
||||
name = name || `session ${id}`;
|
||||
state.tabs.push({ id, name, tier: "c", transcript: [], inputDraft: "" });
|
||||
state.activeTabId = id;
|
||||
renderAll();
|
||||
saveSoon();
|
||||
// Route through setActiveTab so the outgoing tab's auto-pause
|
||||
// fires and the toolbar buttons sync to the freshly-created
|
||||
// (idle) tab. Without this, opening a new tab during an eval
|
||||
// leaves the send button disabled and the eval orphaned.
|
||||
await setActiveTab(id);
|
||||
}
|
||||
|
||||
function closeTab(id) {
|
||||
|
|
@ -206,8 +208,19 @@ async function setActiveTab(id) {
|
|||
}
|
||||
state.activeTabId = id;
|
||||
renderAll();
|
||||
saveSoon();
|
||||
// Sync the global toolbar button states to the incoming tab —
|
||||
// send/cancel/pause are not tab-scoped DOM elements, so a
|
||||
// switch-away during one tab's eval would otherwise leave the
|
||||
// newly-active (idle) tab with send disabled. The active tab
|
||||
// is idle iff nothing in state.pending matches its id.
|
||||
const incoming = activeTab();
|
||||
if (incoming) {
|
||||
const evalRunning = isEvalInFlight(incoming);
|
||||
sendBtn.disabled = evalRunning;
|
||||
cancelBtn.disabled = !evalRunning;
|
||||
pauseBtn.disabled = !evalRunning || !pauseFlagView;
|
||||
}
|
||||
saveSoon();
|
||||
if (incoming && incoming.autoPause) {
|
||||
await autoResumeTab(incoming);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -146,13 +146,15 @@ function relock() {
|
|||
}
|
||||
|
||||
// ─── Tabs ───────────────────────────────────────────────────────────
|
||||
function newTab(name) {
|
||||
async function newTab(name) {
|
||||
const id = state.nextTabId++;
|
||||
name = name || `session ${id}`;
|
||||
state.tabs.push({ id, name, tier: "c", transcript: [], inputDraft: "" });
|
||||
state.activeTabId = id;
|
||||
renderAll();
|
||||
saveSoon();
|
||||
// Route through setActiveTab so the outgoing tab's auto-pause
|
||||
// fires and the toolbar buttons sync to the freshly-created
|
||||
// (idle) tab. Without this, opening a new tab during an eval
|
||||
// leaves the send button disabled and the eval orphaned.
|
||||
await setActiveTab(id);
|
||||
}
|
||||
|
||||
function closeTab(id) {
|
||||
|
|
@ -206,8 +208,19 @@ async function setActiveTab(id) {
|
|||
}
|
||||
state.activeTabId = id;
|
||||
renderAll();
|
||||
saveSoon();
|
||||
// Sync the global toolbar button states to the incoming tab —
|
||||
// send/cancel/pause are not tab-scoped DOM elements, so a
|
||||
// switch-away during one tab's eval would otherwise leave the
|
||||
// newly-active (idle) tab with send disabled. The active tab
|
||||
// is idle iff nothing in state.pending matches its id.
|
||||
const incoming = activeTab();
|
||||
if (incoming) {
|
||||
const evalRunning = isEvalInFlight(incoming);
|
||||
sendBtn.disabled = evalRunning;
|
||||
cancelBtn.disabled = !evalRunning;
|
||||
pauseBtn.disabled = !evalRunning || !pauseFlagView;
|
||||
}
|
||||
saveSoon();
|
||||
if (incoming && incoming.autoPause) {
|
||||
await autoResumeTab(incoming);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -146,13 +146,15 @@ function relock() {
|
|||
}
|
||||
|
||||
// ─── Tabs ───────────────────────────────────────────────────────────
|
||||
function newTab(name) {
|
||||
async function newTab(name) {
|
||||
const id = state.nextTabId++;
|
||||
name = name || `session ${id}`;
|
||||
state.tabs.push({ id, name, tier: "c", transcript: [], inputDraft: "" });
|
||||
state.activeTabId = id;
|
||||
renderAll();
|
||||
saveSoon();
|
||||
// Route through setActiveTab so the outgoing tab's auto-pause
|
||||
// fires and the toolbar buttons sync to the freshly-created
|
||||
// (idle) tab. Without this, opening a new tab during an eval
|
||||
// leaves the send button disabled and the eval orphaned.
|
||||
await setActiveTab(id);
|
||||
}
|
||||
|
||||
function closeTab(id) {
|
||||
|
|
@ -206,8 +208,19 @@ async function setActiveTab(id) {
|
|||
}
|
||||
state.activeTabId = id;
|
||||
renderAll();
|
||||
saveSoon();
|
||||
// Sync the global toolbar button states to the incoming tab —
|
||||
// send/cancel/pause are not tab-scoped DOM elements, so a
|
||||
// switch-away during one tab's eval would otherwise leave the
|
||||
// newly-active (idle) tab with send disabled. The active tab
|
||||
// is idle iff nothing in state.pending matches its id.
|
||||
const incoming = activeTab();
|
||||
if (incoming) {
|
||||
const evalRunning = isEvalInFlight(incoming);
|
||||
sendBtn.disabled = evalRunning;
|
||||
cancelBtn.disabled = !evalRunning;
|
||||
pauseBtn.disabled = !evalRunning || !pauseFlagView;
|
||||
}
|
||||
saveSoon();
|
||||
if (incoming && incoming.autoPause) {
|
||||
await autoResumeTab(incoming);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue