diff options
| author | Brendan Allan <[email protected]> | 2026-03-12 16:10:52 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-03-12 08:10:52 +0000 |
| commit | b76ead3fe80a6159fdbfcc9b82c7c6318be68e7f (patch) | |
| tree | bad16ba8185403eb9dc97b6c996bbfa78ae7918b /packages/desktop/src | |
| parent | 51835ecf90e23b34957f4dde843bbba1134f17fe (diff) | |
| download | opencode-b76ead3fe80a6159fdbfcc9b82c7c6318be68e7f.tar.gz opencode-b76ead3fe80a6159fdbfcc9b82c7c6318be68e7f.zip | |
refactor(desktop): rework default server initialization and connection handling (#16965)
Diffstat (limited to 'packages/desktop/src')
| -rw-r--r-- | packages/desktop/src/bindings.ts | 1 | ||||
| -rw-r--r-- | packages/desktop/src/index.tsx | 102 |
2 files changed, 44 insertions, 59 deletions
diff --git a/packages/desktop/src/bindings.ts b/packages/desktop/src/bindings.ts index 80548173e..d434d3b35 100644 --- a/packages/desktop/src/bindings.ts +++ b/packages/desktop/src/bindings.ts @@ -38,7 +38,6 @@ export type ServerReadyData = { url: string, username: string | null, password: string | null, - is_sidecar: boolean, }; export type SqliteMigrationProgress = { type: "InProgress"; value: number } | { type: "Done" }; diff --git a/packages/desktop/src/index.tsx b/packages/desktop/src/index.tsx index 9afabe918..65149f34b 100644 --- a/packages/desktop/src/index.tsx +++ b/packages/desktop/src/index.tsx @@ -9,7 +9,6 @@ import { ServerConnection, useCommand, } from "@opencode-ai/app" -import { Splash } from "@opencode-ai/ui/logo" import type { AsyncStorage } from "@solid-primitives/storage" import { getCurrentWindow } from "@tauri-apps/api/window" import { readImage } from "@tauri-apps/plugin-clipboard-manager" @@ -22,7 +21,7 @@ import { relaunch } from "@tauri-apps/plugin-process" import { open as shellOpen } from "@tauri-apps/plugin-shell" import { Store } from "@tauri-apps/plugin-store" import { check, type Update } from "@tauri-apps/plugin-updater" -import { createResource, type JSX, onCleanup, onMount, Show } from "solid-js" +import { createResource, onCleanup, onMount, Show } from "solid-js" import { render } from "solid-js/web" import pkg from "../package.json" import { initI18n, t } from "./i18n" @@ -30,7 +29,7 @@ import { UPDATER_ENABLED } from "./updater" import { webviewZoom } from "./webview-zoom" import "./styles.css" import { Channel } from "@tauri-apps/api/core" -import { commands, ServerReadyData, type InitStep } from "./bindings" +import { commands, type InitStep } from "./bindings" import { createMenu } from "./menu" const root = document.getElementById("root") @@ -348,12 +347,13 @@ const createPlatform = (): Platform => { await commands.setWslConfig({ enabled }) }, - getDefaultServerUrl: async () => { - const result = await commands.getDefaultServerUrl().catch(() => null) - return result + getDefaultServer: async () => { + const url = await commands.getDefaultServerUrl().catch(() => null) + if (!url) return null + return ServerConnection.Key.make(url) }, - setDefaultServerUrl: async (url: string | null) => { + setDefaultServer: async (url: string | null) => { await commands.setDefaultServerUrl(url) }, @@ -412,12 +412,33 @@ void listenForDeepLinks() render(() => { const platform = createPlatform() + // Fetch sidecar credentials from Rust (available immediately, before health check) + const [sidecar] = createResource(() => commands.awaitInitialization(new Channel<InitStep>() as any)) + const [defaultServer] = createResource(() => - platform.getDefaultServerUrl?.().then((url) => { + platform.getDefaultServer?.().then((url) => { if (url) return ServerConnection.key({ type: "http", http: { url } }) }), ) + // Build the sidecar server connection once credentials arrive + const servers = () => { + const data = sidecar() + if (!data) return [] + const http = { + url: data.url, + username: data.username ?? undefined, + password: data.password ?? undefined, + } + const server: ServerConnection.Sidecar = { + displayName: t("desktop.server.local"), + type: "sidecar", + variant: "base", + http, + } + return [server] as ServerConnection.Any[] + } + function handleClick(e: MouseEvent) { const link = (e.target as HTMLElement).closest("a.external-link") as HTMLAnchorElement | null if (link?.href) { @@ -426,6 +447,12 @@ render(() => { } } + function Inner() { + const cmd = useCommand() + menuTrigger = (id) => cmd.trigger(id) + return null + } + onMount(() => { document.addEventListener("click", handleClick) onCleanup(() => { @@ -436,60 +463,19 @@ render(() => { return ( <PlatformProvider value={platform}> <AppBaseProviders> - <ServerGate> - {(data) => { - const http = { - url: data.url, - username: data.username ?? undefined, - password: data.password ?? undefined, - } - const server: ServerConnection.Any = data.is_sidecar - ? { - displayName: t("desktop.server.local"), - type: "sidecar", - variant: "base", - http, - } - : { type: "http", http } - - function Inner() { - const cmd = useCommand() - - menuTrigger = (id) => cmd.trigger(id) - - return null - } - + <Show when={!defaultServer.loading && !sidecar.loading}> + {(_) => { return ( - <Show when={!defaultServer.loading}> - <AppInterface defaultServer={defaultServer.latest ?? ServerConnection.key(server)} servers={[server]}> - <Inner /> - </AppInterface> - </Show> + <AppInterface + defaultServer={defaultServer.latest ?? ServerConnection.Key.make("sidecar")} + servers={servers()} + > + <Inner /> + </AppInterface> ) }} - </ServerGate> + </Show> </AppBaseProviders> </PlatformProvider> ) }, root!) - -// Gate component that waits for the server to be ready -function ServerGate(props: { children: (data: ServerReadyData) => JSX.Element }) { - const [serverData] = createResource(() => commands.awaitInitialization(new Channel<InitStep>() as any)) - if (serverData.state === "errored") throw serverData.error - - return ( - <Show - when={serverData.state !== "pending" && serverData()} - fallback={ - <div class="h-screen w-screen flex flex-col items-center justify-center bg-background-base"> - <Splash class="w-16 h-20 opacity-50 animate-pulse" /> - <div data-tauri-decorum-tb class="flex flex-row absolute top-0 right-0 z-10 h-10" /> - </div> - } - > - {(data) => props.children(data())} - </Show> - ) -} |
