summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src/entry.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/app/src/entry.tsx')
-rw-r--r--packages/app/src/entry.tsx190
1 files changed, 105 insertions, 85 deletions
diff --git a/packages/app/src/entry.tsx b/packages/app/src/entry.tsx
index aa52fa1e7..f041204dc 100644
--- a/packages/app/src/entry.tsx
+++ b/packages/app/src/entry.tsx
@@ -8,97 +8,117 @@ 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 = (() => {
- if (typeof navigator !== "object") return "en" as const
- const languages = navigator.languages?.length ? navigator.languages : [navigator.language]
- for (const language of languages) {
- if (!language) continue
- if (language.toLowerCase().startsWith("zh")) return "zh" as const
- }
- return "en" as const
- })()
+const getLocale = () => {
+ if (typeof navigator !== "object") return "en" as const
+ const languages = navigator.languages?.length ? navigator.languages : [navigator.language]
+ for (const language of languages) {
+ if (!language) continue
+ if (language.toLowerCase().startsWith("zh")) return "zh" as const
+ }
+ return "en" as const
+}
+const getRootNotFoundError = () => {
const key = "error.dev.rootNotFound" as const
- const message = locale === "zh" ? (zh[key] ?? en[key]) : en[key]
- throw new Error(message)
+ const locale = getLocale()
+ return locale === "zh" ? (zh[key] ?? en[key]) : en[key]
+}
+
+const getStorage = (key: string) => {
+ if (typeof localStorage === "undefined") return null
+ try {
+ return localStorage.getItem(key)
+ } catch {
+ return null
+ }
+}
+
+const setStorage = (key: string, value: string | null) => {
+ if (typeof localStorage === "undefined") return
+ try {
+ if (value !== null) {
+ localStorage.setItem(key, value)
+ return
+ }
+ localStorage.removeItem(key)
+ } catch {
+ return
+ }
+}
+
+const readDefaultServerUrl = () => getStorage(DEFAULT_SERVER_URL_KEY)
+const writeDefaultServerUrl = (url: string | null) => setStorage(DEFAULT_SERVER_URL_KEY, url)
+
+const notify: Platform["notify"] = async (title, description, href) => {
+ if (!("Notification" in window)) return
+
+ const permission =
+ Notification.permission === "default"
+ ? await Notification.requestPermission().catch(() => "denied")
+ : Notification.permission
+
+ if (permission !== "granted") return
+
+ const inView = document.visibilityState === "visible" && document.hasFocus()
+ if (inView) return
+
+ const notification = new Notification(title, {
+ body: description ?? "",
+ icon: "https://opencode.ai/favicon-96x96-v3.png",
+ })
+
+ notification.onclick = () => {
+ window.focus()
+ if (href) {
+ window.history.pushState(null, "", href)
+ window.dispatchEvent(new PopStateEvent("popstate"))
+ }
+ notification.close()
+ }
+}
+
+const openLink: Platform["openLink"] = (url) => {
+ window.open(url, "_blank")
+}
+
+const back: Platform["back"] = () => {
+ window.history.back()
+}
+
+const forward: Platform["forward"] = () => {
+ window.history.forward()
+}
+
+const restart: Platform["restart"] = async () => {
+ window.location.reload()
+}
+
+const root = document.getElementById("root")
+if (!(root instanceof HTMLElement) && import.meta.env.DEV) {
+ throw new Error(getRootNotFoundError())
}
const platform: Platform = {
platform: "web",
version: pkg.version,
- openLink(url: string) {
- window.open(url, "_blank")
- },
- back() {
- window.history.back()
- },
- forward() {
- window.history.forward()
- },
- restart: async () => {
- window.location.reload()
- },
- notify: async (title, description, href) => {
- if (!("Notification" in window)) return
-
- const permission =
- Notification.permission === "default"
- ? await Notification.requestPermission().catch(() => "denied")
- : Notification.permission
-
- if (permission !== "granted") return
-
- const inView = document.visibilityState === "visible" && document.hasFocus()
- if (inView) return
-
- await Promise.resolve()
- .then(() => {
- const notification = new Notification(title, {
- body: description ?? "",
- icon: "https://opencode.ai/favicon-96x96-v3.png",
- })
- notification.onclick = () => {
- window.focus()
- if (href) {
- window.history.pushState(null, "", href)
- window.dispatchEvent(new PopStateEvent("popstate"))
- }
- notification.close()
- }
- })
- .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
- }
- },
+ openLink,
+ back,
+ forward,
+ restart,
+ notify,
+ getDefaultServerUrl: readDefaultServerUrl,
+ setDefaultServerUrl: writeDefaultServerUrl,
}
-render(
- () => (
- <PlatformProvider value={platform}>
- <AppBaseProviders>
- <AppInterface />
- </AppBaseProviders>
- </PlatformProvider>
- ),
- root!,
-)
+if (root instanceof HTMLElement) {
+ render(
+ () => (
+ <PlatformProvider value={platform}>
+ <AppBaseProviders>
+ <AppInterface />
+ </AppBaseProviders>
+ </PlatformProvider>
+ ),
+ root,
+ )
+}