From 6b6279ffee0fa56447dfb388815361c244bb874b Mon Sep 17 00:00:00 2001
From: Paul <paulmakles@gmail.com>
Date: Sat, 31 Jul 2021 13:48:26 +0100
Subject: [PATCH] Move typing indicator into revolt.js

---
 package.json                                  |  2 +-
 .../common/messaging/bars/TypingIndicator.tsx | 29 +++++------
 src/components/navigation/left/common.ts      |  5 +-
 src/context/revoltjs/StateMonitor.tsx         | 27 -----------
 src/context/revoltjs/events.ts                | 18 -------
 src/pages/channels/Channel.tsx                |  2 +-
 src/redux/index.ts                            |  2 -
 src/redux/reducers/index.ts                   |  3 --
 src/redux/reducers/typing.ts                  | 48 -------------------
 yarn.lock                                     |  8 ++--
 10 files changed, 18 insertions(+), 126 deletions(-)
 delete mode 100644 src/redux/reducers/typing.ts

diff --git a/package.json b/package.json
index 400a600..00831bf 100644
--- a/package.json
+++ b/package.json
@@ -97,7 +97,7 @@
     "react-router-dom": "^5.2.0",
     "react-scroll": "^1.8.2",
     "redux": "^4.1.0",
-    "revolt.js": "5.0.0-alpha.14",
+    "revolt.js": "5.0.0-alpha.16-patch.0",
     "rimraf": "^3.0.2",
     "sass": "^1.35.1",
     "shade-blend-color": "^1.0.0",
diff --git a/src/components/common/messaging/bars/TypingIndicator.tsx b/src/components/common/messaging/bars/TypingIndicator.tsx
index 3704e79..b35ce14 100644
--- a/src/components/common/messaging/bars/TypingIndicator.tsx
+++ b/src/components/common/messaging/bars/TypingIndicator.tsx
@@ -1,15 +1,15 @@
 import { observer } from "mobx-react-lite";
+import { Channel } from "revolt.js/dist/maps/Channels";
 import styled from "styled-components";
 
 import { Text } from "preact-i18n";
 
 import { connectState } from "../../../../redux/connector";
-import { TypingUser } from "../../../../redux/reducers/typing";
 
 import { useClient } from "../../../../context/revoltjs/RevoltClient";
 
 interface Props {
-    typing?: TypingUser[];
+    channel: Channel;
 }
 
 const Base = styled.div`
@@ -55,22 +55,21 @@ const Base = styled.div`
     }
 `;
 
-export const TypingIndicator = observer(({ typing }: Props) => {
-    if (typing && typing.length > 0) {
-        const client = useClient();
-        const users = typing
-            .map((x) => client.users.get(x.id)!)
-            .filter((x) => typeof x !== "undefined");
+export default observer(({ channel }: Props) => {
+    const users = channel.typing.filter(
+        (x) => typeof x !== "undefined" && x._id !== x.client.user!._id,
+    );
 
+    if (users.length > 0) {
         users.sort((a, b) =>
-            a._id.toUpperCase().localeCompare(b._id.toUpperCase()),
+            a!._id.toUpperCase().localeCompare(b!._id.toUpperCase()),
         );
 
         let text;
         if (users.length >= 5) {
             text = <Text id="app.main.channel.typing.several" />;
         } else if (users.length > 1) {
-            const userlist = [...users].map((x) => x.username);
+            const userlist = [...users].map((x) => x!.username);
             const user = userlist.pop();
 
             /*for (let i = 0; i < userlist.length - 1; i++) {
@@ -90,7 +89,7 @@ export const TypingIndicator = observer(({ typing }: Props) => {
             text = (
                 <Text
                     id="app.main.channel.typing.single"
-                    fields={{ user: users[0].username }}
+                    fields={{ user: users[0]!.username }}
                 />
             );
         }
@@ -102,7 +101,7 @@ export const TypingIndicator = observer(({ typing }: Props) => {
                         {users.map((user) => (
                             <img
                                 loading="eager"
-                                src={user.generateAvatarURL({ max_side: 256 })}
+                                src={user!.generateAvatarURL({ max_side: 256 })}
                             />
                         ))}
                     </div>
@@ -114,9 +113,3 @@ export const TypingIndicator = observer(({ typing }: Props) => {
 
     return null;
 });
-
-export default connectState<{ id: string }>(TypingIndicator, (state, props) => {
-    return {
-        typing: state.typing && state.typing[props.id],
-    };
-});
diff --git a/src/components/navigation/left/common.ts b/src/components/navigation/left/common.ts
index 1416b63..a19d1c3 100644
--- a/src/components/navigation/left/common.ts
+++ b/src/components/navigation/left/common.ts
@@ -39,10 +39,7 @@ export function useUnreads({ channel, unreads }: UnreadProps) {
                         message,
                     });
 
-                    client.req(
-                        "PUT",
-                        `/channels/${channel._id}/ack/${message}` as "/channels/id/ack/id",
-                    );
+                    channel.ack(message);
                 }
             }
         }
diff --git a/src/context/revoltjs/StateMonitor.tsx b/src/context/revoltjs/StateMonitor.tsx
index bc235fc..9784bed 100644
--- a/src/context/revoltjs/StateMonitor.tsx
+++ b/src/context/revoltjs/StateMonitor.tsx
@@ -8,13 +8,11 @@ import { useContext, useEffect } from "preact/hooks";
 import { dispatch } from "../../redux";
 import { connectState } from "../../redux/connector";
 import { QueuedMessage } from "../../redux/reducers/queue";
-import { Typing } from "../../redux/reducers/typing";
 
 import { AppContext } from "./RevoltClient";
 
 type Props = {
     messages: QueuedMessage[];
-    typing: Typing;
 };
 
 function StateMonitor(props: Props) {
@@ -41,36 +39,11 @@ function StateMonitor(props: Props) {
         return () => client.removeListener("message", add);
     }, [props.messages]);
 
-    useEffect(() => {
-        function removeOld() {
-            if (!props.typing) return;
-            for (const channel of Object.keys(props.typing)) {
-                const users = props.typing[channel];
-
-                for (const user of users) {
-                    if (+new Date() > user.started + 5000) {
-                        dispatch({
-                            type: "TYPING_STOP",
-                            channel,
-                            user: user.id,
-                        });
-                    }
-                }
-            }
-        }
-
-        removeOld();
-
-        const interval = setInterval(removeOld, 1000);
-        return () => clearInterval(interval);
-    }, [props.typing]);
-
     return null;
 }
 
 export default connectState(StateMonitor, (state) => {
     return {
         messages: [...state.queue],
-        typing: state.typing,
     };
 });
diff --git a/src/context/revoltjs/events.ts b/src/context/revoltjs/events.ts
index 1fe2907..ee06a8d 100644
--- a/src/context/revoltjs/events.ts
+++ b/src/context/revoltjs/events.ts
@@ -47,24 +47,6 @@ export function registerEvents(
 
         packet: (packet: ClientboundNotification) => {
             switch (packet.type) {
-                case "ChannelStartTyping": {
-                    if (packet.user === client.user?._id) return;
-                    dispatch({
-                        type: "TYPING_START",
-                        channel: packet.id,
-                        user: packet.user,
-                    });
-                    break;
-                }
-                case "ChannelStopTyping": {
-                    if (packet.user === client.user?._id) return;
-                    dispatch({
-                        type: "TYPING_STOP",
-                        channel: packet.id,
-                        user: packet.user,
-                    });
-                    break;
-                }
                 case "ChannelAck": {
                     dispatch({
                         type: "UNREADS_MARK_READ",
diff --git a/src/pages/channels/Channel.tsx b/src/pages/channels/Channel.tsx
index b9846d0..411e1f1 100644
--- a/src/pages/channels/Channel.tsx
+++ b/src/pages/channels/Channel.tsx
@@ -89,7 +89,7 @@ const TextChannel = observer(({ channel }: { channel: ChannelI }) => {
                 <ChannelContent>
                     <VoiceHeader id={id} />
                     <MessageArea id={id} />
-                    <TypingIndicator id={id} />
+                    <TypingIndicator channel={channel} />
                     <JumpToBottom id={id} />
                     <MessageBox channel={channel} />
                 </ChannelContent>
diff --git a/src/redux/index.ts b/src/redux/index.ts
index 99c16c0..cab197f 100644
--- a/src/redux/index.ts
+++ b/src/redux/index.ts
@@ -14,7 +14,6 @@ import { QueuedMessage } from "./reducers/queue";
 import { SectionToggle } from "./reducers/section_toggle";
 import { Settings } from "./reducers/settings";
 import { SyncOptions } from "./reducers/sync";
-import { Typing } from "./reducers/typing";
 import { Unreads } from "./reducers/unreads";
 
 export type State = {
@@ -24,7 +23,6 @@ export type State = {
     settings: Settings;
     unreads: Unreads;
     queue: QueuedMessage[];
-    typing: Typing;
     drafts: Drafts;
     sync: SyncOptions;
     experiments: ExperimentOptions;
diff --git a/src/redux/reducers/index.ts b/src/redux/reducers/index.ts
index 979d36e..e2b29cd 100644
--- a/src/redux/reducers/index.ts
+++ b/src/redux/reducers/index.ts
@@ -12,7 +12,6 @@ import { sectionToggle, SectionToggleAction } from "./section_toggle";
 import { config, ConfigAction } from "./server_config";
 import { settings, SettingsAction } from "./settings";
 import { sync, SyncAction } from "./sync";
-import { typing, TypingAction } from "./typing";
 import { unreads, UnreadsAction } from "./unreads";
 
 export default combineReducers({
@@ -22,7 +21,6 @@ export default combineReducers({
     settings,
     unreads,
     queue,
-    typing,
     drafts,
     sync,
     experiments,
@@ -38,7 +36,6 @@ export type Action =
     | SettingsAction
     | UnreadsAction
     | QueueAction
-    | TypingAction
     | DraftAction
     | SyncAction
     | ExperimentsAction
diff --git a/src/redux/reducers/typing.ts b/src/redux/reducers/typing.ts
deleted file mode 100644
index 41a08e2..0000000
--- a/src/redux/reducers/typing.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-export type TypingUser = { id: string; started: number };
-export type Typing = { [key: string]: TypingUser[] };
-
-export type TypingAction =
-    | { type: undefined }
-    | {
-          type: "TYPING_START";
-          channel: string;
-          user: string;
-      }
-    | {
-          type: "TYPING_STOP";
-          channel: string;
-          user: string;
-      }
-    | {
-          type: "RESET";
-      };
-
-export function typing(state: Typing = {}, action: TypingAction): Typing {
-    switch (action.type) {
-        case "TYPING_START":
-            return {
-                ...state,
-                [action.channel]: [
-                    ...(state[action.channel] ?? []).filter(
-                        (x) => x.id !== action.user,
-                    ),
-                    {
-                        id: action.user,
-                        started: +new Date(),
-                    },
-                ],
-            };
-        case "TYPING_STOP":
-            return {
-                ...state,
-                [action.channel]:
-                    state[action.channel]?.filter(
-                        (x) => x.id !== action.user,
-                    ) ?? [],
-            };
-        case "RESET":
-            return {};
-        default:
-            return state;
-    }
-}
diff --git a/yarn.lock b/yarn.lock
index b3d7704..cd740ba 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3570,10 +3570,10 @@ revolt-api@0.5.1-alpha.10-patch.0:
   resolved "https://registry.yarnpkg.com/revolt-api/-/revolt-api-0.5.1-alpha.10-patch.0.tgz#97d31bec7dfa4573567097443acb059c4feaac20"
   integrity sha512-UyM890HkGlYNQOxpHuEpUsJHLt8Ujnjg9/zPEDGpbvS4iy0jmHX23Hh8tOCfb/ewxbNrtT3G1HpSWKOneW/vYg==
 
-revolt.js@5.0.0-alpha.14:
-  version "5.0.0-alpha.14"
-  resolved "https://registry.yarnpkg.com/revolt.js/-/revolt.js-5.0.0-alpha.14.tgz#13b1d350a89467eb2ad6905a290ee1fada4150c1"
-  integrity sha512-kZBIx9PX8Y8Esu51Y6OgeFwlpajtaRv/ap3YKlWEELlAcDAEDoSZj+iL4ilkxIxvh4RDJMlVlAforwSvXvy9DQ==
+revolt.js@5.0.0-alpha.16-patch.0:
+  version "5.0.0-alpha.16-patch.0"
+  resolved "https://registry.yarnpkg.com/revolt.js/-/revolt.js-5.0.0-alpha.16-patch.0.tgz#a46aaf037cb43c8760f4c282574cbc6d54baa59c"
+  integrity sha512-DFDH5KjTUCvbsdHRluS7YbQHrtyRyAnlY5uE4ZC0uVBjEaGWAH7kdIVi8ztzVQE45obpXprmXz//r/1UgsBtUA==
   dependencies:
     axios "^0.19.2"
     eventemitter3 "^4.0.7"
-- 
GitLab