// User settings, persisted in localStorage (including the GitHub token — // by design there is no backend holding it). import { DEFAULT_PALM, type PalmOptions } from '$lib/ink/palm'; export type ThemePref = 'system' | 'light' | 'dark'; export type PageStylePref = 'paper' | 'match'; export interface GitHubSettings { token: string; owner: string; repo: string; branch: string; /** Folder inside the repo that holds the vault ('' = repo root). */ dir: string; } interface SettingsData { theme: ThemePref; pageStyle: PageStylePref; fingerDraw: boolean; palm: PalmOptions; github: GitHubSettings; /** Minutes between automatic pushes (0 = manual only). */ pushInterval: number; penColors: string[]; highlighterColors: string[]; } const DEFAULTS: SettingsData = { theme: 'system', pageStyle: 'match', fingerDraw: true, palm: DEFAULT_PALM, github: { token: '', owner: '', repo: '', branch: 'main', dir: '' }, pushInterval: 5, penColors: ['#1f1f1f', '#2563eb', '#dc2626', '#16a34a', '#9333ea'], highlighterColors: ['#ffd400', '#7ee081', '#6ec5ff', '#ff8ad8'] }; const KEY = 'papure:settings'; function load(): SettingsData { try { const raw = localStorage.getItem(KEY); if (!raw) return structuredClone(DEFAULTS); const saved = JSON.parse(raw); return { ...DEFAULTS, ...saved, palm: { ...DEFAULTS.palm, ...saved.palm }, github: { ...DEFAULTS.github, ...saved.github } }; } catch { return structuredClone(DEFAULTS); } } class Settings { data = $state(load()); private systemDark = $state(false); constructor() { if (typeof window === 'undefined') return; const mq = window.matchMedia('(prefers-color-scheme: dark)'); this.systemDark = mq.matches; mq.addEventListener('change', (e) => (this.systemDark = e.matches)); } get dark() { return this.data.theme === 'dark' || (this.data.theme === 'system' && this.systemDark); } get githubReady() { const g = this.data.github; return !!(g.token && g.owner && g.repo && g.branch); } save() { try { localStorage.setItem(KEY, JSON.stringify($state.snapshot(this.data))); } catch { // Storage unavailable (private mode) — settings last for this session only. } } toggleTheme() { this.data.theme = this.dark ? 'light' : 'dark'; this.save(); } } export const settings = new Settings();