feat: add "ordering" data store

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

View file

@ -90,13 +90,13 @@
"@hcaptcha/react-hcaptcha": "^0.3.6", "@hcaptcha/react-hcaptcha": "^0.3.6",
"@insertish/vite-plugin-babel-macros": "^1.0.5", "@insertish/vite-plugin-babel-macros": "^1.0.5",
"@preact/preset-vite": "^2.0.0", "@preact/preset-vite": "^2.0.0",
"@revoltchat/ui": "^1.0.32", "@revoltchat/ui": "1.0.33",
"@rollup/plugin-replace": "^2.4.2", "@rollup/plugin-replace": "^2.4.2",
"@styled-icons/boxicons-logos": "^10.38.0", "@styled-icons/boxicons-logos": "^10.38.0",
"@styled-icons/boxicons-regular": "^10.38.0", "@styled-icons/boxicons-regular": "^10.38.0",
"@styled-icons/boxicons-solid": "^10.38.0", "@styled-icons/boxicons-solid": "^10.38.0",
"@styled-icons/simple-icons": "^10.33.0", "@styled-icons/simple-icons": "^10.33.0",
"@tippyjs/react": "npm:4.2.5", "@tippyjs/react": "4.2.6",
"@traptitech/markdown-it-katex": "^3.4.3", "@traptitech/markdown-it-katex": "^3.4.3",
"@traptitech/markdown-it-spoiler": "^1.1.6", "@traptitech/markdown-it-spoiler": "^1.1.6",
"@trivago/prettier-plugin-sort-imports": "^2.0.2", "@trivago/prettier-plugin-sort-imports": "^2.0.2",
@ -138,14 +138,14 @@
"prettier": "^2.3.1", "prettier": "^2.3.1",
"prismjs": "^1.23.0", "prismjs": "^1.23.0",
"react-beautiful-dnd": "^13.1.0", "react-beautiful-dnd": "^13.1.0",
"react-device-detect": "npm:2.2.2", "react-device-detect": "2.2.2",
"react-helmet": "^6.1.0", "react-helmet": "^6.1.0",
"react-hook-form": "6.3.0", "react-hook-form": "6.3.0",
"react-overlapping-panels": "1.2.2", "react-overlapping-panels": "1.2.2",
"react-router-dom": "^5.2.0", "react-router-dom": "^5.2.0",
"react-scroll": "^1.8.2", "react-scroll": "^1.8.2",
"react-virtuoso": "^2.12.0", "react-virtuoso": "^2.12.0",
"revolt.js": "npm:6.0.1", "revolt.js": "6.0.1",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"sass": "^1.35.1", "sass": "^1.35.1",
"shade-blend-color": "^1.0.0", "shade-blend-color": "^1.0.0",

View file

@ -35,6 +35,8 @@ export default observer(() => {
createServer={createServer} createServer={createServer}
permit={state.notifications} permit={state.notifications}
home={state.layout.getLastHomePath} 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 LocaleOptions from "./stores/LocaleOptions";
import MessageQueue from "./stores/MessageQueue"; import MessageQueue from "./stores/MessageQueue";
import NotificationOptions from "./stores/NotificationOptions"; import NotificationOptions from "./stores/NotificationOptions";
import Ordering from "./stores/Ordering";
import Plugins from "./stores/Plugins"; import Plugins from "./stores/Plugins";
import ServerConfig from "./stores/ServerConfig"; import ServerConfig from "./stores/ServerConfig";
import Settings from "./stores/Settings"; import Settings from "./stores/Settings";
@ -41,6 +42,7 @@ export default class State {
settings: Settings; settings: Settings;
sync: Sync; sync: Sync;
plugins: Plugins; plugins: Plugins;
ordering: Ordering;
private persistent: [string, Persistent<unknown>][] = []; private persistent: [string, Persistent<unknown>][] = [];
private disabled: Set<string> = new Set(); private disabled: Set<string> = new Set();
@ -62,6 +64,7 @@ export default class State {
this.settings = new Settings(); this.settings = new Settings();
this.sync = new Sync(this); this.sync = new Sync(this);
this.plugins = new Plugins(this); this.plugins = new Plugins(this);
this.ordering = new Ordering(this);
makeAutoObservable(this, { makeAutoObservable(this, {
client: false, client: false,
@ -280,6 +283,7 @@ export default class State {
this.queue = new MessageQueue(); this.queue = new MessageQueue();
this.settings = new Settings(); this.settings = new Settings();
this.sync = new Sync(this); this.sync = new Sync(this);
this.ordering = new Ordering(this);
this.save(); 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 Persistent from "../interfaces/Persistent";
import Store from "../interfaces/Store"; 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[] = [ export const SYNC_KEYS: SyncKeys[] = [
"theme", "theme",
"appearance", "appearance",
"locale", "locale",
"notifications", "notifications",
"ordering",
]; ];
export interface Data { export interface Data {
@ -151,6 +157,13 @@ export default class Sync implements Store, Persistent<Data> {
); );
this.setRevision("notifications", notifications[0]); 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]);
}
}); });
} }

View file

@ -2220,9 +2220,9 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@revoltchat/ui@npm:^1.0.32": "@revoltchat/ui@npm:1.0.33":
version: 1.0.32 version: 1.0.33
resolution: "@revoltchat/ui@npm:1.0.32" resolution: "@revoltchat/ui@npm:1.0.33"
dependencies: dependencies:
"@styled-icons/boxicons-logos": ^10.38.0 "@styled-icons/boxicons-logos": ^10.38.0
"@styled-icons/boxicons-regular": ^10.38.0 "@styled-icons/boxicons-regular": ^10.38.0
@ -2235,7 +2235,7 @@ __metadata:
react-device-detect: "*" react-device-detect: "*"
react-virtuoso: "*" react-virtuoso: "*"
revolt.js: "*" revolt.js: "*"
checksum: 7004add041a66932a7efc836f33648e905bd9820dd1d65890bccc93bc95cbc643ccede67dc570341fcc9c9993fffb57702dbd6ed41dac014553be18400bc313e checksum: 503fbf8557d205be153343776b8803335b6444b8767e0b1fccf6a34470e4cb333118f7cb614bf16e20d22cb811e7e1160622b9557b73414ad554f8b4bbfb565b
languageName: node languageName: node
linkType: hard linkType: hard
@ -2384,15 +2384,15 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@tippyjs/react@npm:4.2.5": "@tippyjs/react@npm:4.2.6":
version: 4.2.5 version: 4.2.6
resolution: "@tippyjs/react@npm:4.2.5" resolution: "@tippyjs/react@npm:4.2.6"
dependencies: dependencies:
tippy.js: ^6.3.1 tippy.js: ^6.3.1
peerDependencies: peerDependencies:
react: ">=16.8" react: ">=16.8"
react-dom: ">=16.8" react-dom: ">=16.8"
checksum: 68a6bb8922597df105f601953f14c593a8179328026dc425db0cd5d8521cdd8ad8c6ec7b6d0707708c8ed25e5ad01c488e95a6b3de0b2f404bd71137e2b8fce9 checksum: 8f0fba591c9dae2e1af1ae632bbc775ba5c9dd4498e50e242be70302b4c27115c6740eec44e885e294b27cb28515777b52af5b34aac9d4bab627d948add938ae
languageName: node languageName: node
linkType: hard linkType: hard
@ -3521,13 +3521,13 @@ __metadata:
"@hcaptcha/react-hcaptcha": ^0.3.6 "@hcaptcha/react-hcaptcha": ^0.3.6
"@insertish/vite-plugin-babel-macros": ^1.0.5 "@insertish/vite-plugin-babel-macros": ^1.0.5
"@preact/preset-vite": ^2.0.0 "@preact/preset-vite": ^2.0.0
"@revoltchat/ui": ^1.0.32 "@revoltchat/ui": 1.0.33
"@rollup/plugin-replace": ^2.4.2 "@rollup/plugin-replace": ^2.4.2
"@styled-icons/boxicons-logos": ^10.38.0 "@styled-icons/boxicons-logos": ^10.38.0
"@styled-icons/boxicons-regular": ^10.38.0 "@styled-icons/boxicons-regular": ^10.38.0
"@styled-icons/boxicons-solid": ^10.38.0 "@styled-icons/boxicons-solid": ^10.38.0
"@styled-icons/simple-icons": ^10.33.0 "@styled-icons/simple-icons": ^10.33.0
"@tippyjs/react": "npm:4.2.5" "@tippyjs/react": 4.2.6
"@traptitech/markdown-it-katex": ^3.4.3 "@traptitech/markdown-it-katex": ^3.4.3
"@traptitech/markdown-it-spoiler": ^1.1.6 "@traptitech/markdown-it-spoiler": ^1.1.6
"@trivago/prettier-plugin-sort-imports": ^2.0.2 "@trivago/prettier-plugin-sort-imports": ^2.0.2
@ -3571,14 +3571,14 @@ __metadata:
prettier: ^2.3.1 prettier: ^2.3.1
prismjs: ^1.23.0 prismjs: ^1.23.0
react-beautiful-dnd: ^13.1.0 react-beautiful-dnd: ^13.1.0
react-device-detect: "npm:2.2.2" react-device-detect: 2.2.2
react-helmet: ^6.1.0 react-helmet: ^6.1.0
react-hook-form: 6.3.0 react-hook-form: 6.3.0
react-overlapping-panels: 1.2.2 react-overlapping-panels: 1.2.2
react-router-dom: ^5.2.0 react-router-dom: ^5.2.0
react-scroll: ^1.8.2 react-scroll: ^1.8.2
react-virtuoso: ^2.12.0 react-virtuoso: ^2.12.0
revolt.js: "npm:6.0.1" revolt.js: 6.0.1
rimraf: ^3.0.2 rimraf: ^3.0.2
sass: ^1.35.1 sass: ^1.35.1
shade-blend-color: ^1.0.0 shade-blend-color: ^1.0.0