| 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); |
| } |
|
|