feat(app): default servers on web
This commit is contained in:
@@ -14,7 +14,7 @@ import { GlobalSyncProvider } from "@/context/global-sync"
|
||||
import { PermissionProvider } from "@/context/permission"
|
||||
import { LayoutProvider } from "@/context/layout"
|
||||
import { GlobalSDKProvider } from "@/context/global-sdk"
|
||||
import { ServerProvider, useServer } from "@/context/server"
|
||||
import { normalizeServerUrl, ServerProvider, useServer } from "@/context/server"
|
||||
import { SettingsProvider } from "@/context/settings"
|
||||
import { TerminalProvider } from "@/context/terminal"
|
||||
import { PromptProvider } from "@/context/prompt"
|
||||
@@ -85,8 +85,19 @@ function ServerKey(props: ParentProps) {
|
||||
}
|
||||
|
||||
export function AppInterface(props: { defaultUrl?: string }) {
|
||||
const platform = usePlatform()
|
||||
|
||||
const stored = (() => {
|
||||
if (platform.platform !== "web") return
|
||||
const result = platform.getDefaultServerUrl?.()
|
||||
if (result instanceof Promise) return
|
||||
if (!result) return
|
||||
return normalizeServerUrl(result)
|
||||
})()
|
||||
|
||||
const defaultServerUrl = () => {
|
||||
if (props.defaultUrl) return props.defaultUrl
|
||||
if (stored) return stored
|
||||
if (location.hostname.includes("opencode.ai")) return "http://localhost:4096"
|
||||
if (import.meta.env.DEV)
|
||||
return `http://${import.meta.env.VITE_OPENCODE_SERVER_HOST ?? "localhost"}:${import.meta.env.VITE_OPENCODE_SERVER_PORT ?? "4096"}`
|
||||
|
||||
@@ -155,7 +155,7 @@ export function DialogSelectServer() {
|
||||
},
|
||||
{ initialValue: null },
|
||||
)
|
||||
const isDesktop = platform.platform === "desktop"
|
||||
const canDefault = createMemo(() => !!platform.getDefaultServerUrl && !!platform.setDefaultServerUrl)
|
||||
|
||||
const looksComplete = (value: string) => {
|
||||
const normalized = normalizeServerUrl(value)
|
||||
@@ -505,7 +505,7 @@ export function DialogSelectServer() {
|
||||
>
|
||||
<DropdownMenu.ItemLabel>{language.t("dialog.server.menu.edit")}</DropdownMenu.ItemLabel>
|
||||
</DropdownMenu.Item>
|
||||
<Show when={isDesktop && defaultUrl() !== i}>
|
||||
<Show when={canDefault() && defaultUrl() !== i}>
|
||||
<DropdownMenu.Item
|
||||
onSelect={async () => {
|
||||
await platform.setDefaultServerUrl?.(i)
|
||||
@@ -517,7 +517,7 @@ export function DialogSelectServer() {
|
||||
</DropdownMenu.ItemLabel>
|
||||
</DropdownMenu.Item>
|
||||
</Show>
|
||||
<Show when={isDesktop && defaultUrl() === i}>
|
||||
<Show when={canDefault() && defaultUrl() === i}>
|
||||
<DropdownMenu.Item
|
||||
onSelect={async () => {
|
||||
await platform.setDefaultServerUrl?.(null)
|
||||
|
||||
@@ -125,13 +125,21 @@ export function StatusPopover() {
|
||||
|
||||
const [defaultServerUrl, setDefaultServerUrl] = createSignal<string | undefined>()
|
||||
|
||||
createEffect(() => {
|
||||
const refreshDefaultServerUrl = () => {
|
||||
const result = platform.getDefaultServerUrl?.()
|
||||
if (!result) {
|
||||
setDefaultServerUrl(undefined)
|
||||
return
|
||||
}
|
||||
if (result instanceof Promise) {
|
||||
result.then((url) => setDefaultServerUrl(url ? normalizeServerUrl(url) : undefined))
|
||||
return
|
||||
}
|
||||
if (result) setDefaultServerUrl(normalizeServerUrl(result))
|
||||
setDefaultServerUrl(normalizeServerUrl(result))
|
||||
}
|
||||
|
||||
createEffect(() => {
|
||||
refreshDefaultServerUrl()
|
||||
})
|
||||
|
||||
return (
|
||||
@@ -294,7 +302,7 @@ export function StatusPopover() {
|
||||
<Button
|
||||
variant="secondary"
|
||||
class="mt-3 self-start h-8 px-3 py-1.5"
|
||||
onClick={() => dialog.show(() => <DialogSelectServer />)}
|
||||
onClick={() => dialog.show(() => <DialogSelectServer />, refreshDefaultServerUrl)}
|
||||
>
|
||||
{language.t("status.popover.action.manageServers")}
|
||||
</Button>
|
||||
|
||||
@@ -41,11 +41,11 @@ export type Platform = {
|
||||
/** Fetch override */
|
||||
fetch?: typeof fetch
|
||||
|
||||
/** Get the configured default server URL (desktop only) */
|
||||
getDefaultServerUrl?(): Promise<string | null>
|
||||
/** Get the configured default server URL (platform-specific) */
|
||||
getDefaultServerUrl?(): Promise<string | null> | string | null
|
||||
|
||||
/** Set the default server URL to use on app startup (desktop only) */
|
||||
setDefaultServerUrl?(url: string | null): Promise<void>
|
||||
/** Set the default server URL to use on app startup (platform-specific) */
|
||||
setDefaultServerUrl?(url: string | null): Promise<void> | void
|
||||
|
||||
/** Parse markdown to HTML using native parser (desktop only, returns unprocessed code blocks) */
|
||||
parseMarkdown?(markdown: string): Promise<string>
|
||||
|
||||
@@ -6,6 +6,8 @@ import { dict as en } from "@/i18n/en"
|
||||
import { dict as zh } from "@/i18n/zh"
|
||||
import pkg from "../package.json"
|
||||
|
||||
const DEFAULT_SERVER_URL_KEY = "opencode.settings.dat:defaultServerUrl"
|
||||
|
||||
const root = document.getElementById("root")
|
||||
if (import.meta.env.DEV && !(root instanceof HTMLElement)) {
|
||||
const locale = (() => {
|
||||
@@ -62,6 +64,26 @@ const platform: Platform = {
|
||||
})
|
||||
.catch(() => undefined)
|
||||
},
|
||||
getDefaultServerUrl: () => {
|
||||
if (typeof localStorage === "undefined") return null
|
||||
try {
|
||||
return localStorage.getItem(DEFAULT_SERVER_URL_KEY)
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
},
|
||||
setDefaultServerUrl: (url) => {
|
||||
if (typeof localStorage === "undefined") return
|
||||
try {
|
||||
if (url) {
|
||||
localStorage.setItem(DEFAULT_SERVER_URL_KEY, url)
|
||||
return
|
||||
}
|
||||
localStorage.removeItem(DEFAULT_SERVER_URL_KEY)
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
render(
|
||||
|
||||
Reference in New Issue
Block a user