1import { writable } from 'svelte/store';
2import { defaultTheme, type Theme } from './theme';
3
4export type ApiEndpoints = Record<string, string> & {
5 slingshot: string;
6 spacedust: string;
7 constellation: string;
8};
9export type Settings = {
10 endpoints: ApiEndpoints;
11 theme: Theme;
12 socialAppUrl: string;
13};
14
15export const defaultSettings: Settings = {
16 endpoints: {
17 slingshot: 'https://slingshot.microcosm.blue',
18 spacedust: 'https://spacedust.microcosm.blue',
19 constellation: 'https://constellation.microcosm.blue'
20 },
21 theme: defaultTheme,
22 socialAppUrl: 'https://bsky.app'
23};
24
25const createSettingsStore = () => {
26 const stored = localStorage.getItem('settings');
27
28 const initial: Partial<Settings> = stored ? JSON.parse(stored) : defaultSettings;
29 initial.endpoints = initial.endpoints ?? defaultSettings.endpoints;
30 initial.theme = initial.theme ?? defaultSettings.theme;
31 initial.socialAppUrl = initial.socialAppUrl ?? defaultSettings.socialAppUrl;
32
33 const { subscribe, set, update } = writable<Settings>(initial as Settings);
34
35 subscribe((settings) => {
36 const theme = settings.theme;
37 document.documentElement.style.setProperty('--nucleus-bg', theme.bg);
38 document.documentElement.style.setProperty('--nucleus-fg', theme.fg);
39 document.documentElement.style.setProperty('--nucleus-accent', theme.accent);
40 document.documentElement.style.setProperty('--nucleus-accent2', theme.accent2);
41 });
42
43 return {
44 subscribe,
45 set: (value: Settings) => {
46 localStorage.setItem('settings', JSON.stringify(value));
47 set(value);
48 },
49 update: (fn: (value: Settings) => Settings) => {
50 update((value) => {
51 const newValue = fn(value);
52 localStorage.setItem('settings', JSON.stringify(newValue));
53 return newValue;
54 });
55 },
56 reset: () => {
57 localStorage.setItem('settings', JSON.stringify(defaultSettings));
58 set(defaultSettings);
59 }
60 };
61};
62
63export const settings = createSettingsStore();
64
65export const needsReload = (current: Settings, other: Settings): boolean => {
66 return (
67 current.endpoints.slingshot !== other.endpoints.slingshot ||
68 current.endpoints.spacedust !== other.endpoints.spacedust ||
69 current.endpoints.constellation !== other.endpoints.constellation
70 );
71};