mirror of
https://github.com/immich-app/immich
synced 2025-11-14 17:36:12 +00:00
refactor: theme manager (#17976)
This commit is contained in:
parent
2c2dd01bf0
commit
038a82c4f1
11 changed files with 197 additions and 85 deletions
81
web/src/lib/utils/persisted.ts
Normal file
81
web/src/lib/utils/persisted.ts
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
import { browser } from '$app/environment';
|
||||
import { createSubscriber } from 'svelte/reactivity';
|
||||
|
||||
type PersistedBaseOptions<T> = {
|
||||
read: (key: string) => T | undefined;
|
||||
write: (key: string, value: T) => void;
|
||||
};
|
||||
|
||||
class PersistedBase<T> {
|
||||
#value: T;
|
||||
#subscribe: () => void;
|
||||
#update = () => {};
|
||||
|
||||
#write: (value: T) => void;
|
||||
|
||||
get current() {
|
||||
this.#subscribe();
|
||||
return this.#value as T;
|
||||
}
|
||||
|
||||
set current(value: T) {
|
||||
this.#write(value);
|
||||
this.#update();
|
||||
this.#value = value;
|
||||
}
|
||||
|
||||
constructor(key: string, defaultValue: T, options: PersistedBaseOptions<T>) {
|
||||
const value = options.read(key);
|
||||
|
||||
this.#value = value === undefined ? defaultValue : value;
|
||||
this.#write = (value: T) => options.write(key, value);
|
||||
|
||||
this.#subscribe = createSubscriber((update) => {
|
||||
this.#update = update;
|
||||
|
||||
return () => {
|
||||
this.#update = () => {};
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
type PersistedLocalStorageOptions<T> = {
|
||||
serializer?: {
|
||||
stringify(value: T): string;
|
||||
parse(text: string): T;
|
||||
};
|
||||
valid?: (value: T | unknown) => value is T;
|
||||
};
|
||||
|
||||
export class PersistedLocalStorage<T> extends PersistedBase<T> {
|
||||
constructor(key: string, defaultValue: T, options: PersistedLocalStorageOptions<T> = {}) {
|
||||
const valid = options.valid || (() => true);
|
||||
const serializer = options.serializer || JSON;
|
||||
|
||||
super(key, defaultValue, {
|
||||
read: (key: string) => {
|
||||
if (!browser) {
|
||||
return;
|
||||
}
|
||||
|
||||
const item = localStorage.getItem(key) ?? undefined;
|
||||
if (item === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const parsed = serializer.parse(item);
|
||||
if (!valid(parsed)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return parsed;
|
||||
},
|
||||
write: (key: string, value: T) => {
|
||||
if (browser) {
|
||||
localStorage.setItem(key, serializer.stringify(value));
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue