mirror of
https://github.com/revoltchat/revite.git
synced 2024-11-29 02:10:59 -05:00
feat(mobx): migrate legacy data
This commit is contained in:
parent
e89bbb7455
commit
74430b1a8f
2 changed files with 105 additions and 13 deletions
|
@ -4,6 +4,8 @@ import localforage from "localforage";
|
||||||
import { makeAutoObservable, reaction } from "mobx";
|
import { makeAutoObservable, reaction } from "mobx";
|
||||||
import { Client } from "revolt.js";
|
import { Client } from "revolt.js";
|
||||||
|
|
||||||
|
import { legacyMigrateForwards, LegacyState } from "./legacy/redux";
|
||||||
|
|
||||||
import Persistent from "./interfaces/Persistent";
|
import Persistent from "./interfaces/Persistent";
|
||||||
import Syncable from "./interfaces/Syncable";
|
import Syncable from "./interfaces/Syncable";
|
||||||
import Auth from "./stores/Auth";
|
import Auth from "./stores/Auth";
|
||||||
|
@ -89,10 +91,23 @@ export default class State {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Temporarily ignore updates to a key.
|
||||||
|
* @param key Key to ignore
|
||||||
|
*/
|
||||||
setDisabled(key: string) {
|
setDisabled(key: string) {
|
||||||
this.disabled.add(key);
|
this.disabled.add(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save to disk.
|
||||||
|
*/
|
||||||
|
async save() {
|
||||||
|
for (const [id, store] of this.persistent) {
|
||||||
|
await localforage.setItem(id, store.toJSON());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register reaction listeners for persistent data stores.
|
* Register reaction listeners for persistent data stores.
|
||||||
* @returns Function to dispose of listeners
|
* @returns Function to dispose of listeners
|
||||||
|
@ -177,6 +192,20 @@ export default class State {
|
||||||
* Load data stores from local storage.
|
* Load data stores from local storage.
|
||||||
*/
|
*/
|
||||||
async hydrate() {
|
async hydrate() {
|
||||||
|
// Migrate legacy Redux store.
|
||||||
|
let legacy = await localforage.getItem("state");
|
||||||
|
if (legacy) {
|
||||||
|
if (typeof legacy === "string") {
|
||||||
|
legacy = JSON.parse(legacy);
|
||||||
|
}
|
||||||
|
|
||||||
|
legacyMigrateForwards(legacy as Partial<LegacyState>, this);
|
||||||
|
await localforage.removeItem("state");
|
||||||
|
await this.save();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load MobX store.
|
||||||
const sync = (await localforage.getItem("sync")) as DataSync;
|
const sync = (await localforage.getItem("sync")) as DataSync;
|
||||||
if (sync) {
|
if (sync) {
|
||||||
const { revision } = sync;
|
const { revision } = sync;
|
||||||
|
@ -205,15 +234,3 @@ export async function hydrateState() {
|
||||||
export function useApplicationState() {
|
export function useApplicationState() {
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Redux hydration:
|
|
||||||
* localForage.getItem("state").then((s) => {
|
|
||||||
if (s !== null) {
|
|
||||||
dispatch({ type: "__INIT", state: s as State });
|
|
||||||
}
|
|
||||||
|
|
||||||
state.hydrate().then(() => setLoaded(true));
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
|
@ -1,8 +1,15 @@
|
||||||
|
import { runInAction } from "mobx";
|
||||||
import { Session } from "revolt-api/types/Auth";
|
import { Session } from "revolt-api/types/Auth";
|
||||||
|
|
||||||
import { Language } from "../../context/Locale";
|
import { Language } from "../../context/Locale";
|
||||||
import { Fonts, MonospaceFonts, Overrides } from "../../context/Theme";
|
import {
|
||||||
|
Fonts,
|
||||||
|
MonospaceFonts,
|
||||||
|
Overrides,
|
||||||
|
ThemeOptions,
|
||||||
|
} from "../../context/Theme";
|
||||||
|
|
||||||
|
import State from "../State";
|
||||||
import { Data as DataAuth } from "../stores/Auth";
|
import { Data as DataAuth } from "../stores/Auth";
|
||||||
import { Data as DataLocaleOptions } from "../stores/LocaleOptions";
|
import { Data as DataLocaleOptions } from "../stores/LocaleOptions";
|
||||||
import { Data as DataNotificationOptions } from "../stores/NotificationOptions";
|
import { Data as DataNotificationOptions } from "../stores/NotificationOptions";
|
||||||
|
@ -62,6 +69,11 @@ export interface LegacyAuthState {
|
||||||
active?: string;
|
active?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface LegacySettings {
|
||||||
|
theme?: LegacyThemeOptions;
|
||||||
|
appearance?: LegacyAppearanceOptions;
|
||||||
|
}
|
||||||
|
|
||||||
export function legacyMigrateAuth(auth: LegacyAuthState): DataAuth {
|
export function legacyMigrateAuth(auth: LegacyAuthState): DataAuth {
|
||||||
return {
|
return {
|
||||||
current: auth.active,
|
current: auth.active,
|
||||||
|
@ -100,6 +112,20 @@ export function legacyMigrateAppearance(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove trolling from an object
|
||||||
|
* @param inp Object to remove trolling from
|
||||||
|
* @returns Object without trolling
|
||||||
|
*/
|
||||||
|
function detroll(inp: object): ISettings {
|
||||||
|
const obj: object = {};
|
||||||
|
Object.keys(inp)
|
||||||
|
.filter((x) => typeof (inp as any)[x] !== "undefined")
|
||||||
|
.map((x) => ((obj as any)[x] = (inp as any)[x]));
|
||||||
|
|
||||||
|
return obj as unknown as ISettings;
|
||||||
|
}
|
||||||
|
|
||||||
export function legacyMigrateNotification(
|
export function legacyMigrateNotification(
|
||||||
channel: LegacyNotifications,
|
channel: LegacyNotifications,
|
||||||
): DataNotificationOptions {
|
): DataNotificationOptions {
|
||||||
|
@ -116,3 +142,52 @@ export function legacyMigrateSync(sync: LegacySyncOptions): DataSync {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type LegacyState = {
|
||||||
|
locale: Language;
|
||||||
|
auth: LegacyAuthState;
|
||||||
|
settings: LegacySettings;
|
||||||
|
sync: LegacySyncOptions;
|
||||||
|
notifications: LegacyNotifications;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function legacyMigrateForwards(
|
||||||
|
data: Partial<LegacyState>,
|
||||||
|
target: State,
|
||||||
|
) {
|
||||||
|
runInAction(() => {
|
||||||
|
if ("sync" in data) {
|
||||||
|
target.sync.hydrate(legacyMigrateSync(data.sync!));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("locale" in data) {
|
||||||
|
target.locale.hydrate(legacyMigrateLocale(data.locale!));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("auth" in data) {
|
||||||
|
target.auth.hydrate(legacyMigrateAuth(data.auth!));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("settings" in data) {
|
||||||
|
if (data!.settings!.theme) {
|
||||||
|
target.settings.hydrate(
|
||||||
|
detroll(legacyMigrateTheme(data.settings!.theme!)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data!.settings!.appearance) {
|
||||||
|
target.settings.hydrate(
|
||||||
|
detroll(
|
||||||
|
legacyMigrateAppearance(data.settings!.appearance!),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("notifications" in data) {
|
||||||
|
target.notifications.hydrate(
|
||||||
|
legacyMigrateNotification(data.notifications!),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue