Skip to content

Commit a379eb3

Browse files
committed
Revert "fix(app): startup efficiency (anomalyco#18854)"
This reverts commit 546748a.
1 parent cbe1337 commit a379eb3

33 files changed

Lines changed: 632 additions & 939 deletions

packages/app/src/app.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { MarkedProvider } from "@opencode-ai/ui/context/marked"
66
import { File } from "@opencode-ai/ui/file"
77
import { Font } from "@opencode-ai/ui/font"
88
import { Splash } from "@opencode-ai/ui/logo"
9-
import { ThemeProvider } from "@opencode-ai/ui/theme/context"
9+
import { ThemeProvider } from "@opencode-ai/ui/theme"
1010
import { MetaProvider } from "@solidjs/meta"
1111
import { type BaseRouterProps, Navigate, Route, Router } from "@solidjs/router"
1212
import { QueryClient, QueryClientProvider } from "@tanstack/solid-query"
@@ -32,7 +32,7 @@ import { FileProvider } from "@/context/file"
3232
import { GlobalSDKProvider } from "@/context/global-sdk"
3333
import { GlobalSyncProvider } from "@/context/global-sync"
3434
import { HighlightsProvider } from "@/context/highlights"
35-
import { LanguageProvider, type Locale, useLanguage } from "@/context/language"
35+
import { LanguageProvider, useLanguage } from "@/context/language"
3636
import { LayoutProvider } from "@/context/layout"
3737
import { ModelsProvider } from "@/context/models"
3838
import { NotificationProvider } from "@/context/notification"
@@ -130,7 +130,7 @@ function RouterRoot(props: ParentProps<{ appChildren?: JSX.Element }>) {
130130
)
131131
}
132132

133-
export function AppBaseProviders(props: ParentProps<{ locale?: Locale }>) {
133+
export function AppBaseProviders(props: ParentProps) {
134134
return (
135135
<MetaProvider>
136136
<Font />
@@ -139,7 +139,7 @@ export function AppBaseProviders(props: ParentProps<{ locale?: Locale }>) {
139139
void window.api?.setTitlebar?.({ mode })
140140
}}
141141
>
142-
<LanguageProvider locale={props.locale}>
142+
<LanguageProvider>
143143
<UiI18nBridge>
144144
<ErrorBoundary fallback={(error) => <ErrorPage error={error} />}>
145145
<QueryProvider>

packages/app/src/components/dialog-connect-provider.tsx

Lines changed: 12 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { ProviderAuthAuthorization, ProviderAuthMethod } from "@opencode-ai/sdk/v2/client"
1+
import type { ProviderAuthAuthorization } from "@opencode-ai/sdk/v2/client"
22
import { Button } from "@opencode-ai/ui/button"
33
import { useDialog } from "@opencode-ai/ui/context/dialog"
44
import { Dialog } from "@opencode-ai/ui/dialog"
@@ -9,7 +9,7 @@ import { ProviderIcon } from "@opencode-ai/ui/provider-icon"
99
import { Spinner } from "@opencode-ai/ui/spinner"
1010
import { TextField } from "@opencode-ai/ui/text-field"
1111
import { showToast } from "@opencode-ai/ui/toast"
12-
import { createEffect, createMemo, createResource, Match, onCleanup, onMount, Switch } from "solid-js"
12+
import { createMemo, Match, onCleanup, onMount, Switch } from "solid-js"
1313
import { createStore, produce } from "solid-js/store"
1414
import { Link } from "@/components/link"
1515
import { useGlobalSDK } from "@/context/global-sdk"
@@ -34,25 +34,15 @@ export function DialogConnectProvider(props: { provider: string }) {
3434
})
3535

3636
const provider = createMemo(() => globalSync.data.provider.all.find((x) => x.id === props.provider)!)
37-
const fallback = createMemo<ProviderAuthMethod[]>(() => [
38-
{
39-
type: "api" as const,
40-
label: language.t("provider.connect.method.apiKey"),
41-
},
42-
])
43-
const [auth] = createResource(
44-
() => props.provider,
45-
async () => {
46-
const cached = globalSync.data.provider_auth[props.provider]
47-
if (cached) return cached
48-
const res = await globalSDK.client.provider.auth()
49-
if (!alive.value) return fallback()
50-
globalSync.set("provider_auth", res.data ?? {})
51-
return res.data?.[props.provider] ?? fallback()
52-
},
37+
const methods = createMemo(
38+
() =>
39+
globalSync.data.provider_auth[props.provider] ?? [
40+
{
41+
type: "api",
42+
label: language.t("provider.connect.method.apiKey"),
43+
},
44+
],
5345
)
54-
const loading = createMemo(() => auth.loading && !globalSync.data.provider_auth[props.provider])
55-
const methods = createMemo(() => auth.latest ?? globalSync.data.provider_auth[props.provider] ?? fallback())
5646
const [store, setStore] = createStore({
5747
methodIndex: undefined as undefined | number,
5848
authorization: undefined as undefined | ProviderAuthAuthorization,
@@ -187,11 +177,7 @@ export function DialogConnectProvider(props: { provider: string }) {
187177
index: 0,
188178
})
189179

190-
const prompts = createMemo<NonNullable<ProviderAuthMethod["prompts"]>>(() => {
191-
const value = method()
192-
if (value?.type !== "oauth") return []
193-
return value.prompts ?? []
194-
})
180+
const prompts = createMemo(() => method()?.prompts ?? [])
195181
const matches = (prompt: NonNullable<ReturnType<typeof prompts>[number]>, value: Record<string, string>) => {
196182
if (!prompt.when) return true
197183
const actual = value[prompt.when.key]
@@ -310,12 +296,8 @@ export function DialogConnectProvider(props: { provider: string }) {
310296
listRef?.onKeyDown(e)
311297
}
312298

313-
let auto = false
314-
createEffect(() => {
315-
if (auto) return
316-
if (loading()) return
299+
onMount(() => {
317300
if (methods().length === 1) {
318-
auto = true
319301
selectMethod(0)
320302
}
321303
})
@@ -591,14 +573,6 @@ export function DialogConnectProvider(props: { provider: string }) {
591573
<div class="px-2.5 pb-10 flex flex-col gap-6">
592574
<div onKeyDown={handleKey} tabIndex={0} autofocus={store.methodIndex === undefined ? true : undefined}>
593575
<Switch>
594-
<Match when={loading()}>
595-
<div class="text-14-regular text-text-base">
596-
<div class="flex items-center gap-x-2">
597-
<Spinner />
598-
<span>{language.t("provider.connect.status.inProgress")}</span>
599-
</div>
600-
</div>
601-
</Match>
602576
<Match when={store.methodIndex === undefined}>
603577
<MethodSelection />
604578
</Match>

packages/app/src/components/settings-general.tsx

Lines changed: 12 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,40 @@
1-
import { Component, Show, createMemo, createResource, onMount, type JSX } from "solid-js"
1+
import { Component, Show, createMemo, createResource, type JSX } from "solid-js"
22
import { createStore } from "solid-js/store"
33
import { Button } from "@opencode-ai/ui/button"
44
import { Icon } from "@opencode-ai/ui/icon"
55
import { Select } from "@opencode-ai/ui/select"
66
import { Switch } from "@opencode-ai/ui/switch"
77
import { Tooltip } from "@opencode-ai/ui/tooltip"
8-
import { useTheme, type ColorScheme } from "@opencode-ai/ui/theme/context"
8+
import { useTheme, type ColorScheme } from "@opencode-ai/ui/theme"
99
import { showToast } from "@opencode-ai/ui/toast"
1010
import { useLanguage } from "@/context/language"
1111
import { usePlatform } from "@/context/platform"
1212
import { useSettings, monoFontFamily } from "@/context/settings"
13-
import { playSoundById, SOUND_OPTIONS } from "@/utils/sound"
13+
import { playSound, SOUND_OPTIONS } from "@/utils/sound"
1414
import { Link } from "./link"
1515
import { SettingsList } from "./settings-list"
1616

1717
let demoSoundState = {
1818
cleanup: undefined as (() => void) | undefined,
1919
timeout: undefined as NodeJS.Timeout | undefined,
20-
run: 0,
21-
}
22-
23-
type ThemeOption = {
24-
id: string
25-
name: string
26-
}
27-
28-
let font: Promise<typeof import("@opencode-ai/ui/font-loader")> | undefined
29-
30-
function loadFont() {
31-
font ??= import("@opencode-ai/ui/font-loader")
32-
return font
3320
}
3421

3522
// To prevent audio from overlapping/playing very quickly when navigating the settings menus,
3623
// delay the playback by 100ms during quick selection changes and pause existing sounds.
3724
const stopDemoSound = () => {
38-
demoSoundState.run += 1
3925
if (demoSoundState.cleanup) {
4026
demoSoundState.cleanup()
4127
}
4228
clearTimeout(demoSoundState.timeout)
4329
demoSoundState.cleanup = undefined
4430
}
4531

46-
const playDemoSound = (id: string | undefined) => {
32+
const playDemoSound = (src: string | undefined) => {
4733
stopDemoSound()
48-
if (!id) return
34+
if (!src) return
4935

50-
const run = ++demoSoundState.run
5136
demoSoundState.timeout = setTimeout(() => {
52-
void playSoundById(id).then((cleanup) => {
53-
if (demoSoundState.run !== run) {
54-
cleanup?.()
55-
return
56-
}
57-
demoSoundState.cleanup = cleanup
58-
})
37+
demoSoundState.cleanup = playSound(src)
5938
}, 100)
6039
}
6140

@@ -65,10 +44,6 @@ export const SettingsGeneral: Component = () => {
6544
const platform = usePlatform()
6645
const settings = useSettings()
6746

68-
onMount(() => {
69-
void theme.loadThemes()
70-
})
71-
7247
const [store, setStore] = createStore({
7348
checking: false,
7449
})
@@ -129,7 +104,9 @@ export const SettingsGeneral: Component = () => {
129104
.finally(() => setStore("checking", false))
130105
}
131106

132-
const themeOptions = createMemo<ThemeOption[]>(() => theme.ids().map((id) => ({ id, name: theme.name(id) })))
107+
const themeOptions = createMemo(() =>
108+
Object.entries(theme.themes()).map(([id, def]) => ({ id, name: def.name ?? id })),
109+
)
133110

134111
const colorSchemeOptions = createMemo((): { value: ColorScheme; label: string }[] => [
135112
{ value: "system", label: language.t("theme.scheme.system") },
@@ -166,7 +143,7 @@ export const SettingsGeneral: Component = () => {
166143
] as const
167144
const fontOptionsList = [...fontOptions]
168145

169-
const noneSound = { id: "none", label: "sound.option.none" } as const
146+
const noneSound = { id: "none", label: "sound.option.none", src: undefined } as const
170147
const soundOptions = [noneSound, ...SOUND_OPTIONS]
171148

172149
const soundSelectProps = (
@@ -181,7 +158,7 @@ export const SettingsGeneral: Component = () => {
181158
label: (o: (typeof soundOptions)[number]) => language.t(o.label),
182159
onHighlight: (option: (typeof soundOptions)[number] | undefined) => {
183160
if (!option) return
184-
playDemoSound(option.id === "none" ? undefined : option.id)
161+
playDemoSound(option.src)
185162
},
186163
onSelect: (option: (typeof soundOptions)[number] | undefined) => {
187164
if (!option) return
@@ -192,7 +169,7 @@ export const SettingsGeneral: Component = () => {
192169
}
193170
setEnabled(true)
194171
set(option.id)
195-
playDemoSound(option.id)
172+
playDemoSound(option.src)
196173
},
197174
variant: "secondary" as const,
198175
size: "small" as const,
@@ -344,9 +321,6 @@ export const SettingsGeneral: Component = () => {
344321
current={fontOptionsList.find((o) => o.value === settings.appearance.font())}
345322
value={(o) => o.value}
346323
label={(o) => language.t(o.label)}
347-
onHighlight={(option) => {
348-
void loadFont().then((x) => x.ensureMonoFont(option?.value))
349-
}}
350324
onSelect={(option) => option && settings.appearance.setFont(option.value)}
351325
variant="secondary"
352326
size="small"

packages/app/src/components/status-popover.tsx

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { useSDK } from "@/context/sdk"
1616
import { normalizeServerUrl, ServerConnection, useServer } from "@/context/server"
1717
import { useSync } from "@/context/sync"
1818
import { useCheckServerHealth, type ServerHealth } from "@/utils/server-health"
19+
import { DialogSelectServer } from "./dialog-select-server"
1920

2021
const pollMs = 10_000
2122

@@ -53,15 +54,11 @@ const listServersByHealth = (
5354
})
5455
}
5556

56-
const useServerHealth = (servers: Accessor<ServerConnection.Any[]>, enabled: Accessor<boolean>) => {
57+
const useServerHealth = (servers: Accessor<ServerConnection.Any[]>) => {
5758
const checkServerHealth = useCheckServerHealth()
5859
const [status, setStatus] = createStore({} as Record<ServerConnection.Key, ServerHealth | undefined>)
5960

6061
createEffect(() => {
61-
if (!enabled()) {
62-
setStatus(reconcile({}))
63-
return
64-
}
6562
const list = servers()
6663
let dead = false
6764

@@ -165,20 +162,14 @@ export function StatusPopover() {
165162
const navigate = useNavigate()
166163

167164
const [shown, setShown] = createSignal(false)
168-
let dialogRun = 0
169-
let dialogDead = false
170-
onCleanup(() => {
171-
dialogDead = true
172-
dialogRun += 1
173-
})
174165
const servers = createMemo(() => {
175166
const current = server.current
176167
const list = server.list
177168
if (!current) return list
178169
if (list.every((item) => ServerConnection.key(item) !== ServerConnection.key(current))) return [current, ...list]
179170
return [current, ...list.filter((item) => ServerConnection.key(item) !== ServerConnection.key(current))]
180171
})
181-
const health = useServerHealth(servers, shown)
172+
const health = useServerHealth(servers)
182173
const sortedServers = createMemo(() => listServersByHealth(servers(), server.key, health))
183174
const toggleMcp = useMcpToggleMutation()
184175
const defaultServer = useDefaultServerKey(platform.getDefaultServer)
@@ -309,13 +300,7 @@ export function StatusPopover() {
309300
<Button
310301
variant="secondary"
311302
class="mt-3 self-start h-8 px-3 py-1.5"
312-
onClick={() => {
313-
const run = ++dialogRun
314-
void import("./dialog-select-server").then((x) => {
315-
if (dialogDead || dialogRun !== run) return
316-
dialog.show(() => <x.DialogSelectServer />, defaultServer.refresh)
317-
})
318-
}}
303+
onClick={() => dialog.show(() => <DialogSelectServer />, defaultServer.refresh)}
319304
>
320305
{language.t("status.popover.action.manageServers")}
321306
</Button>

packages/app/src/components/terminal.tsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
import { withAlpha } from "@opencode-ai/ui/theme/color"
2-
import { useTheme } from "@opencode-ai/ui/theme/context"
3-
import { resolveThemeVariant } from "@opencode-ai/ui/theme/resolve"
4-
import type { HexColor } from "@opencode-ai/ui/theme/types"
1+
import { type HexColor, resolveThemeVariant, useTheme, withAlpha } from "@opencode-ai/ui/theme"
52
import { showToast } from "@opencode-ai/ui/toast"
63
import type { FitAddon, Ghostty, Terminal as Term } from "ghostty-web"
74
import { type ComponentProps, createEffect, createMemo, onCleanup, onMount, splitProps } from "solid-js"

packages/app/src/components/titlebar.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { IconButton } from "@opencode-ai/ui/icon-button"
55
import { Icon } from "@opencode-ai/ui/icon"
66
import { Button } from "@opencode-ai/ui/button"
77
import { Tooltip, TooltipKeybind } from "@opencode-ai/ui/tooltip"
8-
import { useTheme } from "@opencode-ai/ui/theme/context"
8+
import { useTheme } from "@opencode-ai/ui/theme"
99

1010
import { useLayout } from "@/context/layout"
1111
import { usePlatform } from "@/context/platform"

0 commit comments

Comments
 (0)