Ver Fonte

tui: simplify model dialog ordering logic to reduce complexity

Dax Raad há 2 meses atrás
pai
commit
350982e636

+ 41 - 61
packages/opencode/src/cli/cmd/tui/component/dialog-model.tsx

@@ -6,6 +6,7 @@ import { DialogSelect, type DialogSelectRef } from "@tui/ui/dialog-select"
 import { useDialog } from "@tui/ui/dialog"
 import { createDialogProviderOptions, DialogProvider } from "./dialog-provider"
 import { Keybind } from "@/util/keybind"
+import { iife } from "@/util/iife"
 
 export function DialogModel() {
   const local = useLocal()
@@ -23,71 +24,46 @@ export function DialogModel() {
     const query = ref()?.filter
     const favorites = connected() ? local.model.favorite() : []
     const recents = local.model.recent()
-    const currentModel = local.model.current()
 
-    const orderedRecents = currentModel
-      ? [
-          currentModel,
-          ...recents.filter(
-            (item) => item.providerID !== currentModel.providerID || item.modelID !== currentModel.modelID,
-          ),
-        ]
-      : recents
-
-    const isCurrent = (item: { providerID: string; modelID: string }) =>
-      currentModel && item.providerID === currentModel.providerID && item.modelID === currentModel.modelID
-
-    const currentIsFavorite = currentModel && favorites.some((fav) => isCurrent(fav))
-
-    const recentList = orderedRecents
+    const recentList = recents
       .filter((item) => !favorites.some((fav) => fav.providerID === item.providerID && fav.modelID === item.modelID))
       .slice(0, 5)
 
-    const orderedFavorites = currentModel
-      ? [...favorites.filter((item) => isCurrent(item)), ...favorites.filter((item) => !isCurrent(item))]
-      : favorites
-
-    const orderedRecentList =
-      currentModel && !currentIsFavorite
-        ? [...recentList.filter((item) => isCurrent(item)), ...recentList.filter((item) => !isCurrent(item))]
-        : recentList
-
-    const favoriteOptions =
-      !query && favorites.length > 0
-        ? orderedFavorites.flatMap((item) => {
-            const provider = sync.data.provider.find((x) => x.id === item.providerID)
-            if (!provider) return []
-            const model = provider.models[item.modelID]
-            if (!model) return []
-            return [
-              {
-                key: item,
-                value: {
-                  providerID: provider.id,
-                  modelID: model.id,
-                },
-                title: model.name ?? item.modelID,
-                description: provider.name,
-                category: "Favorites",
-                disabled: provider.id === "opencode" && model.id.includes("-nano"),
-                footer: model.cost?.input === 0 && provider.id === "opencode" ? "Free" : undefined,
-                onSelect: () => {
-                  dialog.clear()
-                  local.model.set(
-                    {
-                      providerID: provider.id,
-                      modelID: model.id,
-                    },
-                    { recent: true },
-                  )
-                },
+    const favoriteOptions = !query
+      ? favorites.flatMap((item) => {
+          const provider = sync.data.provider.find((x) => x.id === item.providerID)
+          if (!provider) return []
+          const model = provider.models[item.modelID]
+          if (!model) return []
+          return [
+            {
+              key: item,
+              value: {
+                providerID: provider.id,
+                modelID: model.id,
               },
-            ]
-          })
-        : []
+              title: model.name ?? item.modelID,
+              description: provider.name,
+              category: "Favorites",
+              disabled: provider.id === "opencode" && model.id.includes("-nano"),
+              footer: model.cost?.input === 0 && provider.id === "opencode" ? "Free" : undefined,
+              onSelect: () => {
+                dialog.clear()
+                local.model.set(
+                  {
+                    providerID: provider.id,
+                    modelID: model.id,
+                  },
+                  { recent: true },
+                )
+              },
+            },
+          ]
+        })
+      : []
 
     const recentOptions = !query
-      ? orderedRecentList.flatMap((item) => {
+      ? recentList.flatMap((item) => {
           const provider = sync.data.provider.find((x) => x.id === item.providerID)
           if (!provider) return []
           const model = provider.models[item.modelID]
@@ -140,7 +116,11 @@ export function DialogModel() {
               return {
                 value,
                 title: info.name ?? model,
-                description: connected() ? provider.name : undefined,
+                description: favorites.some(
+                  (item) => item.providerID === value.providerID && item.modelID === value.modelID,
+                )
+                  ? "(Favorite)"
+                  : undefined,
                 category: connected() ? provider.name : undefined,
                 disabled: provider.id === "opencode" && model.includes("-nano"),
                 footer: info.cost?.input === 0 && provider.id === "opencode" ? "Free" : undefined,
@@ -162,10 +142,10 @@ export function DialogModel() {
               const inFavorites = favorites.some(
                 (item) => item.providerID === value.providerID && item.modelID === value.modelID,
               )
-              const inRecents = orderedRecents.some(
+              if (inFavorites) return false
+              const inRecents = recents.some(
                 (item) => item.providerID === value.providerID && item.modelID === value.modelID,
               )
-              if (inFavorites) return false
               if (inRecents) return false
               return true
             }),

+ 17 - 13
packages/opencode/src/cli/cmd/tui/ui/dialog-select.tsx

@@ -173,8 +173,10 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
   }
   props.ref?.(ref)
 
+  const keybinds = createMemo(() => props.keybind?.filter((x) => !x.disabled) ?? [])
+
   return (
-    <box gap={1}>
+    <box gap={1} paddingBottom={1}>
       <box paddingLeft={4} paddingRight={4}>
         <box flexDirection="row" justifyContent="space-between">
           <text fg={theme.text} attributes={TextAttributes.BOLD}>
@@ -255,18 +257,20 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
           )}
         </For>
       </scrollbox>
-      <box paddingRight={2} paddingLeft={4} flexDirection="row" paddingBottom={1} gap={2}>
-        <For each={(props.keybind ?? []).filter((x) => !x.disabled)}>
-          {(item) => (
-            <text>
-              <span style={{ fg: theme.text }}>
-                <b>{item.title}</b>{" "}
-              </span>
-              <span style={{ fg: theme.textMuted }}>{Keybind.toString(item.keybind)}</span>
-            </text>
-          )}
-        </For>
-      </box>
+      <Show when={keybinds().length} fallback={<box flexShrink={0} />}>
+        <box paddingRight={2} paddingLeft={4} flexDirection="row" gap={2} flexShrink={0} paddingTop={1}>
+          <For each={keybinds()}>
+            {(item) => (
+              <text>
+                <span style={{ fg: theme.text }}>
+                  <b>{item.title}</b>{" "}
+                </span>
+                <span style={{ fg: theme.textMuted }}>{Keybind.toString(item.keybind)}</span>
+              </text>
+            )}
+          </For>
+        </box>
+      </Show>
     </box>
   )
 }