Init
This commit is contained in:
commit
0ad405c26e
78 changed files with 9127 additions and 0 deletions
93
src/lib/state/settings.svelte.ts
Normal file
93
src/lib/state/settings.svelte.ts
Normal 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();
|
||||
Loading…
Add table
Add a link
Reference in a new issue