MNEMO / client /src /context /PreferencesContext.jsx
SyntaxAdi
style: fix image rendering and refine AnswerRenderer logic
bcf42ee
Raw
History Blame Contribute Delete
1.9 kB
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);
}