slack status without the slack
status.zzstoatzz.io
hatk
statusphere
1import { writable, get } from "svelte/store";
2import { callXrpc } from "$hatk/client";
3
4export interface Preferences {
5 accentColor: string;
6 font: string;
7 theme: string;
8}
9
10const DEFAULT: Preferences = {
11 accentColor: "#4a9eff",
12 font: "mono",
13 theme: "dark",
14};
15
16export const FONTS = [
17 { value: "system", label: "system", css: "system-ui, -apple-system, sans-serif" },
18 { value: "mono", label: "mono", css: "ui-monospace, SF Mono, Monaco, monospace" },
19 { value: "serif", label: "serif", css: "ui-serif, Georgia, serif" },
20 { value: "comic", label: "comic", css: "Comic Sans MS, Comic Sans, cursive" },
21];
22
23export const ACCENT_COLORS = [
24 "#4a9eff", "#10b981", "#f59e0b", "#ef4444",
25 "#8b5cf6", "#ec4899", "#06b6d4", "#f97316",
26];
27
28export const preferences = writable<Preferences>({ ...DEFAULT });
29
30export function loadPreferences(prefs: Record<string, unknown> | null): void {
31 if (!prefs) return;
32 const merged = { ...DEFAULT };
33 if (typeof prefs.accentColor === "string") merged.accentColor = prefs.accentColor;
34 if (typeof prefs.font === "string") merged.font = prefs.font;
35 if (typeof prefs.theme === "string") merged.theme = prefs.theme;
36 preferences.set(merged);
37 applyPreferences(merged);
38}
39
40export function applyPreferences(prefs: Preferences): void {
41 if (typeof document === "undefined") return;
42 document.documentElement.style.setProperty("--accent", prefs.accentColor);
43 const font = FONTS.find((f) => f.value === prefs.font) ?? FONTS[1];
44 document.documentElement.style.setProperty("--font-family", font.css);
45 document.documentElement.setAttribute("data-theme", prefs.theme);
46 localStorage.setItem("theme", prefs.theme);
47}
48
49export async function savePreferences(prefs: Preferences): Promise<void> {
50 preferences.set(prefs);
51 applyPreferences(prefs);
52 await Promise.all([
53 callXrpc("dev.hatk.putPreference", { key: "accentColor", value: prefs.accentColor }),
54 callXrpc("dev.hatk.putPreference", { key: "font", value: prefs.font }),
55 callXrpc("dev.hatk.putPreference", { key: "theme", value: prefs.theme }),
56 ]);
57}