mirror of
https://github.com/anomalyco/opencode.git
synced 2026-09-10 08:15:07 +00:00
fix(app): keep the browser attachment and tab menu reliable
This commit is contained in:
parent
5f6a75fa23
commit
b676c4fe0e
3 changed files with 21 additions and 1 deletions
|
|
@ -42,10 +42,24 @@ export function createSessionBrowser(session: SessionModel) {
|
|||
const owner = session.ownership.capture()
|
||||
const target = { sessionID, endpoint: server.conn.http }
|
||||
let registration: BrowserPaneRegistration | undefined
|
||||
let retry: ReturnType<typeof setTimeout> | undefined
|
||||
let attempts = 0
|
||||
const register = () => {
|
||||
if (registration) return
|
||||
registration = pane.register(target, (event) =>
|
||||
owner.run(() => (event.type === "open" ? open() : setState({ browser: event.state, error: event.error }))),
|
||||
owner.run(() => {
|
||||
if (event.type === "open") return open()
|
||||
// The desktop dropped the attachment (server restart, attach race).
|
||||
// Re-register so the agent's browser tool comes back without a reload.
|
||||
if (event.error === "browser.pane.registration.closed") {
|
||||
registration?.close()
|
||||
registration = undefined
|
||||
setState({ registration: undefined, browser: null, error: undefined })
|
||||
retry = setTimeout(register, Math.min(30_000, 1_000 * 2 ** attempts++))
|
||||
return
|
||||
}
|
||||
setState({ browser: event.state, error: event.error })
|
||||
}),
|
||||
)
|
||||
setState({ registration, browser: null, error: undefined })
|
||||
}
|
||||
|
|
@ -56,6 +70,7 @@ export function createSessionBrowser(session: SessionModel) {
|
|||
if (!session.shared.data.session.creating(sessionID)) register()
|
||||
onCleanup(() => {
|
||||
unsubscribe()
|
||||
clearTimeout(retry)
|
||||
registration?.close()
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -442,6 +442,9 @@ export function SessionSidePanel(props: {
|
|||
variant="ghost-muted"
|
||||
size="large"
|
||||
aria-label={language.t("session.tab.add")}
|
||||
// The tablist redirects focus entering it to the selected
|
||||
// tab, which counts as focus-outside and closes the menu.
|
||||
onPointerDown={(event: PointerEvent) => event.preventDefault()}
|
||||
/>
|
||||
<Menu.Portal>
|
||||
<Menu.Content>
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@ export function createDesktopPlatform(
|
|||
if (!closed && value.bindingID === bindingID) onEvent(value.event)
|
||||
})
|
||||
const ready = api.browserPane.request({ type: "register", bindingID, target })
|
||||
// Failures reach the owner through the closed-state event; keep the bare promise handled.
|
||||
void ready.catch(() => undefined)
|
||||
return {
|
||||
setLayout(layout) {
|
||||
if (!closed)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue