mirror of
https://github.com/anomalyco/opencode.git
synced 2026-08-05 01:49:53 +00:00
fix(tui): keep closed tabs closed
This commit is contained in:
parent
3f30203b72
commit
74e7137c10
2 changed files with 57 additions and 14 deletions
|
|
@ -1,4 +1,4 @@
|
|||
import { createEffect, createMemo, createSignal, onCleanup } from "solid-js"
|
||||
import { createEffect, createMemo, createSignal, on, onCleanup } from "solid-js"
|
||||
import { isDeepEqual } from "remeda"
|
||||
import { createSimpleContext } from "./helper"
|
||||
import { useClient } from "./client"
|
||||
|
|
@ -126,22 +126,40 @@ export const { use: useSessionTabs, provider: SessionTabsProvider } = createSimp
|
|||
})
|
||||
}
|
||||
|
||||
createEffect(
|
||||
on(
|
||||
[
|
||||
() => (enabled() && route.data.type === "session" ? route.data.sessionID : undefined),
|
||||
() => config.tabs?.scope,
|
||||
() => paths.cwd,
|
||||
],
|
||||
([routed]) => {
|
||||
if (!routed || routed === "dummy") return
|
||||
const sessionID = root(routed)
|
||||
history = recordSessionTabHistory(history, sessionID)
|
||||
const fallback = newTab() ? NEW_SESSION_TAB_TITLE : undefined
|
||||
update((draft) => {
|
||||
draft.tabs = openSessionTab(draft.tabs, {
|
||||
sessionID,
|
||||
title: title(sessionID, draft.tabs.find((tab) => tab.sessionID === sessionID)?.title, fallback),
|
||||
})
|
||||
delete draft.unread[sessionID]
|
||||
})
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
createEffect(() => {
|
||||
if (!enabled()) return
|
||||
if (route.data.type !== "session" || route.data.sessionID === "dummy") return
|
||||
if (!enabled() || route.data.type !== "session" || route.data.sessionID === "dummy") return
|
||||
const sessionID = root(route.data.sessionID)
|
||||
history = recordSessionTabHistory(history, sessionID)
|
||||
const fallback = newTab() ? NEW_SESSION_TAB_TITLE : undefined
|
||||
const tabs = openSessionTab(state().tabs, {
|
||||
sessionID,
|
||||
title: title(sessionID, state().tabs.find((tab) => tab.sessionID === sessionID)?.title, fallback),
|
||||
})
|
||||
if (tabs === state().tabs && !state().unread[sessionID]) return
|
||||
const tab = state().tabs.find((tab) => tab.sessionID === sessionID)
|
||||
if (!tab) return
|
||||
const nextTitle = title(sessionID, tab.title)
|
||||
if ((!nextTitle || nextTitle === tab.title) && !state().unread[sessionID]) return
|
||||
update((draft) => {
|
||||
draft.tabs = openSessionTab(draft.tabs, {
|
||||
sessionID,
|
||||
title: title(sessionID, draft.tabs.find((tab) => tab.sessionID === sessionID)?.title, fallback),
|
||||
})
|
||||
const tab = draft.tabs.find((tab) => tab.sessionID === sessionID)
|
||||
if (!tab) return
|
||||
draft.tabs = openSessionTab(draft.tabs, { sessionID, title: title(sessionID, tab.title) })
|
||||
delete draft.unread[sessionID]
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -170,6 +170,31 @@ test("concurrent TUIs do not alternate shared tab titles from divergent session
|
|||
}
|
||||
})
|
||||
|
||||
test("closing a tab is not undone by another TUI viewing the same session", async () => {
|
||||
const state = stateDir("opencode-session-tabs-shared-close-")
|
||||
const first = await renderSessionTabs("shared", { state })
|
||||
const second = await renderSessionTabs("shared", { state })
|
||||
|
||||
try {
|
||||
await wait(() => first.tabs.tabs().some((tab) => tab.sessionID === "shared"))
|
||||
await wait(() => second.tabs.tabs().some((tab) => tab.sessionID === "shared"))
|
||||
first.tabs.close()
|
||||
await wait(() => first.route.data.type === "home")
|
||||
await wait(() => !second.tabs.tabs().some((tab) => tab.sessionID === "shared"))
|
||||
await Bun.sleep(50)
|
||||
|
||||
expect(first.tabs.tabs().some((tab) => tab.sessionID === "shared")).toBe(false)
|
||||
|
||||
second.route.navigate({ type: "home" })
|
||||
await wait(() => second.route.data.type === "home")
|
||||
second.route.navigate({ type: "session", sessionID: "shared" })
|
||||
await wait(() => first.tabs.tabs().some((tab) => tab.sessionID === "shared"))
|
||||
} finally {
|
||||
first.destroy()
|
||||
second.destroy()
|
||||
}
|
||||
})
|
||||
|
||||
test("user prompt admissions pulse an already-busy background tab", async () => {
|
||||
const setup = await renderSessionTabs("background")
|
||||
const admitted = (sessionID: string, inputID: string): OpenCodeEvent => ({
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue