From 2ee3da28b95a5ba84a9c7efd71921a93b147c824 Mon Sep 17 00:00:00 2001
From: Paul <paulmakles@gmail.com>
Date: Fri, 9 Jul 2021 14:34:36 +0100
Subject: [PATCH] Experiment: New search function.

---
 package.json                                  |  2 +-
 .../navigation/right/MemberSidebar.tsx        | 51 ++++++++++++++++++-
 src/redux/reducers/experiments.ts             |  4 +-
 yarn.lock                                     |  8 +--
 4 files changed, 57 insertions(+), 8 deletions(-)

diff --git a/package.json b/package.json
index becf247..767f300 100644
--- a/package.json
+++ b/package.json
@@ -94,7 +94,7 @@
     "react-router-dom": "^5.2.0",
     "react-scroll": "^1.8.2",
     "redux": "^4.1.0",
-    "revolt.js": "4.3.3-alpha.11",
+    "revolt.js": "4.3.3-alpha.14",
     "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 c83e1c3..8e8ebe8 100644
--- a/src/components/navigation/right/MemberSidebar.tsx
+++ b/src/components/navigation/right/MemberSidebar.tsx
@@ -1,8 +1,9 @@
 import { useParams } from "react-router";
 import { User } from "revolt.js";
-import { Channels, Servers, Users } from "revolt.js/dist/api/objects";
+import { Channels, Message, Servers, Users } from "revolt.js/dist/api/objects";
 import { ClientboundNotification } from "revolt.js/dist/websocket/notifications";
 
+import { Link } from "react-router-dom";
 import { Text } from "preact-i18n";
 import { useContext, useEffect, useState } from "preact/hooks";
 
@@ -27,6 +28,8 @@ import placeholderSVG from "../items/placeholder.svg";
 import { GenericSidebarBase, GenericSidebarList } from "../SidebarBase";
 import { UserButton } from "../items/ButtonItem";
 import { ChannelDebugInfo } from "./ChannelDebugInfo";
+import InputBox from "../../ui/InputBox";
+import { getState } from "../../../redux";
 
 interface Props {
     ctx: HookContext;
@@ -97,6 +100,8 @@ export function GroupMemberSidebar({
         <GenericSidebarBase>
             <GenericSidebarList>
                 <ChannelDebugInfo id={channel._id} />
+                <Search channel={channel._id} />
+
                 {/*voiceActive && voiceParticipants.length !== 0 && (
                     <Fragment>
                         <Category
@@ -237,6 +242,7 @@ export function ServerMemberSidebar({
         <GenericSidebarBase>
             <GenericSidebarList>
                 <ChannelDebugInfo id={channel._id} />
+                <Search channel={channel._id} />
                 <div>{!members && <Preloader type="ring" />}</div>
                 {members && (
                     <CollapsibleSection
@@ -273,3 +279,46 @@ export function ServerMemberSidebar({
         </GenericSidebarBase>
     );
 }
+
+function Search({ channel }: { channel: string }) {
+    if (!getState().experiments.enabled?.includes('search')) return null;
+
+    const client = useContext(AppContext);
+    const [query,setV] = useState('');
+    const [results,setResults] = useState<Message[]>([]);
+
+    async function search() {
+        let data = await client.channels.searchWithUsers(channel, { query, sort: 'Relevance' }, true);
+        setResults(data.messages);
+    }
+
+    return (
+        <CollapsibleSection
+            sticky
+            id="search"
+            defaultValue={false}
+            summary={"Search (BETA)"}>
+            <InputBox style={{ width: '100%' }}
+                onKeyDown={e => e.key === 'Enter' && search()}
+                value={query} onChange={e => setV(e.currentTarget.value)} />
+            <div style={{ display: 'flex', flexDirection: 'column', gap: '4px', marginTop: '8px' }}>
+            {
+                results.map(message => {
+                    let href = '';
+                    let channel = client.channels.get(message.channel);
+                    if (channel?.channel_type === 'TextChannel') {
+                        href += `/server/${channel.server}`;
+                    }
+
+                    href += `/channel/${message.channel}/${message._id}`;
+
+                    return <Link to={href}><div style={{ margin: '2px', padding: '6px', background: 'var(--primary-background)' }}>
+                        <b>@{ client.users.get(message.author)?.username }</b><br/>
+                        { message.content }
+                    </div></Link>
+                })
+            }
+            </div>
+        </CollapsibleSection>
+    )
+}
diff --git a/src/redux/reducers/experiments.ts b/src/redux/reducers/experiments.ts
index 66d095b..3ccc847 100644
--- a/src/redux/reducers/experiments.ts
+++ b/src/redux/reducers/experiments.ts
@@ -1,5 +1,5 @@
-export type Experiments = never;
-export const AVAILABLE_EXPERIMENTS: Experiments[] = [];
+export type Experiments = 'search';
+export const AVAILABLE_EXPERIMENTS: Experiments[] = [ 'search' ];
 
 export interface ExperimentOptions {
     enabled?: Experiments[];
diff --git a/yarn.lock b/yarn.lock
index 870786d..2926089 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3563,10 +3563,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.11:
-  version "4.3.3-alpha.11"
-  resolved "https://registry.yarnpkg.com/revolt.js/-/revolt.js-4.3.3-alpha.11.tgz#d8499607cc3de48ab580c7da9bf2e8e0a1992ae9"
-  integrity sha512-//UB+VXKE4MziUoBm2RMDZNgxLmrar8FQ1hCewkdFbTdfkYey6joagNVF5DW+ImbffYbrnnjZhlJP7RRXZ5IeQ==
+revolt.js@4.3.3-alpha.14:
+  version "4.3.3-alpha.14"
+  resolved "https://registry.yarnpkg.com/revolt.js/-/revolt.js-4.3.3-alpha.14.tgz#f4912ee25725de6e43ba1d4fd8ab84c711678271"
+  integrity sha512-4p3DhEu+GUKZxczCPXR2JM04fzGlFfZdwHYjgkgU48NgPXgzxQrSv4x0FjpyIIv3xNpuO59z35mYRMLxAnBXsQ==
   dependencies:
     "@insertish/mutable" "1.1.0"
     axios "^0.19.2"
-- 
GitLab