135 lines
3.3 KiB
JavaScript
135 lines
3.3 KiB
JavaScript
import { createContext, useContext, useEffect, useState } from "react";
|
|
import { AuthContext } from "./AuthContext";
|
|
|
|
|
|
const DEFAULT_SETTINGS = {
|
|
// Appearance
|
|
theme: "auto", // "light" | "dark" | "auto"
|
|
compactView: false,
|
|
|
|
// List Display
|
|
showRecentlyBought: true,
|
|
recentlyBoughtCount: 10,
|
|
recentlyBoughtCollapsed: false,
|
|
|
|
// Behavior
|
|
confirmBeforeBuy: true,
|
|
autoReloadInterval: 0, // 0 = disabled, else minutes
|
|
hapticFeedback: true,
|
|
|
|
// Advanced
|
|
debugMode: false,
|
|
};
|
|
|
|
const SETTINGS_KEYS = Object.keys(DEFAULT_SETTINGS);
|
|
|
|
function normalizeSettings(savedSettings = {}) {
|
|
return SETTINGS_KEYS.reduce((normalized, key) => {
|
|
normalized[key] = Object.prototype.hasOwnProperty.call(savedSettings, key)
|
|
? savedSettings[key]
|
|
: DEFAULT_SETTINGS[key];
|
|
return normalized;
|
|
}, {});
|
|
}
|
|
|
|
|
|
export const SettingsContext = createContext({
|
|
settings: DEFAULT_SETTINGS,
|
|
updateSettings: () => { },
|
|
resetSettings: () => { },
|
|
});
|
|
|
|
|
|
export const SettingsProvider = ({ children }) => {
|
|
const { username } = useContext(AuthContext);
|
|
const [settings, setSettings] = useState(DEFAULT_SETTINGS);
|
|
|
|
|
|
// Load settings from localStorage when user changes
|
|
useEffect(() => {
|
|
if (!username) {
|
|
setSettings(DEFAULT_SETTINGS);
|
|
return;
|
|
}
|
|
|
|
const storageKey = `user_preferences_${username}`;
|
|
const savedSettings = localStorage.getItem(storageKey);
|
|
|
|
if (savedSettings) {
|
|
try {
|
|
const parsed = JSON.parse(savedSettings);
|
|
const normalized = normalizeSettings(parsed);
|
|
setSettings(normalized);
|
|
localStorage.setItem(storageKey, JSON.stringify(normalized));
|
|
} catch (error) {
|
|
console.error("Failed to parse settings:", error);
|
|
setSettings(DEFAULT_SETTINGS);
|
|
}
|
|
} else {
|
|
setSettings(DEFAULT_SETTINGS);
|
|
}
|
|
}, [username]);
|
|
|
|
|
|
// Apply theme to document
|
|
useEffect(() => {
|
|
const applyTheme = () => {
|
|
let theme = settings.theme;
|
|
|
|
if (theme === "auto") {
|
|
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
theme = prefersDark ? "dark" : "light";
|
|
}
|
|
|
|
document.documentElement.setAttribute("data-theme", theme);
|
|
};
|
|
|
|
applyTheme();
|
|
|
|
// Listen for system theme changes if in auto mode
|
|
if (settings.theme === "auto") {
|
|
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
const handler = () => applyTheme();
|
|
mediaQuery.addEventListener("change", handler);
|
|
return () => mediaQuery.removeEventListener("change", handler);
|
|
}
|
|
}, [settings.theme]);
|
|
|
|
|
|
// Save settings to localStorage
|
|
const updateSettings = (newSettings) => {
|
|
if (!username) return;
|
|
|
|
const updated = normalizeSettings({ ...settings, ...newSettings });
|
|
setSettings(updated);
|
|
|
|
const storageKey = `user_preferences_${username}`;
|
|
localStorage.setItem(storageKey, JSON.stringify(updated));
|
|
};
|
|
|
|
|
|
// Reset to defaults
|
|
const resetSettings = () => {
|
|
if (!username) return;
|
|
|
|
setSettings(DEFAULT_SETTINGS);
|
|
|
|
const storageKey = `user_preferences_${username}`;
|
|
localStorage.setItem(storageKey, JSON.stringify(DEFAULT_SETTINGS));
|
|
};
|
|
|
|
|
|
const value = {
|
|
settings,
|
|
updateSettings,
|
|
resetSettings,
|
|
};
|
|
|
|
|
|
return (
|
|
<SettingsContext.Provider value={value}>
|
|
{children}
|
|
</SettingsContext.Provider>
|
|
);
|
|
};
|