mirror of
https://github.com/stoatchat/for-legacy-web.git
synced 2026-03-07 09:25:27 +00:00
feat(mobx): start implementing theme store
This commit is contained in:
@@ -2,11 +2,12 @@ import { action, computed, makeAutoObservable, ObservableMap } from "mobx";
|
||||
|
||||
import { mapToRecord } from "../../lib/conversion";
|
||||
|
||||
import { Theme } from "../../context/Theme";
|
||||
import { Fonts, MonospaceFonts, Overrides, Theme } from "../../context/Theme";
|
||||
|
||||
import { Sounds } from "../../assets/sounds/Audio";
|
||||
import Persistent from "../interfaces/Persistent";
|
||||
import Store from "../interfaces/Store";
|
||||
import STheme from "./helpers/STheme";
|
||||
|
||||
export type SoundOptions = {
|
||||
[key in Sounds]?: boolean;
|
||||
@@ -20,43 +21,35 @@ interface ISettings {
|
||||
|
||||
"appearance:emoji": EmojiPack;
|
||||
"appearance:ligatures": boolean;
|
||||
"appearance:theme:base": string;
|
||||
"appearance:theme:custom": Partial<Theme>;
|
||||
|
||||
"appearance:theme:base": "dark" | "light";
|
||||
"appearance:theme:overrides": Partial<Overrides>;
|
||||
"appearance:theme:light": boolean;
|
||||
"appearance:theme:font": Fonts;
|
||||
"appearance:theme:monoFont": MonospaceFonts;
|
||||
"appearance:theme:css": string;
|
||||
}
|
||||
|
||||
/*const Schema: {
|
||||
[key in keyof ISettings]:
|
||||
| "string"
|
||||
| "number"
|
||||
| "boolean"
|
||||
| "object"
|
||||
| "function";
|
||||
} = {
|
||||
"notifications:desktop": "boolean",
|
||||
"notifications:sounds": "object",
|
||||
|
||||
"appearance:emoji": "string",
|
||||
"appearance:ligatures": "boolean",
|
||||
"appearance:theme:base": "string",
|
||||
"appearance:theme:custom": "object",
|
||||
};*/
|
||||
|
||||
/**
|
||||
* Manages user settings.
|
||||
*/
|
||||
export default class Settings implements Store, Persistent<ISettings> {
|
||||
private data: ObservableMap<string, unknown>;
|
||||
|
||||
theme: STheme;
|
||||
|
||||
/**
|
||||
* Construct new Layout store.
|
||||
* Construct new Settings store.
|
||||
*/
|
||||
constructor() {
|
||||
this.data = new ObservableMap();
|
||||
makeAutoObservable(this);
|
||||
|
||||
this.theme = new STheme(this);
|
||||
}
|
||||
|
||||
get id() {
|
||||
return "layout";
|
||||
return "settings";
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
@@ -69,18 +62,38 @@ export default class Settings implements Store, Persistent<ISettings> {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a settings key.
|
||||
* @param key Colon-divided key
|
||||
* @param value Value
|
||||
*/
|
||||
@action set<T extends keyof ISettings>(key: T, value: ISettings[T]) {
|
||||
return this.data.set(key, value);
|
||||
this.data.set(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a settings key.
|
||||
* @param key Colon-divided key
|
||||
* @returns Value at key
|
||||
*/
|
||||
@computed get<T extends keyof ISettings>(key: T) {
|
||||
return this.data.get(key) as ISettings[T] | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a value in settings without type-checking.
|
||||
* @param key Colon-divided key
|
||||
* @param value Value
|
||||
*/
|
||||
@action setUnchecked(key: string, value: unknown) {
|
||||
return this.data.set(key, value);
|
||||
this.data.set(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a settings key with unknown type.
|
||||
* @param key Colon-divided key
|
||||
* @returns Value at key
|
||||
*/
|
||||
@computed getUnchecked(key: string) {
|
||||
return this.data.get(key);
|
||||
}
|
||||
|
||||
94
src/mobx/stores/helpers/STheme.ts
Normal file
94
src/mobx/stores/helpers/STheme.ts
Normal file
@@ -0,0 +1,94 @@
|
||||
import { makeAutoObservable, computed } from "mobx";
|
||||
|
||||
import {
|
||||
Theme,
|
||||
PRESETS,
|
||||
Variables,
|
||||
DEFAULT_FONT,
|
||||
DEFAULT_MONO_FONT,
|
||||
} from "../../../context/Theme";
|
||||
|
||||
import Settings from "../Settings";
|
||||
|
||||
/**
|
||||
* Helper class for reading and writing themes.
|
||||
*/
|
||||
export default class STheme {
|
||||
private settings: Settings;
|
||||
|
||||
/**
|
||||
* Construct a new theme helper.
|
||||
* @param settings Settings parent class
|
||||
*/
|
||||
constructor(settings: Settings) {
|
||||
this.settings = settings;
|
||||
makeAutoObservable(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the base theme used for this theme.
|
||||
* @returns Id of base theme
|
||||
*/
|
||||
@computed getBase() {
|
||||
return this.settings.get("appearance:theme:base") ?? "dark";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether the theme is light.
|
||||
* @returns True if the theme is light
|
||||
*/
|
||||
@computed isLight() {
|
||||
return (
|
||||
this.settings.get("appearance:theme:light") ??
|
||||
this.getBase() === "light"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current theme's CSS variables.
|
||||
* @returns Record of CSS variables
|
||||
*/
|
||||
@computed getVariables(): Theme {
|
||||
return {
|
||||
...PRESETS[this.getBase()],
|
||||
...this.settings.get("appearance:theme:overrides"),
|
||||
light: this.isLight(),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specific value of a variable by its key.
|
||||
* @param key Variable
|
||||
* @returns Value of variable
|
||||
*/
|
||||
@computed getVariable(key: Variables) {
|
||||
return (this.settings.get("appearance:theme:overrides") ??
|
||||
PRESETS[this.getBase()])[key]!;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current applied font.
|
||||
* @returns Current font
|
||||
*/
|
||||
@computed getFont() {
|
||||
return this.settings.get("appearance:theme:font") ?? DEFAULT_FONT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current applied monospace font.
|
||||
* @returns Current monospace font
|
||||
*/
|
||||
@computed getMonospaceFont() {
|
||||
return (
|
||||
this.settings.get("appearance:theme:monoFont") ?? DEFAULT_MONO_FONT
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the currently applied CSS snippet.
|
||||
* @returns CSS string
|
||||
*/
|
||||
@computed getCSS() {
|
||||
return this.settings.get("appearance:theme:css");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user