feat: add "ordering" data store

This commit is contained in:
Paul Makles
2022-05-27 21:18:12 +01:00
parent 588cb7c019
commit bdf741e0ee
6 changed files with 129 additions and 17 deletions

View File

@@ -35,6 +35,8 @@ export default observer(() => {
createServer={createServer}
permit={state.notifications}
home={state.layout.getLastHomePath}
servers={state.ordering.orderedServers}
reorder={state.ordering.reorderServer}
/>
);
});

View File

@@ -17,6 +17,7 @@ import Layout from "./stores/Layout";
import LocaleOptions from "./stores/LocaleOptions";
import MessageQueue from "./stores/MessageQueue";
import NotificationOptions from "./stores/NotificationOptions";
import Ordering from "./stores/Ordering";
import Plugins from "./stores/Plugins";
import ServerConfig from "./stores/ServerConfig";
import Settings from "./stores/Settings";
@@ -41,6 +42,7 @@ export default class State {
settings: Settings;
sync: Sync;
plugins: Plugins;
ordering: Ordering;
private persistent: [string, Persistent<unknown>][] = [];
private disabled: Set<string> = new Set();
@@ -62,6 +64,7 @@ export default class State {
this.settings = new Settings();
this.sync = new Sync(this);
this.plugins = new Plugins(this);
this.ordering = new Ordering(this);
makeAutoObservable(this, {
client: false,
@@ -280,6 +283,7 @@ export default class State {
this.queue = new MessageQueue();
this.settings = new Settings();
this.sync = new Sync(this);
this.ordering = new Ordering(this);
this.save();

View File

@@ -0,0 +1,93 @@
import { action, computed, makeAutoObservable } from "mobx";
import { reorder } from "@revoltchat/ui";
import State from "../State";
import Persistent from "../interfaces/Persistent";
import Store from "../interfaces/Store";
import Syncable from "../interfaces/Syncable";
export interface Data {
servers?: string[];
}
/**
* Keeps track of ordering of various elements
*/
export default class Ordering implements Store, Persistent<Data>, Syncable {
private state: State;
/**
* Ordered list of server IDs
*/
private servers: string[];
/**
* Construct new Layout store.
*/
constructor(state: State) {
this.servers = [];
makeAutoObservable(this);
this.state = state;
this.reorderServer = this.reorderServer.bind(this);
}
get id() {
return "ordering";
}
toJSON() {
return {
servers: this.servers,
};
}
@action hydrate(data: Data) {
if (data.servers) {
this.servers = data.servers;
}
}
apply(_key: string, data: unknown, _revision: number): void {
this.hydrate(data as Data);
}
toSyncable(): { [key: string]: object } {
return {
ordering: this.toJSON(),
};
}
/**
* All known servers with ordering applied
*/
@computed get orderedServers() {
const known = new Set(this.state.client?.servers.keys() ?? []);
const ordered = [...this.servers];
const out = [];
for (const id of ordered) {
if (known.delete(id)) {
out.push(this.state.client!.servers.get(id)!);
}
}
for (const id of known) {
out.push(this.state.client!.servers.get(id)!);
}
return out;
}
/**
* Re-order a server
*/
@action reorderServer(source: number, dest: number) {
this.servers = reorder(
this.orderedServers.map((x) => x._id),
source,
dest,
);
}
}

View File

@@ -14,13 +14,19 @@ import State from "../State";
import Persistent from "../interfaces/Persistent";
import Store from "../interfaces/Store";
export type SyncKeys = "theme" | "appearance" | "locale" | "notifications";
export type SyncKeys =
| "theme"
| "appearance"
| "locale"
| "notifications"
| "ordering";
export const SYNC_KEYS: SyncKeys[] = [
"theme",
"appearance",
"locale",
"notifications",
"ordering",
];
export interface Data {
@@ -151,6 +157,13 @@ export default class Sync implements Store, Persistent<Data> {
);
this.setRevision("notifications", notifications[0]);
}
const ordering = tryRead("ordering");
if (ordering) {
this.state.setDisabled("ordering");
this.state.ordering.apply("ordering", ordering[1], ordering[0]);
this.setRevision("ordering", ordering[0]);
}
});
}