diff --git a/packages/app/src/components/settings-dialog.tsx b/packages/app/src/components/settings-dialog.tsx new file mode 100644 index 00000000000..d2cc85c04e5 --- /dev/null +++ b/packages/app/src/components/settings-dialog.tsx @@ -0,0 +1,43 @@ +import { useParams } from "@solidjs/router" +import { onCleanup } from "solid-js" +import { useCommand } from "@/context/command" +import { useLanguage } from "@/context/language" +import { useDialog } from "@opencode-ai/ui/context/dialog" + +export function useSettingsDialog() { + const dialog = useDialog() + const params = useParams<{ id?: string }>() + let run = 0 + let dead = false + + onCleanup(() => { + dead = true + }) + + return () => { + const current = ++run + const sessionID = params.id + void import("@/components/settings-v2").then((module) => { + if (dead || run !== current) return + void dialog.show(() => ) + }) + } +} + +export function useSettingsCommand() { + const command = useCommand() + const language = useLanguage() + const show = useSettingsDialog() + + command.register("settings", () => [ + { + id: "settings.open", + title: language.t("command.settings.open"), + category: language.t("command.category.settings"), + keybind: "mod+comma", + onSelect: show, + }, + ]) + + return show +} diff --git a/packages/app/src/components/settings-v2/dialog-settings-v2.tsx b/packages/app/src/components/settings-v2/dialog-settings-v2.tsx index cfe6971b12b..a93a10dcb2f 100644 --- a/packages/app/src/components/settings-v2/dialog-settings-v2.tsx +++ b/packages/app/src/components/settings-v2/dialog-settings-v2.tsx @@ -11,7 +11,9 @@ import { SettingsModelsV2 } from "./models" import "./settings-v2.css" import { SettingsServersV2 } from "./servers" -export const DialogSettings: Component = () => { +export const DialogSettings: Component<{ + sessionID?: string +}> = (props) => { const language = useLanguage() const platform = usePlatform() @@ -62,7 +64,7 @@ export const DialogSettings: Component = () => { - + diff --git a/packages/app/src/components/settings-v2/general.tsx b/packages/app/src/components/settings-v2/general.tsx index c4d3e0d9e79..0dd48a5523c 100644 --- a/packages/app/src/components/settings-v2/general.tsx +++ b/packages/app/src/components/settings-v2/general.tsx @@ -6,7 +6,6 @@ import { Switch } from "@opencode-ai/ui/v2/switch-v2" import { TextInputV2 } from "@opencode-ai/ui/v2/text-input-v2" import { useTheme, type ColorScheme } from "@opencode-ai/ui/theme/context" import { useDialog } from "@opencode-ai/ui/context/dialog" -import { useParams } from "@solidjs/router" import { useLanguage } from "@/context/language" import { usePermission } from "@/context/permission" import { usePlatform } from "@/context/platform" @@ -25,7 +24,6 @@ import { terminalInput, useSettings, } from "@/context/settings" -import { decode64 } from "@/utils/base64" import { playSoundById, SOUND_OPTIONS } from "@/utils/sound" import { Link } from "../link" import { SettingsListV2 } from "./parts/list" @@ -82,50 +80,46 @@ const playDemoSound = (id: string | undefined) => { }, 100) } -export const SettingsGeneralV2: Component = () => { +export const SettingsGeneralV2: Component<{ + sessionID?: string +}> = (props) => { const theme = useTheme() const language = useLanguage() const permission = usePermission() const platform = usePlatform() const dialog = useDialog() - const params = useParams() const settings = useSettings() + const serverSync = useServerSync() + const serverSdk = useServerSDK() const mobile = createMediaQuery("(max-width: 767px)") const updater = useUpdaterAction() - const dir = createMemo(() => decode64(params.dir)) + const dir = createMemo(() => { + if (!props.sessionID) return undefined + return serverSync().session.lineage.peek(props.sessionID)?.session.directory + }) const accepting = createMemo(() => { const value = dir() - if (!value) return false - if (!params.id) return permission.isAutoAcceptingDirectory(value) - return permission.isAutoAccepting(params.id, value) + if (!value || !props.sessionID) return false + return permission.isAutoAccepting(props.sessionID, value) }) const toggleAccept = (checked: boolean) => { const value = dir() - if (!value) return - - if (!params.id) { - if (permission.isAutoAcceptingDirectory(value) === checked) return - permission.toggleAutoAcceptDirectory(value) - return - } + if (!value || !props.sessionID) return if (checked) { - permission.enableAutoAccept(params.id, value) + permission.enableAutoAccept(props.sessionID, value) return } - permission.disableAutoAccept(params.id, value) + permission.disableAutoAccept(props.sessionID, value) } const desktop = createMemo(() => platform.platform === "desktop") const themeOptions = createMemo(() => theme.ids().map((id) => ({ id, name: theme.name(id) }))) - const serverSync = useServerSync() - const serverSdk = useServerSDK() - const [shells] = createResource( () => serverSdk() diff --git a/packages/app/src/pages/home.tsx b/packages/app/src/pages/home.tsx index 6686ab388e7..9f61713ef7a 100644 --- a/packages/app/src/pages/home.tsx +++ b/packages/app/src/pages/home.tsx @@ -33,6 +33,7 @@ import { usePlatform } from "@/context/platform" import { DateTime } from "luxon" import { useDialog } from "@opencode-ai/ui/context/dialog" import { useDirectoryPicker } from "@/components/directory-picker" +import { useSettingsCommand } from "@/components/settings-dialog" import { DialogSelectServer, useServerManagementController } from "@/components/dialog-select-server" import { DialogServerV2 } from "@/components/settings-v2/dialog-server-v2" import { ServerConnection, serverName, useServer } from "@/context/server" @@ -144,6 +145,7 @@ export function NewHome() { const command = useCommand() const notification = useNotification() const marked = useMarked() + const openSettings = useSettingsCommand() let focusSessionSearch: (() => void) | undefined const [state, setState] = createStore({ search: "", @@ -402,12 +404,6 @@ export function NewHome() { }) } - function openSettings() { - void import("@/components/settings-v2").then((x) => { - dialog.show(() => ) - }) - } - return (
diff --git a/packages/app/src/pages/layout-new.tsx b/packages/app/src/pages/layout-new.tsx index 33972f7cebe..f9222cdeb7b 100644 --- a/packages/app/src/pages/layout-new.tsx +++ b/packages/app/src/pages/layout-new.tsx @@ -3,18 +3,12 @@ import { useNavigate, useParams } from "@solidjs/router" import { DebugBar } from "@/components/debug-bar" import { HelpButton } from "@/components/help-button" import { Titlebar, type TitlebarUpdate } from "@/components/titlebar" -import { useCommand } from "@/context/command" -import { useDialog } from "@opencode-ai/ui/context/dialog" -import { useLanguage } from "@/context/language" import { useNotification } from "@/context/notification" import { usePlatform } from "@/context/platform" import { setNavigate } from "@/utils/notification-click" import { setV2Toast, ToastRegion } from "@/utils/toast" export default function NewLayout(props: ParentProps) { - const command = useCommand() - const dialog = useDialog() - const language = useLanguage() const platform = usePlatform() const notification = useNotification() const navigate = useNavigate() @@ -28,20 +22,6 @@ export default function NewLayout(props: ParentProps) { notification.session.markViewed(params.id) }) - command.register("layout", () => [ - { - id: "settings.open", - title: language.t("command.settings.open"), - category: language.t("command.category.settings"), - keybind: "mod+comma", - onSelect: () => { - void import("@/components/settings-v2").then((x) => { - dialog.show(() => ) - }) - }, - }, - ]) - const update: TitlebarUpdate = { version: () => { const state = platform.updater?.state() diff --git a/packages/app/src/pages/new-session.tsx b/packages/app/src/pages/new-session.tsx index fb07221b691..7ea378e3ea8 100644 --- a/packages/app/src/pages/new-session.tsx +++ b/packages/app/src/pages/new-session.tsx @@ -3,6 +3,7 @@ import { createStore } from "solid-js/store" import { useSearchParams } from "@solidjs/router" import { NewSessionDesignView } from "@/components/session" import { PromptInput } from "@/components/prompt-input" +import { useSettingsCommand } from "@/components/settings-dialog" import { PromptProjectAddButton, PromptProjectSelector, @@ -35,6 +36,7 @@ export default function NewSessionPage() { const [searchParams, setSearchParams] = useSearchParams<{ draftId?: string; prompt?: string }>() useComposerCommands() + useSettingsCommand() let inputRef: HTMLDivElement | undefined diff --git a/packages/app/src/pages/session.tsx b/packages/app/src/pages/session.tsx index b65c39d8593..97560a179f6 100644 --- a/packages/app/src/pages/session.tsx +++ b/packages/app/src/pages/session.tsx @@ -43,6 +43,7 @@ import { useSettings } from "@/context/settings" import { useSync } from "@/context/sync" import { useTerminal } from "@/context/terminal" import { PromptInput } from "@/components/prompt-input" +import { useSettingsCommand } from "@/components/settings-dialog" import { type FollowupDraft, sendFollowupDraft } from "@/components/prompt-input/submit" import { createPromptInputController, @@ -787,6 +788,7 @@ export default function Page() { } useComposerCommands() + useSettingsCommand() useSessionCommands({ navigateMessageByOffset, setActiveMessage,