From b0681dfc998c472c3c70f13c3c075099db56c569 Mon Sep 17 00:00:00 2001
From: Paul <paulmakles@gmail.com>
Date: Thu, 29 Jul 2021 21:01:03 +0100
Subject: [PATCH] Load member sidebar into MobX state.

---
 package.json                                  |  2 +-
 .../navigation/right/MemberSidebar.tsx        |  2 +-
 src/context/index.tsx                         | 26 +++++++++----------
 src/context/revoltjs/RevoltClient.tsx         |  7 +++--
 src/context/revoltjs/events.ts                |  6 ++---
 src/mobx/State.tsx                            | 17 ++++++++++--
 src/mobx/index.ts                             | 20 ++++++++++++--
 yarn.lock                                     |  8 +++---
 8 files changed, 57 insertions(+), 31 deletions(-)

diff --git a/package.json b/package.json
index 83f056b..4a1c441 100644
--- a/package.json
+++ b/package.json
@@ -96,7 +96,7 @@
     "react-router-dom": "^5.2.0",
     "react-scroll": "^1.8.2",
     "redux": "^4.1.0",
-    "revolt.js": "^4.3.3-alpha.19",
+    "revolt.js": "4.4.0-alpha.0",
     "rimraf": "^3.0.2",
     "sass": "^1.35.1",
     "shade-blend-color": "^1.0.0",
diff --git a/src/components/navigation/right/MemberSidebar.tsx b/src/components/navigation/right/MemberSidebar.tsx
index 8c2b813..838acd3 100644
--- a/src/components/navigation/right/MemberSidebar.tsx
+++ b/src/components/navigation/right/MemberSidebar.tsx
@@ -181,7 +181,7 @@ export const ServerMemberSidebar = observer(
                 status === ClientStatus.ONLINE &&
                 typeof members === "undefined"
             ) {
-                client.members
+                store
                     .fetchMembers(channel.server!)
                     .then((members) => setMembers(members));
             }
diff --git a/src/context/index.tsx b/src/context/index.tsx
index e3c757e..46966c0 100644
--- a/src/context/index.tsx
+++ b/src/context/index.tsx
@@ -1,8 +1,8 @@
 import { BrowserRouter as Router } from "react-router-dom";
 
+import MobXState from "../mobx/State";
 import State from "../redux/State";
 
-import MobXState from "../mobx/State";
 import { Children } from "../types/Preact";
 import Locale from "./Locale";
 import Settings from "./Settings";
@@ -15,19 +15,19 @@ export default function Context({ children }: { children: Children }) {
     return (
         <Router>
             <State>
-                <MobXState>
-                    <Theme>
-                        <Settings>
-                            <Locale>
-                                <Intermediate>
-                                    <Client>
+                <Theme>
+                    <Settings>
+                        <Locale>
+                            <Intermediate>
+                                <Client>
+                                    <MobXState>
                                         <Voice>{children}</Voice>
-                                    </Client>
-                                </Intermediate>
-                            </Locale>
-                        </Settings>
-                    </Theme>
-                </MobXState>
+                                    </MobXState>
+                                </Client>
+                            </Intermediate>
+                        </Locale>
+                    </Settings>
+                </Theme>
             </State>
         </Router>
     );
diff --git a/src/context/revoltjs/RevoltClient.tsx b/src/context/revoltjs/RevoltClient.tsx
index 27ed319..3a5ad2b 100644
--- a/src/context/revoltjs/RevoltClient.tsx
+++ b/src/context/revoltjs/RevoltClient.tsx
@@ -8,13 +8,13 @@ import { useContext, useEffect, useMemo, useState } from "preact/hooks";
 
 import { SingletonMessageRenderer } from "../../lib/renderer/Singleton";
 
+import { useData } from "../../mobx/State";
 import { dispatch } from "../../redux";
 import { connectState } from "../../redux/connector";
 import { AuthState } from "../../redux/reducers/auth";
 
 import Preloader from "../../components/ui/Preloader";
 
-import { useData } from "../../mobx/State";
 import { Children } from "../../types/Preact";
 import { useIntermediate } from "../intermediate/Intermediate";
 import { registerEvents, setReconnectDisallowed } from "./events";
@@ -158,10 +158,9 @@ function Context({ auth, children }: Props) {
         };
     }, [client, auth.active]);
 
-    const store = useData();
     useEffect(
-        () => registerEvents({ operations }, setStatus, client, store),
-        [client, store],
+        () => registerEvents({ operations }, setStatus, client),
+        [client],
     );
 
     useEffect(() => {
diff --git a/src/context/revoltjs/events.ts b/src/context/revoltjs/events.ts
index f660733..a84e07a 100644
--- a/src/context/revoltjs/events.ts
+++ b/src/context/revoltjs/events.ts
@@ -3,10 +3,10 @@ import { ClientboundNotification } from "revolt.js/dist/websocket/notifications"
 
 import { StateUpdater } from "preact/hooks";
 
-import { dispatch } from "../../redux";
-
 import { DataStore } from "../../mobx";
 import { useData } from "../../mobx/State";
+import { dispatch } from "../../redux";
+
 import { ClientOperations, ClientStatus } from "./RevoltClient";
 
 export var preventReconnect = false;
@@ -20,7 +20,6 @@ export function registerEvents(
     { operations }: { operations: ClientOperations },
     setStatus: StateUpdater<ClientStatus>,
     client: Client,
-    store: DataStore,
 ) {
     function attemptReconnect() {
         if (preventReconnect) return;
@@ -48,7 +47,6 @@ export function registerEvents(
         },
 
         packet: (packet: ClientboundNotification) => {
-            store.packet(packet);
             switch (packet.type) {
                 case "ChannelStartTyping": {
                     if (packet.user === client.user?._id) return;
diff --git a/src/mobx/State.tsx b/src/mobx/State.tsx
index cd3b149..8c491ed 100644
--- a/src/mobx/State.tsx
+++ b/src/mobx/State.tsx
@@ -1,5 +1,9 @@
+import { ClientboundNotification } from "revolt.js/dist/websocket/notifications";
+
 import { createContext } from "preact";
-import { useContext } from "preact/hooks";
+import { useContext, useEffect, useState } from "preact/hooks";
+
+import { useClient } from "../context/revoltjs/RevoltClient";
 
 import { DataStore } from ".";
 import { Children } from "../types/Preact";
@@ -13,9 +17,18 @@ export const DataContext = createContext<DataStore>(null!);
 // ! later we can do seamless account switching, by hooking this into Redux
 // ! and monitoring changes to active account and hence swapping stores.
 // although this may need more work since we need a Client per account too.
-const store = new DataStore();
 
 export default function StateLoader(props: Props) {
+    const client = useClient();
+    const [store] = useState(new DataStore(client));
+
+    useEffect(() => {
+        const packet = (packet: ClientboundNotification) =>
+            store.packet(packet);
+        client.addListener("packet", packet);
+        return () => client.removeListener("packet", packet);
+    }, [client]);
+
     return (
         <DataContext.Provider value={store}>
             {props.children}
diff --git a/src/mobx/index.ts b/src/mobx/index.ts
index 385bb81..4ea148b 100644
--- a/src/mobx/index.ts
+++ b/src/mobx/index.ts
@@ -9,6 +9,7 @@ import {
     action,
     extendObservable,
 } from "mobx";
+import { Client } from "revolt.js";
 import {
     Attachment,
     Channels,
@@ -307,13 +308,16 @@ export class Member {
 }
 
 export class DataStore {
+    client: Client;
+
     @observable users = new Map<string, User>();
     @observable channels = new Map<string, Channel>();
     @observable servers = new Map<string, Server>();
     @observable members = new Map<Servers.MemberCompositeKey, Member>();
 
-    constructor() {
-        makeAutoObservable(this);
+    constructor(client: Client) {
+        makeAutoObservable(this, undefined, { proxy: false });
+        this.client = client;
     }
 
     @action
@@ -389,4 +393,16 @@ export class DataStore {
             }
         }
     }
+
+    async fetchMembers(server: string) {
+        let res = await this.client.members.fetchMembers(server);
+
+        for (let user of res.users) {
+            if (!this.users.has(user._id)) {
+                this.users.set(user._id, new User(user));
+            }
+        }
+
+        return res.members;
+    }
 }
diff --git a/yarn.lock b/yarn.lock
index f943b7e..f6c86fe 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3573,10 +3573,10 @@ reusify@^1.0.4:
   resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
   integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
 
-revolt.js@^4.3.3-alpha.19:
-  version "4.3.3-alpha.19"
-  resolved "https://registry.yarnpkg.com/revolt.js/-/revolt.js-4.3.3-alpha.19.tgz#02b0fe8c44b6b803f5314a2d40eda5d3481901d3"
-  integrity sha512-cpJGqAnAzCV33zuFqiOlRopqhSMhSUZISB7vdsgvjS6Aof1UrWpJJO+POnVxo20FvLM0tMFZaHIxdYeW798U9w==
+revolt.js@4.4.0-alpha.0:
+  version "4.4.0-alpha.0"
+  resolved "https://registry.yarnpkg.com/revolt.js/-/revolt.js-4.4.0-alpha.0.tgz#6b8d7e5605c4e106800ebd7ddcda8215a8fb289b"
+  integrity sha512-TPb7FCC1xpAO0hJ19tXAC5ZwsceJ/yzkFlV/lESteVk4bboVINhRrsElYtJvjSKci7Ft70t0e4bbm8YSYjAblA==
   dependencies:
     "@insertish/mutable" "1.1.0"
     axios "^0.19.2"
-- 
GitLab