import { useLang } from "../hooks/useLang.js"; import { Action as PrefAction, State as PrefState, usePref } from "../hooks/usePref.js"; import { TrimOptios } from "../lrc-parser.js"; import { toastPubSub } from "./toast.js"; const { createContext, useEffect, useMemo } = React; interface IAppContext { lang: Language; prefState: PrefState; prefDispatch: React.Dispatch; trimOptions: Required; } const enum Bits { lang, // lrcFormat, builtInAudio, // screenButton, // themeColor, prefState, } // tslint:disable: no-bitwise export const enum ChangBits { lang = 1 << Bits.lang, // lrcFormat = 1 << Bits.lrcFormat, builtInAudio = 1 << Bits.builtInAudio, // screenButton = 1 << Bits.screenButton, // themeColor = 1 << Bits.themeColor, prefState = 1 << Bits.prefState, } export const appContext = createContext(undefined, (prev, next) => { let bits = 0; if (prev.lang !== next.lang) { bits |= ChangBits.lang; } // const changed = (prop: keyof IAppContext["prefState"]) => { // return prev.prefState[prop] !== next.prefState[prop]; // }; // if (changed("spaceStart") || changed("spaceEnd") || changed("fixed")) { // bits |= ChangBits.lrcFormat; // } // if (changed("builtInAudio")) { // bits |= ChangBits.builtInAudio; // } // if (changed("screenButton")) { // bits |= ChangBits.screenButton; // } // if (changed("themeColor")) { // bits |= ChangBits.themeColor; // } if (prev.prefState.builtInAudio !== next.prefState.builtInAudio) { bits |= ChangBits.builtInAudio; } if (prev.prefState !== next.prefState) { bits |= ChangBits.prefState; } return bits; }); export const AppProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { const [prefState, prefDispatch] = usePref(() => localStorage.getItem(LSK.preferences) || Const.emptyString); const [lang, setLang] = useLang(); useEffect(() => { setLang(prefState.lang).catch((error: Error) => { toastPubSub.pub({ type: "warning", text: error.message, }); }); }, [prefState.lang, setLang]); useEffect(() => { document.title = lang.app.fullname; document.documentElement.lang = prefState.lang; }, [lang, prefState, prefState.lang]); const value = useMemo(() => { return { lang, prefState, prefDispatch, trimOptions: { trimStart: prefState.spaceStart >= 0, trimEnd: prefState.spaceEnd >= 0, }, }; }, [lang, prefDispatch, prefState]); return {children}; };