File size: 1,904 Bytes
81fc505 4ddb4c4 81fc505 4ddb4c4 81fc505 4ddb4c4 81fc505 4ddb4c4 81fc505 | 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 | import { createContext, useContext, useEffect, useMemo, useState } from "react";
import { STORAGE_KEYS } from "../lib/storage";
const PreferencesContext = createContext(null);
export function PreferencesProvider({ children }) {
const [theme, setTheme] = useState(() => localStorage.getItem(STORAGE_KEYS.theme) || "dark");
const [mode, setMode] = useState(() => localStorage.getItem(STORAGE_KEYS.mode) || "read");
const [fontSize, setFontSize] = useState(() => localStorage.getItem(STORAGE_KEYS.fontSize) || "medium");
const [sidebarOpen, setSidebarOpen] = useState(false);
useEffect(() => {
document.documentElement.dataset.theme = theme === "light" ? "light" : "dark";
localStorage.setItem(STORAGE_KEYS.theme, theme);
}, [theme]);
useEffect(() => {
localStorage.setItem(STORAGE_KEYS.mode, mode);
}, [mode]);
useEffect(() => {
document.documentElement.dataset.fontSize = fontSize;
localStorage.setItem(STORAGE_KEYS.fontSize, fontSize);
}, [fontSize]);
useEffect(() => {
function onKeyDown(event) {
const tagName = document.activeElement?.tagName;
const isTyping = tagName === "INPUT" || tagName === "TEXTAREA";
if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "e" && !isTyping) {
event.preventDefault();
setMode((current) => (current === "read" ? "edit" : "read"));
}
}
window.addEventListener("keydown", onKeyDown);
return () => window.removeEventListener("keydown", onKeyDown);
}, []);
const value = useMemo(
() => ({
theme,
setTheme,
mode,
setMode,
fontSize,
setFontSize,
sidebarOpen,
setSidebarOpen
}),
[fontSize, mode, sidebarOpen, theme]
);
return <PreferencesContext.Provider value={value}>{children}</PreferencesContext.Provider>;
}
export function usePreferences() {
return useContext(PreferencesContext);
}
|