mirror of
https://github.com/revoltchat/revite.git
synced 2024-11-25 08:30:58 -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 { Client } from "revolt.js";
|
||||
|
||||
import { legacyMigrateForwards, LegacyState } from "./legacy/redux";
|
||||
|
||||
import Persistent from "./interfaces/Persistent";
|
||||
import Syncable from "./interfaces/Syncable";
|
||||
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) {
|
||||
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.
|
||||
* @returns Function to dispose of listeners
|
||||
|
@ -177,6 +192,20 @@ export default class State {
|
|||
* Load data stores from local storage.
|
||||
*/
|
||||
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;
|
||||
if (sync) {
|
||||
const { revision } = sync;
|
||||
|
@ -205,15 +234,3 @@ export async function hydrateState() {
|
|||
export function useApplicationState() {
|
||||
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 { 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 DataLocaleOptions } from "../stores/LocaleOptions";
|
||||
import { Data as DataNotificationOptions } from "../stores/NotificationOptions";
|
||||
|
@ -62,6 +69,11 @@ export interface LegacyAuthState {
|
|||
active?: string;
|
||||
}
|
||||
|
||||
export interface LegacySettings {
|
||||
theme?: LegacyThemeOptions;
|
||||
appearance?: LegacyAppearanceOptions;
|
||||
}
|
||||
|
||||
export function legacyMigrateAuth(auth: LegacyAuthState): DataAuth {
|
||||
return {
|
||||
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(
|
||||
channel: LegacyNotifications,
|
||||
): 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