forked from abner/for-legacy-web
feat(mobx): continue implementing themes; performance work on settings
This commit is contained in:
76
src/mobx/stores/Cache.ts
Normal file
76
src/mobx/stores/Cache.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import { action, computed, makeAutoObservable, ObservableMap } from "mobx";
|
||||
|
||||
import { mapToRecord } from "../../lib/conversion";
|
||||
|
||||
import { StoredTheme } from "../../redux/reducers/themes";
|
||||
|
||||
import Persistent from "../interfaces/Persistent";
|
||||
import Store from "../interfaces/Store";
|
||||
|
||||
interface Data {
|
||||
themes: Record<string, StoredTheme>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cache data store for temporary, long-lived data.
|
||||
*/
|
||||
export default class Cache implements Store, Persistent<Data> {
|
||||
private themes: ObservableMap<string, StoredTheme>;
|
||||
|
||||
/**
|
||||
* Construct new Cache store.
|
||||
*/
|
||||
constructor() {
|
||||
this.themes = new ObservableMap();
|
||||
makeAutoObservable(this);
|
||||
}
|
||||
|
||||
get id() {
|
||||
return "draft";
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return {
|
||||
themes: JSON.parse(JSON.stringify(mapToRecord(this.themes))),
|
||||
};
|
||||
}
|
||||
|
||||
@action hydrate(data: Data) {
|
||||
Object.keys(data.themes).forEach((key) =>
|
||||
this.themes.set(key, data.themes[key]),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cache a given theme.
|
||||
* @param theme Theme
|
||||
*/
|
||||
@action cacheTheme(theme: StoredTheme) {
|
||||
this.themes.set(theme.slug, theme);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a cached theme.
|
||||
* @param slug String
|
||||
*/
|
||||
@action removeTheme(slug: string) {
|
||||
this.themes.delete(slug);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a cached theme by its slug.
|
||||
* @param slug Theme slug
|
||||
* @returns Theme, if found
|
||||
*/
|
||||
@computed getTheme(slug: string) {
|
||||
return this.themes.get(slug);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all cached themes.
|
||||
* @returns Themes
|
||||
*/
|
||||
@computed getThemes() {
|
||||
return [...this.themes.values()];
|
||||
}
|
||||
}
|
||||
@@ -80,6 +80,10 @@ export default class Settings implements Store, Persistent<ISettings> {
|
||||
return this.data.get(key) as ISettings[T] | undefined;
|
||||
}
|
||||
|
||||
@action remove<T extends keyof ISettings>(key: T) {
|
||||
this.data.delete(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a value in settings without type-checking.
|
||||
* @param key Colon-divided key
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { makeAutoObservable, computed } from "mobx";
|
||||
import { makeAutoObservable, computed, action } from "mobx";
|
||||
|
||||
import {
|
||||
Theme,
|
||||
@@ -6,6 +6,8 @@ import {
|
||||
Variables,
|
||||
DEFAULT_FONT,
|
||||
DEFAULT_MONO_FONT,
|
||||
Fonts,
|
||||
MonospaceFonts,
|
||||
} from "../../../context/Theme";
|
||||
|
||||
import Settings from "../Settings";
|
||||
@@ -23,6 +25,7 @@ export default class STheme {
|
||||
constructor(settings: Settings) {
|
||||
this.settings = settings;
|
||||
makeAutoObservable(this);
|
||||
this.setBase = this.setBase.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,6 +59,13 @@ export default class STheme {
|
||||
};
|
||||
}
|
||||
|
||||
@action setVariable(key: Variables, value: string) {
|
||||
this.settings.set("appearance:theme:overrides", {
|
||||
...this.settings.get("appearance:theme:overrides"),
|
||||
[key]: value,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specific value of a variable by its key.
|
||||
* @param key Variable
|
||||
@@ -66,6 +76,10 @@ export default class STheme {
|
||||
PRESETS[this.getBase()])[key]!;
|
||||
}
|
||||
|
||||
@action setFont(font: Fonts) {
|
||||
this.settings.set("appearance:theme:font", font);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current applied font.
|
||||
* @returns Current font
|
||||
@@ -74,6 +88,10 @@ export default class STheme {
|
||||
return this.settings.get("appearance:theme:font") ?? DEFAULT_FONT;
|
||||
}
|
||||
|
||||
@action setMonospaceFont(font: MonospaceFonts) {
|
||||
this.settings.set("appearance:theme:monoFont", font);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current applied monospace font.
|
||||
* @returns Current monospace font
|
||||
@@ -84,6 +102,14 @@ export default class STheme {
|
||||
);
|
||||
}
|
||||
|
||||
@action setCSS(value: string) {
|
||||
if (value.length > 0) {
|
||||
this.settings.set("appearance:theme:css", value);
|
||||
} else {
|
||||
this.settings.remove("appearance:theme:css");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the currently applied CSS snippet.
|
||||
* @returns CSS string
|
||||
@@ -91,4 +117,12 @@ export default class STheme {
|
||||
@computed getCSS() {
|
||||
return this.settings.get("appearance:theme:css");
|
||||
}
|
||||
|
||||
@action setBase(base?: "light" | "dark") {
|
||||
if (base) {
|
||||
this.settings.set("appearance:theme:base", base);
|
||||
} else {
|
||||
this.settings.remove("appearance:theme:base");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user