summaryrefslogtreecommitdiffstats
path: root/src/contexts/Settings.tsx
blob: 2bbebcc601a8b3eaf50a3a53f05a6aae7a2745d8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import * as React from "react";
import {
  Context,
  createContext,
  PropsWithChildren,
  useCallback,
  useEffect,
  useState,
} from "react";
import { Settings } from "~/types";

interface SettingsApi {
  darkMode: boolean;
  setSetting: (key: keyof Settings, value: any) => void;
}

export const SettingsContext = createContext<Partial<SettingsApi>>(
  {}
) as Context<SettingsApi>;

export default function SettingsProvider({ children }: PropsWithChildren<any>) {
  // const themeConfig = useMemo(() => new ThemeConfig(), []);
  const [settings, setSettings] = useState<Settings>(() => {
    const stored = localStorage.getItem("settings");

    if (stored) {
      return JSON.parse(stored);
    }

    return {
      darkMode:
        window.matchMedia &&
        window.matchMedia("(prefers-color-scheme: dark)").matches,
    };
  });

  const setSetting = useCallback(
    (key: keyof Settings, value: any) => {
      const newSetting = {
        ...settings,
        [key]: value,
      };
      setSettings(newSetting);
      localStorage.setItem("settings", JSON.stringify(newSetting));
    },
    [settings]
  );

  useEffect(() => {
    document
      .querySelector("html")
      ?.setAttribute("data-bs-theme", settings.darkMode ? "dark" : "light");
  }, [settings.darkMode]);

  return (
    <SettingsContext.Provider
      value={{
        darkMode: settings.darkMode,
        setSetting,
      }}
    >
      {children}
    </SettingsContext.Provider>
  );
}