diff --git a/packages/desktop/src/components/dialog-manage-models.tsx b/packages/desktop/src/components/dialog-manage-models.tsx
index de1c3cb15..5765a8e1a 100644
--- a/packages/desktop/src/components/dialog-manage-models.tsx
+++ b/packages/desktop/src/components/dialog-manage-models.tsx
@@ -27,18 +27,21 @@ export const DialogManageModels: Component = () => {
}}
onSelect={(x) => {
if (!x) return
- local.model.setVisibility({ modelID: x.id, providerID: x.provider.id }, !x.visible)
+ const visible = local.model.visible({ modelID: x.id, providerID: x.provider.id })
+ local.model.setVisibility({ modelID: x.id, providerID: x.provider.id }, !visible)
}}
>
{(i) => (
{i.name}
-
{
- local.model.setVisibility({ modelID: i.id, providerID: i.provider.id }, checked)
- }}
- />
+ e.stopPropagation()}>
+ {
+ local.model.setVisibility({ modelID: i.id, providerID: i.provider.id }, checked)
+ }}
+ />
+
)}
diff --git a/packages/desktop/src/components/dialog-select-model.tsx b/packages/desktop/src/components/dialog-select-model.tsx
index 805db47fe..f0b2e6db9 100644
--- a/packages/desktop/src/components/dialog-select-model.tsx
+++ b/packages/desktop/src/components/dialog-select-model.tsx
@@ -13,11 +13,10 @@ export const DialogSelectModel: Component<{ provider?: string }> = (props) => {
const local = useLocal()
const dialog = useDialog()
- let closeButton!: HTMLButtonElement
const models = createMemo(() =>
local.model
.list()
- .filter((m) => m.visible)
+ .filter((m) => local.model.visible({ modelID: m.id, providerID: m.provider.id }))
.filter((m) => (props.provider ? m.provider.id === props.provider : true)),
)
@@ -58,7 +57,7 @@ export const DialogSelectModel: Component<{ provider?: string }> = (props) => {
local.model.set(x ? { modelID: x.id, providerID: x.provider.id } : undefined, {
recent: true,
})
- closeButton.click()
+ dialog.clear()
}}
>
{(i) => (
diff --git a/packages/desktop/src/context/local.tsx b/packages/desktop/src/context/local.tsx
index 0970178ea..56154c5ba 100644
--- a/packages/desktop/src/context/local.tsx
+++ b/packages/desktop/src/context/local.tsx
@@ -132,10 +132,10 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
Object.values(p.models).map((m) => ({
...m,
provider: p,
- user: store.user.find((x) => x.modelID === m.id && x.providerID === p.id),
})),
),
)
+
const latest = createMemo(() =>
pipe(
available(),
@@ -163,10 +163,6 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
...m,
name: m.name.replace("(latest)", "").trim(),
latest: m.name.includes("(latest)"),
- visible:
- m.user?.visibility !== "hide" &&
- (latest().find((x) => x.modelID === m.id && x.providerID === m.provider.id) ||
- store.user.find((x) => x.modelID === m.id && x.providerID === m.provider.id)?.visibility === "show"),
})),
)
@@ -241,7 +237,7 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
if (index >= 0) {
setStore("user", index, { visibility })
} else {
- setStore("user", (prev) => [...prev, { ...model, visibility }])
+ setStore("user", store.user.length, { ...model, visibility })
}
}
@@ -260,11 +256,13 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
}
})
},
- show(model: ModelKey) {
- updateVisibility(model, "show")
- },
- hide(model: ModelKey) {
- updateVisibility(model, "hide")
+ visible(model: ModelKey) {
+ const user = store.user.find((x) => x.modelID === model.modelID && x.providerID === model.providerID)
+ return (
+ user?.visibility !== "hide" &&
+ (latest().find((x) => x.modelID === model.modelID && x.providerID === model.providerID) ||
+ user?.visibility === "show")
+ )
},
setVisibility(model: ModelKey, visible: boolean) {
updateVisibility(model, visible ? "show" : "hide")
diff --git a/packages/ui/src/components/list.tsx b/packages/ui/src/components/list.tsx
index 2923956a9..7ec6e159d 100644
--- a/packages/ui/src/components/list.tsx
+++ b/packages/ui/src/components/list.tsx
@@ -1,4 +1,4 @@
-import { createEffect, Show, For, type JSX, createSignal } from "solid-js"
+import { createEffect, on, Show, For, type JSX, createSignal } from "solid-js"
import { createStore } from "solid-js/store"
import { FilteredListProps, useFilteredList } from "@opencode-ai/ui/hooks"
import { Icon, IconProps } from "./icon"
@@ -32,24 +32,34 @@ export function List(props: ListProps & { ref?: (ref: ListRef) => void })
mouseActive: false,
})
- const { filter, grouped, flat, reset, active, setActive, onKeyDown, onInput } = useFilteredList(props)
+ const { filter, grouped, flat, active, setActive, onKeyDown, onInput } = useFilteredList(props)
const searchProps = () => (typeof props.search === "object" ? props.search : {})
- const hasSearch = () => !!props.search
createEffect(() => {
if (props.filter !== undefined) {
onInput(props.filter)
- } else if (hasSearch()) {
- onInput(internalFilter())
}
})
- createEffect(() => {
- filter()
- scrollRef()?.scrollTo(0, 0)
- reset()
- })
+ createEffect((prev) => {
+ if (!props.search) return
+ const current = internalFilter()
+ if (prev !== current) {
+ onInput(current)
+ }
+ return current
+ }, "")
+
+ createEffect(
+ on(
+ filter,
+ () => {
+ scrollRef()?.scrollTo(0, 0)
+ },
+ { defer: true },
+ ),
+ )
createEffect(() => {
if (!scrollRef()) return
@@ -100,7 +110,7 @@ export function List(props: ListProps & { ref?: (ref: ListRef) => void })
return (