import { Dialog } from "@opencode-ai/ui/dialog" import { FileIcon } from "@opencode-ai/ui/file-icon" import { Icon } from "@opencode-ai/ui/icon" import { Keybind } from "@opencode-ai/ui/keybind" import { List } from "@opencode-ai/ui/list" import { getDirectory, getFilename } from "@opencode-ai/core/util/path" import { createMemo, createSignal, lazy, Match, Show, Switch } from "solid-js" import { formatKeybind } from "@/context/command" import { useServerSDK } from "@/context/server-sdk" import { useLanguage } from "@/context/language" import { usePlatform } from "@/context/platform" import { useSettings } from "@/context/settings" import { useSessionLayout } from "@/pages/session/session-layout" import { decode64 } from "@/utils/base64" import { getRelativeTime } from "@/utils/time" import { createCommandPaletteFileEntry, createCommandPaletteFileOpener, createCommandPaletteModel, uniqueCommandPaletteEntries, type CommandPaletteEntry, } from "./command-palette" import { DialogCommandPaletteV2 } from "./dialog-command-palette-v2" const DialogSelectFileV2 = lazy(() => import("./dialog-select-directory-v2").then((module) => ({ default: module.DialogSelectDirectoryV2 })), ) type DialogSelectFileMode = "all" | "files" export function DialogSelectFile(props: { mode?: DialogSelectFileMode; onOpenFile?: (path: string) => void }) { const platform = usePlatform() const settings = useSettings() const filesOnly = () => props.mode === "files" if (!filesOnly() && settings.general.newLayoutDesigns()) { return } if (filesOnly() && platform.platform === "desktop" && settings.general.newLayoutDesigns()) { return } return } function DialogSelectFileDesktopV2(props: { onOpenFile?: (path: string) => void }) { const language = useLanguage() const serverSDK = useServerSDK() const { params } = useSessionLayout() const projectDirectory = createMemo(() => decode64(params.dir) ?? "") const openFile = createCommandPaletteFileOpener(props.onOpenFile) return ( { if (typeof result !== "string") return openFile(result) }} /> ) } function DialogSelectFileLegacy(props: { filesOnly: () => boolean; onOpenFile?: (path: string) => void }) { const palette = createCommandPaletteModel(props) const [grouped, setGrouped] = createSignal(false) const items = async (text: string) => { const query = text.trim() setGrouped(query.length > 0) if (!query && props.filesOnly()) { const loaded = palette.file.tree.state("")?.loaded const pending = loaded ? Promise.resolve() : palette.file.tree.list("") const next = uniqueCommandPaletteEntries([...palette.recentFileEntries(), ...palette.rootFileEntries()]) if (loaded || next.length > 0) { void pending return next } await pending return uniqueCommandPaletteEntries([...palette.recentFileEntries(), ...palette.rootFileEntries()]) } if (!query) return [...palette.preferredCommandEntries(), ...palette.recentFileEntries()] if (props.filesOnly()) { const files = await palette.file.searchFiles(query) const category = palette.language.t("palette.group.files") return files.map((path) => createCommandPaletteFileEntry(path, category)) } const [files, nextSessions] = await Promise.all([ palette.file.searchFiles(query), Promise.resolve(palette.sessions(query)), ]) const category = palette.language.t("palette.group.files") const entries = files.map((path) => createCommandPaletteFileEntry(path, category)) return [...palette.commandEntries(), ...nextSessions, ...entries] } return ( item.id} filterKeys={["title", "description", "category"]} skipFilter={(item) => item.type === "file"} groupBy={grouped() ? (item) => item.category : () => ""} onMove={(item: CommandPaletteEntry | undefined) => palette.highlight(item)} onSelect={(item: CommandPaletteEntry | undefined) => palette.select(item)} > {(item) => ( {getDirectory(item.path ?? "")} {getFilename(item.path ?? "")} } > {item.title} {item.description} {formatKeybind(item.keybind ?? "", palette.language.t)} {item.title} {item.description} {getRelativeTime(new Date(item.updated!).toISOString(), palette.language.t)} )} ) }