This commit is contained in:
Reudy 2026-09-26 19:13:02 +02:00
commit 0ad405c26e
78 changed files with 9127 additions and 0 deletions

View file

@ -0,0 +1,93 @@
// 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<SettingsData>(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();