mirror of
https://github.com/stoatchat/for-legacy-web.git
synced 2026-03-06 17:11:55 +00:00
feat(mobx): start work on migrations
This commit is contained in:
11
src/mobx/interfaces/Migrate.ts
Normal file
11
src/mobx/interfaces/Migrate.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import Store from "./Store";
|
||||
|
||||
/**
|
||||
* A data store which is migrated forwards.
|
||||
*/
|
||||
export default interface Migrate<K extends string> extends Store {
|
||||
/**
|
||||
* Migrate this data store.
|
||||
*/
|
||||
migrate(key: K, data: Record<string, unknown>, rev: number): void;
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
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()];
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,6 @@ export default class Experiments implements Store, Persistent<Data> {
|
||||
*/
|
||||
constructor() {
|
||||
this.enabled = new ObservableSet();
|
||||
|
||||
makeAutoObservable(this);
|
||||
}
|
||||
|
||||
|
||||
70
src/mobx/stores/Sync.ts
Normal file
70
src/mobx/stores/Sync.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import {
|
||||
action,
|
||||
computed,
|
||||
makeAutoObservable,
|
||||
ObservableMap,
|
||||
ObservableSet,
|
||||
} from "mobx";
|
||||
import { Client } from "revolt.js";
|
||||
|
||||
import { mapToRecord } from "../../lib/conversion";
|
||||
|
||||
import Persistent from "../interfaces/Persistent";
|
||||
import Store from "../interfaces/Store";
|
||||
|
||||
export type SyncKeys = "theme" | "appearance" | "locale" | "notifications";
|
||||
|
||||
export const SYNC_KEYS: SyncKeys[] = [
|
||||
"theme",
|
||||
"appearance",
|
||||
"locale",
|
||||
"notifications",
|
||||
];
|
||||
|
||||
interface Data {
|
||||
disabled: SyncKeys[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles syncing settings data.
|
||||
*/
|
||||
export default class Sync implements Store, Persistent<Data> {
|
||||
private disabled: ObservableSet<SyncKeys>;
|
||||
|
||||
/**
|
||||
* Construct new Sync store.
|
||||
*/
|
||||
constructor() {
|
||||
this.disabled = new ObservableSet();
|
||||
makeAutoObservable(this);
|
||||
this.isEnabled = this.isEnabled.bind(this);
|
||||
}
|
||||
|
||||
get id() {
|
||||
return "sync";
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return {
|
||||
enabled: [...this.disabled],
|
||||
};
|
||||
}
|
||||
|
||||
@action hydrate(data: Data) {
|
||||
if (data.disabled) {
|
||||
for (const key of data.disabled) {
|
||||
this.disabled.add(key as SyncKeys);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@computed isEnabled(key: SyncKeys) {
|
||||
return !this.disabled.has(key);
|
||||
}
|
||||
|
||||
async pull(client: Client) {
|
||||
const data = await client.syncFetchSettings(
|
||||
SYNC_KEYS.filter(this.isEnabled),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,9 @@ export default class STheme {
|
||||
);
|
||||
}
|
||||
|
||||
@action hydrate(data: Partial<Theme>) {
|
||||
@action hydrate(data: Partial<Theme>, resetCSS = false) {
|
||||
if (resetCSS) this.setCSS();
|
||||
|
||||
for (const key of Object.keys(data)) {
|
||||
const value = data[key as keyof Theme] as string;
|
||||
switch (key) {
|
||||
@@ -137,8 +139,8 @@ export default class STheme {
|
||||
);
|
||||
}
|
||||
|
||||
@action setCSS(value: string) {
|
||||
if (value.length > 0) {
|
||||
@action setCSS(value?: string) {
|
||||
if (value && value.length > 0) {
|
||||
this.settings.set("appearance:theme:css", value);
|
||||
} else {
|
||||
this.settings.remove("appearance:theme:css");
|
||||
@@ -153,6 +155,13 @@ export default class STheme {
|
||||
return this.settings.get("appearance:theme:css");
|
||||
}
|
||||
|
||||
@computed isModified() {
|
||||
return (
|
||||
Object.keys(this.settings.get("appearance:theme:overrides") ?? {})
|
||||
.length > 0
|
||||
);
|
||||
}
|
||||
|
||||
@action setBase(base?: "light" | "dark") {
|
||||
if (base) {
|
||||
this.settings.set("appearance:theme:base", base);
|
||||
|
||||
Reference in New Issue
Block a user