import { createContext, useCallback, useContext, useEffect, useRef, useState, type ReactNode, } from "react"; import { Settings as SettingsSvc } from "@bindings/services"; import type { Config } from "@bindings/services/models.js"; import { useProfile } from "@/modules/profile/ProfileContext.tsx"; const SAVE_DEBOUNCE_MS = 400; type SettingsContextValue = { config: Config; setField: (k: K, v: Config[K]) => void; saveField: (k: K, v: Config[K]) => Promise; saveNow: () => Promise; }; const SettingsContext = createContext(null); export const useSettings = () => { const ctx = useContext(SettingsContext); if (!ctx) { throw new Error("useSettings must be used inside SettingsProvider"); } return ctx; }; const useSettingsState = () => { const { username, activeProfile, loaded: profileLoaded } = useProfile(); const [config, setConfig] = useState(null); const [error, setError] = useState(null); const saveTimer = useRef | null>(null); useEffect(() => { if (!profileLoaded || !activeProfile) return; (async () => { try { const c = await SettingsSvc.GetConfig({ profileName: activeProfile, username, }); setConfig(c); setError(null); } catch (e) { setError(String(e)); } })(); }, [profileLoaded, activeProfile, username]); useEffect( () => () => { if (saveTimer.current) clearTimeout(saveTimer.current); }, [], ); const save = useCallback( async (next: Config) => { try { await SettingsSvc.SetConfig({ ...next, profileName: activeProfile, username, }); setError(null); } catch (e) { setError(String(e)); } }, [activeProfile, username], ); const setField = useCallback( (k: K, v: Config[K]) => { setConfig((c) => { if (!c) return c; const next = { ...c, [k]: v }; if (saveTimer.current) clearTimeout(saveTimer.current); saveTimer.current = setTimeout(() => { void save(next); }, SAVE_DEBOUNCE_MS); return next; }); }, [save], ); const saveNow = useCallback(async () => { if (!config) return; if (saveTimer.current) { clearTimeout(saveTimer.current); saveTimer.current = null; } await save(config); }, [config, save]); const saveField = useCallback( async (k: K, v: Config[K]) => { if (!config) return; if (saveTimer.current) { clearTimeout(saveTimer.current); saveTimer.current = null; } const next = { ...config, [k]: v }; setConfig(next); await save(next); }, [config, save], ); return { config, error, setField, saveField, saveNow }; }; export const SettingsProvider = ({ children }: { children: ReactNode }) => { const { config, error, setField, saveField, saveNow } = useSettingsState(); return ( <> {error &&

{error}

}
{!config ? (
Loading…
) : ( {children} )}
); };