Skip to content
This repository was archived by the owner on Apr 1, 2026. It is now read-only.

Commit dbbcf0b

Browse files
committed
tui: fix model selection dialog to properly replace current dialog instead of creating nested dialogs
1 parent efac8ce commit dbbcf0b

3 files changed

Lines changed: 41 additions & 34 deletions

File tree

packages/desktop/src/components/prompt-input.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -864,7 +864,9 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
864864
as="div"
865865
variant="ghost"
866866
onClick={() =>
867-
dialog.push(() => (providers.paid().length > 0 ? <DialogSelectModel /> : <DialogSelectModelUnpaid />))
867+
dialog.replace(() =>
868+
providers.paid().length > 0 ? <DialogSelectModel /> : <DialogSelectModelUnpaid />,
869+
)
868870
}
869871
>
870872
{local.model.current()?.name ?? "Select model"}

packages/desktop/src/context/notification.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ export const { use: useNotification, provider: NotificationProvider } = createSi
5858
time: Date.now(),
5959
viewed: false,
6060
}
61+
console.log(event)
6162
switch (event.type) {
6263
case "session.idle": {
6364
const sessionID = event.properties.sessionID

packages/ui/src/context/dialog.tsx

Lines changed: 37 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import {
22
createContext,
3+
createEffect,
34
createMemo,
45
createSignal,
6+
For,
57
getOwner,
68
Owner,
79
ParentProps,
@@ -11,6 +13,7 @@ import {
1113
type JSX,
1214
} from "solid-js"
1315
import { Dialog as Kobalte } from "@kobalte/core/dialog"
16+
import { iife } from "@opencode-ai/util/iife"
1417

1518
type DialogElement = () => JSX.Element
1619

@@ -25,23 +28,49 @@ function init() {
2528
}[]
2629
>([])
2730

28-
return {
31+
const result = {
2932
get stack() {
3033
return store()
3134
},
32-
push(element: DialogElement, owner: Owner, onClose?: () => void) {
33-
setStore((s) => [...s, { element, onClose, owner }])
34-
},
3535
pop() {
3636
const current = store().at(-1)
37+
if (!current) return
3738
current?.onClose?.()
38-
setStore((stack) => stack.slice(0, -1))
39+
setStore((stack) => {
40+
stack.pop()
41+
return [...stack]
42+
})
3943
},
4044
replace(element: DialogElement, owner: Owner, onClose?: () => void) {
4145
for (const item of store()) {
4246
item.onClose?.()
4347
}
44-
setStore([{ element, onClose, owner }])
48+
setStore([
49+
{
50+
element: () =>
51+
runWithOwner(owner, () => (
52+
<Show when={result.stack.at(-1)?.owner === owner}>
53+
<Kobalte
54+
modal
55+
defaultOpen
56+
onOpenChange={(open) => {
57+
if (!open) {
58+
onClose?.()
59+
result.pop()
60+
}
61+
}}
62+
>
63+
<Kobalte.Portal>
64+
<Kobalte.Overlay data-component="dialog-overlay" />
65+
{element()}
66+
</Kobalte.Portal>
67+
</Kobalte>
68+
</Show>
69+
)),
70+
onClose,
71+
owner,
72+
},
73+
])
4574
},
4675
clear() {
4776
for (const item of store()) {
@@ -50,38 +79,16 @@ function init() {
5079
setStore([])
5180
},
5281
}
82+
return result
5383
}
5484

5585
export function DialogProvider(props: ParentProps) {
5686
const ctx = init()
57-
const last = createMemo(() => ctx.stack.at(-1))
5887
return (
5988
<Context.Provider value={ctx}>
6089
{props.children}
6190
<div data-component="dialog-stack">
62-
<Show when={last()}>
63-
{(item) =>
64-
runWithOwner(item().owner, () => {
65-
return (
66-
<Kobalte
67-
modal
68-
defaultOpen
69-
onOpenChange={(open) => {
70-
if (!open) {
71-
item().onClose?.()
72-
ctx.pop()
73-
}
74-
}}
75-
>
76-
<Kobalte.Portal>
77-
<Kobalte.Overlay data-component="dialog-overlay" />
78-
{item().element()}
79-
</Kobalte.Portal>
80-
</Kobalte>
81-
)
82-
})
83-
}
84-
</Show>
91+
<For each={ctx.stack}>{(item) => <>{item.element()}</>}</For>
8592
</div>
8693
</Context.Provider>
8794
)
@@ -103,9 +110,6 @@ export function useDialog() {
103110
replace(element: DialogElement, onClose?: () => void) {
104111
ctx.replace(element, owner, onClose)
105112
},
106-
push(element: DialogElement, onClose?: () => void) {
107-
ctx.push(element, owner, onClose)
108-
},
109113
pop() {
110114
ctx.pop()
111115
},

0 commit comments

Comments
 (0)