| 1 | import { useEffect, useMemo, useState } from "react"; |
| 2 | import { desktopHost } from "../lib/desktopHost"; |
| 3 | import { useCommittedCommand } from "../lib/useCommittedCommand"; |
| 4 | import { useCommittedAsyncCommand } from "../lib/useCommittedAsyncCommand"; |
| 5 | import { useConfigLoadWarnings } from "../lib/useConfigLoadWarnings"; |
| 6 | import { useI18n, useT } from "../lib/i18n"; |
| 7 | import { DEFAULT_STATUS_BAR_ITEMS, normalizeStatusBarItems } from "../lib/statusBarItems"; |
| 8 | import { hydrateReasoningDisplayMode, setReasoningDisplayPending } from "../lib/reasoningDisplayPreference"; |
| 9 | import { hydrateSessionExperience } from "../lib/sessionExperience"; |
| 10 | import type { BotRuntimeStatusView } from "../lib/types"; |
| 11 | import { app } from "../lib/bridge"; |
| 12 | import { applyPreferencesAppearance, synchronizeDesktopPreferences, type DesktopPreferencesSnapshot } from "./desktopPreferencesAdapter"; |
| 13 | import { sidebarImConnectionsFromBot, sidebarImTopicSourcesFromBot } from "./sidebarImProjection"; |
| 14 | |
| 15 | export function useDesktopPreferences() { |
| 16 | const { locale, setPref } = useI18n(); |
| 17 | const t = useT(); |
| 18 | const warnings = useConfigLoadWarnings(); |
| 19 | const [snapshot, setSnapshot] = useState<DesktopPreferencesSnapshot | null>(null); |
| 20 | const [botRuntime, setBotRuntime] = useState<BotRuntimeStatusView | null>(null); |
| 21 | const [startupFailed, setStartupFailed] = useState(false); |
| 22 | const publish = useCommittedCommand((settings: DesktopPreferencesSnapshot, runtime: BotRuntimeStatusView | null) => { |
| 23 | setPref(applyPreferencesAppearance(settings)); |
| 24 | if ("configWarnings" in settings) warnings.applySnapshot(settings.configWarnings, settings.configWarningsRevision); |
| 25 | setSnapshot(settings); |
| 26 | setBotRuntime(runtime); |
| 27 | setStartupFailed(false); |
| 28 | }); |
| 29 | const synchronize = useCommittedAsyncCommand((provided?: DesktopPreferencesSnapshot | null, loadTheme: boolean = false) => ({ provided, publish, loadTheme }), synchronizeDesktopPreferences); |
| 30 | const failed = useCommittedCommand((error: unknown) => { |
| 31 | setStartupFailed(true); |
| 32 | if (!snapshot) { |
| 33 | hydrateSessionExperience("standard"); |
| 34 | hydrateReasoningDisplayMode("auto", false); |
| 35 | } |
| 36 | console.warn("desktop preferences sync failed", error); |
| 37 | }); |
| 38 | const reload = useCommittedCommand(async (provided?: DesktopPreferencesSnapshot | null, loadTheme = false) => { |
| 39 | const result = await synchronize(provided, loadTheme); |
| 40 | if (result.status === "failed") failed(result.error); |
| 41 | }); |
| 42 | useEffect(() => { |
| 43 | setReasoningDisplayPending(); |
| 44 | void reload(undefined, true); |
| 45 | }, [reload]); |
| 46 | useEffect(() => { void app.SetTrayLocale(locale).catch(() => {}); }, [locale]); |
| 47 | const nativeRuntime = typeof window === "undefined" || desktopHost().kind !== "none"; |
| 48 | const sidebarImConnections = useMemo(() => snapshot ? sidebarImConnectionsFromBot(snapshot.bot, t, botRuntime, nativeRuntime) : [], [snapshot, t, botRuntime, nativeRuntime]); |
| 49 | const imTopicSources = useMemo(() => snapshot ? sidebarImTopicSourcesFromBot(snapshot.bot, t) : {}, [snapshot, t]); |
| 50 | return { |
| 51 | startupUpdateChecksEnabled: snapshot |
| 52 | ? snapshot.updaterEnabled === true && snapshot.checkUpdates !== false |
| 53 | : startupFailed ? false : null, |
| 54 | statusBarStyle: snapshot?.statusBarStyle === "text" ? "text" as const : "icon" as const, |
| 55 | statusBarItems: snapshot ? normalizeStatusBarItems(snapshot.statusBarItems) : DEFAULT_STATUS_BAR_ITEMS, |
| 56 | sidebarImConnections, imTopicSources, |
| 57 | configLoadWarnings: warnings.configLoadWarnings, reloadConfigWarnings: warnings.reload, dismissConfigWarnings: warnings.dismiss, |
| 58 | reload, |
| 59 | }; |
| 60 | } |
| 61 |