diff options
Diffstat (limited to 'packages/app/src/entry.tsx')
| -rw-r--r-- | packages/app/src/entry.tsx | 190 |
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, + ) +} |
