summaryrefslogtreecommitdiffhomepage
path: root/packages/desktop-electron/src/renderer/loading.tsx
diff options
context:
space:
mode:
authorBrendan Allan <[email protected]>2026-03-04 15:12:34 +0800
committerGitHub <[email protected]>2026-03-04 15:12:34 +0800
commit5cf235fa6cf7b4c890c68f8ff68a96fcae992abf (patch)
tree25fdfd8ce95ad048fb097822995dcf060e8d6d8b /packages/desktop-electron/src/renderer/loading.tsx
parente4f0825c56300286ec0aa82b1006e4006a17e1e1 (diff)
downloadopencode-5cf235fa6cf7b4c890c68f8ff68a96fcae992abf.tar.gz
opencode-5cf235fa6cf7b4c890c68f8ff68a96fcae992abf.zip
desktop: add electron version (#15663)
Diffstat (limited to 'packages/desktop-electron/src/renderer/loading.tsx')
-rw-r--r--packages/desktop-electron/src/renderer/loading.tsx80
1 files changed, 80 insertions, 0 deletions
diff --git a/packages/desktop-electron/src/renderer/loading.tsx b/packages/desktop-electron/src/renderer/loading.tsx
new file mode 100644
index 000000000..165950352
--- /dev/null
+++ b/packages/desktop-electron/src/renderer/loading.tsx
@@ -0,0 +1,80 @@
+import { render } from "solid-js/web"
+import { MetaProvider } from "@solidjs/meta"
+import "@opencode-ai/app/index.css"
+import { Font } from "@opencode-ai/ui/font"
+import { Splash } from "@opencode-ai/ui/logo"
+import { Progress } from "@opencode-ai/ui/progress"
+import "./styles.css"
+import { createEffect, createMemo, createSignal, onCleanup, onMount } from "solid-js"
+import type { InitStep, SqliteMigrationProgress } from "../preload/types"
+
+const root = document.getElementById("root")!
+const lines = ["Just a moment...", "Migrating your database", "This may take a couple of minutes"]
+const delays = [3000, 9000]
+
+render(() => {
+ const [step, setStep] = createSignal<InitStep | null>(null)
+ const [line, setLine] = createSignal(0)
+ const [percent, setPercent] = createSignal(0)
+
+ const phase = createMemo(() => step()?.phase)
+
+ const value = createMemo(() => {
+ if (phase() === "done") return 100
+ return Math.max(25, Math.min(100, percent()))
+ })
+
+ window.api.awaitInitialization((next) => setStep(next as InitStep)).catch(() => undefined)
+
+ onMount(() => {
+ setLine(0)
+ setPercent(0)
+
+ const timers = delays.map((ms, i) => setTimeout(() => setLine(i + 1), ms))
+
+ const listener = window.api.onSqliteMigrationProgress((progress: SqliteMigrationProgress) => {
+ if (progress.type === "InProgress") setPercent(Math.max(0, Math.min(100, progress.value)))
+ if (progress.type === "Done") setPercent(100)
+ })
+
+ onCleanup(() => {
+ listener()
+ timers.forEach(clearTimeout)
+ })
+ })
+
+ createEffect(() => {
+ if (phase() !== "done") return
+
+ const timer = setTimeout(() => window.api.loadingWindowComplete(), 1000)
+ onCleanup(() => clearTimeout(timer))
+ })
+
+ const status = createMemo(() => {
+ if (phase() === "done") return "All done"
+ if (phase() === "sqlite_waiting") return lines[line()]
+ return "Just a moment..."
+ })
+
+ return (
+ <MetaProvider>
+ <div class="w-screen h-screen bg-background-base flex items-center justify-center">
+ <Font />
+ <div class="flex flex-col items-center gap-11">
+ <Splash class="w-20 h-25 opacity-15" />
+ <div class="w-60 flex flex-col items-center gap-4" aria-live="polite">
+ <span class="w-full overflow-hidden text-center text-ellipsis whitespace-nowrap text-text-strong text-14-normal">
+ {status()}
+ </span>
+ <Progress
+ value={value()}
+ class="w-20 [&_[data-slot='progress-track']]:h-1 [&_[data-slot='progress-track']]:border-0 [&_[data-slot='progress-track']]:rounded-none [&_[data-slot='progress-track']]:bg-surface-weak [&_[data-slot='progress-fill']]:rounded-none [&_[data-slot='progress-fill']]:bg-icon-warning-base"
+ aria-label="Database migration progress"
+ getValueLabel={({ value }) => `${Math.round(value)}%`}
+ />
+ </div>
+ </div>
+ </div>
+ </MetaProvider>
+ )
+}, root)