diff --git a/src/components/common/messaging/Message.tsx b/src/components/common/messaging/Message.tsx
index e3540bcd..e17cc8b0 100644
--- a/src/components/common/messaging/Message.tsx
+++ b/src/components/common/messaging/Message.tsx
@@ -33,6 +33,7 @@ interface Props {
contrast?: boolean;
content?: Children;
head?: boolean;
+ hideReply?: boolean;
}
const Message = observer(
@@ -44,6 +45,7 @@ const Message = observer(
content: replacement,
head: preferHead,
queued,
+ hideReply,
}: Props) => {
const client = useClient();
const user = message.author;
@@ -72,23 +74,26 @@ const Message = observer(
return (
- {message.reply_ids?.map((message_id, index) => (
-
- ))}
+ {!hideReply &&
+ message.reply_ids?.map((message_id, index) => (
+
+ ))}
0
- )) ??
- false
+ hideReply
+ ? false
+ : (head &&
+ !(
+ message.reply_ids &&
+ message.reply_ids.length > 0
+ )) ??
+ false
}
contrast={contrast}
sending={typeof queued !== "undefined"}
diff --git a/src/components/navigation/RightSidebar.tsx b/src/components/navigation/RightSidebar.tsx
index edfac4db..46d938d6 100644
--- a/src/components/navigation/RightSidebar.tsx
+++ b/src/components/navigation/RightSidebar.tsx
@@ -1,9 +1,31 @@
import { Route, Switch } from "react-router";
+import { useEffect, useState } from "preact/hooks";
+
+import { internalSubscribe } from "../../lib/eventEmitter";
+
import SidebarBase from "./SidebarBase";
import MemberSidebar from "./right/MemberSidebar";
+import { SearchSidebar } from "./right/Search";
export default function RightSidebar() {
+ const [sidebar, setSidebar] = useState<"search" | undefined>();
+ const close = () => setSidebar(undefined);
+
+ useEffect(
+ () =>
+ internalSubscribe(
+ "RightSidebar",
+ "open",
+ setSidebar as (...args: unknown[]) => void,
+ ),
+ [setSidebar],
+ );
+
+ if (sidebar === "search") {
+ return ;
+ }
+
return (
diff --git a/src/components/navigation/right/MemberSidebar.tsx b/src/components/navigation/right/MemberSidebar.tsx
index 37cc085a..4e8bb83e 100644
--- a/src/components/navigation/right/MemberSidebar.tsx
+++ b/src/components/navigation/right/MemberSidebar.tsx
@@ -16,10 +16,10 @@ import {
import { GenericSidebarBase } from "../SidebarBase";
import MemberList, { MemberListGroup } from "./MemberList";
-export default function MemberSidebar({ channel: obj }: { channel?: Channel }) {
- const { channel: channel_id } = useParams<{ channel: string }>();
- const client = useClient();
- const channel = obj ?? client.channels.get(channel_id);
+export default function MemberSidebar() {
+ const channel = useClient().channels.get(
+ useParams<{ channel: string }>().channel,
+ );
switch (channel?.channel_type) {
case "Group":
diff --git a/src/components/navigation/right/Search.note b/src/components/navigation/right/Search.note
deleted file mode 100644
index 0e467399..00000000
--- a/src/components/navigation/right/Search.note
+++ /dev/null
@@ -1,80 +0,0 @@
-// this is the search code
-
-function Search({ channel }: { channel: Channel }) {
- if (!getState().experiments.enabled?.includes("search")) return null;
-
- type Sort = "Relevance" | "Latest" | "Oldest";
- const [sort, setSort] = useState("Relevance");
-
- const [query, setV] = useState("");
- const [results, setResults] = useState([]);
-
- async function search() {
- const data = await channel.searchWithUsers({ query, sort });
- setResults(data.messages);
- }
-
- return (
-
- (BETA)
- >
- }>
-
- {["Relevance", "Latest", "Oldest"].map((key) => (
-
- ))}
-
- e.key === "Enter" && search()}
- value={query}
- onChange={(e) => setV(e.currentTarget.value)}
- />
-
- {results.map((message) => {
- let href = "";
- if (channel?.channel_type === "TextChannel") {
- href += `/server/${channel.server_id}`;
- }
-
- href += `/channel/${message.channel_id}/${message._id}`;
-
- return (
-
-
- @{message.author?.username}
-
- {message.content}
-
-
- );
- })}
-
-
- );
-}
diff --git a/src/components/navigation/right/Search.tsx b/src/components/navigation/right/Search.tsx
index f8023f16..388f424c 100644
--- a/src/components/navigation/right/Search.tsx
+++ b/src/components/navigation/right/Search.tsx
@@ -1,12 +1,154 @@
-/*export const SearchSidebar = observer(
- ({ channel }: { channel: Channel }) => {
- const keys = [...channel.recipient_ids!];
- const entries = useEntries(channel, keys);
+import { Link, useParams } from "react-router-dom";
+import { Message as MessageI } from "revolt.js/dist/maps/Messages";
+import styled from "styled-components";
- return (
-
-
-
- );
- },
-);*/
+import { Text } from "preact-i18n";
+import { useEffect, useState } from "preact/hooks";
+
+import { useClient } from "../../../context/revoltjs/RevoltClient";
+
+import Message from "../../common/messaging/Message";
+import Button from "../../ui/Button";
+import InputBox from "../../ui/InputBox";
+import Overline from "../../ui/Overline";
+import Preloader from "../../ui/Preloader";
+
+import { GenericSidebarBase } from "../SidebarBase";
+
+type SearchState =
+ | {
+ type: "waiting";
+ }
+ | {
+ type: "loading";
+ }
+ | {
+ type: "results";
+ results: MessageI[];
+ };
+
+const SearchBase = styled.div`
+ padding: 6px;
+
+ input {
+ width: 100%;
+ }
+
+ .list {
+ gap: 4px;
+ margin: 8px 0;
+ display: flex;
+ flex-direction: column;
+ }
+
+ .message {
+ margin: 2px;
+ padding: 6px;
+ overflow: hidden;
+ border-radius: var(--border-radius);
+ background: var(--primary-background);
+
+ &:hover {
+ background: var(--hover);
+ }
+
+ > * {
+ pointer-events: none;
+ }
+ }
+
+ .sort {
+ gap: 4px;
+ margin: 6px 0;
+ display: flex;
+
+ > * {
+ flex: 1;
+ min-width: 0;
+ }
+ }
+`;
+
+interface Props {
+ close: () => void;
+}
+
+export function SearchSidebar({ close }: Props) {
+ const channel = useClient().channels.get(
+ useParams<{ channel: string }>().channel,
+ )!;
+
+ type Sort = "Relevance" | "Latest" | "Oldest";
+ const [sort, setSort] = useState("Latest");
+ const [query, setQuery] = useState("");
+
+ const [state, setState] = useState({ type: "waiting" });
+
+ async function search() {
+ if (!query) return;
+ setState({ type: "loading" });
+ const data = await channel.searchWithUsers({ query, sort });
+ setState({ type: "results", results: data.messages });
+ }
+
+ useEffect(() => {
+ search();
+ // eslint-disable-next-line
+ }, [sort]);
+
+ return (
+
+
+
+ go back to members
+
+
+
+
+ e.key === "Enter" && search()}
+ onChange={(e) => setQuery(e.currentTarget.value)}
+ />
+
+ {["Latest", "Oldest", "Relevance"].map((key) => (
+
+ ))}
+
+ {state.type === "loading" && }
+ {state.type === "results" && (
+
+ {state.results.map((message) => {
+ let href = "";
+ if (channel?.channel_type === "TextChannel") {
+ href += `/server/${channel.server_id}`;
+ }
+
+ href += `/channel/${message.channel_id}/${message._id}`;
+
+ return (
+
+
+
+
+
+ );
+ })}
+
+ )}
+
+
+ );
+}
diff --git a/src/lib/eventEmitter.ts b/src/lib/eventEmitter.ts
index cdb6c3a2..51227f27 100644
--- a/src/lib/eventEmitter.ts
+++ b/src/lib/eventEmitter.ts
@@ -18,6 +18,7 @@ export function internalEmit(ns: string, event: string, ...args: unknown[]) {
// Event structure: namespace/event
/// Event List
+// - RightSidebar/open
// - MessageArea/jump_to_bottom
// - MessageRenderer/edit_last
// - MessageRenderer/edit_message
diff --git a/src/pages/channels/actions/HeaderActions.tsx b/src/pages/channels/actions/HeaderActions.tsx
index 3a9bb1ab..ef3ba03c 100644
--- a/src/pages/channels/actions/HeaderActions.tsx
+++ b/src/pages/channels/actions/HeaderActions.tsx
@@ -1,4 +1,5 @@
/* eslint-disable react-hooks/rules-of-hooks */
+import { Search } from "@styled-icons/boxicons-regular";
import {
UserPlus,
Cog,
@@ -8,6 +9,7 @@ import {
} from "@styled-icons/boxicons-solid";
import { useHistory } from "react-router-dom";
+import { internalEmit } from "../../../lib/eventEmitter";
import { isTouchscreenDevice } from "../../../lib/isTouchscreenDevice";
import { voiceState, VoiceStatus } from "../../../lib/vortex/VoiceState";
@@ -25,13 +27,17 @@ export default function HeaderActions({
const { openScreen } = useIntermediate();
const history = useHistory();
+ function openRightSidebar() {
+ const panels = document.querySelector("#app > div > div");
+ panels?.scrollTo({
+ behavior: "smooth",
+ left: panels.clientWidth * 3,
+ });
+ }
+
function openSidebar() {
if (isTouchscreenDevice) {
- const panels = document.querySelector("#app > div > div");
- panels?.scrollTo({
- behavior: "smooth",
- left: panels.clientWidth * 3,
- });
+ openRightSidebar();
} else {
toggleSidebar?.();
}
@@ -65,6 +71,15 @@ export default function HeaderActions({
>
)}
+ {channel.channel_type !== "VoiceChannel" && (
+ {
+ internalEmit("RightSidebar", "open", "search");
+ openRightSidebar();
+ }}>
+
+
+ )}
{(channel.channel_type === "Group" ||
channel.channel_type === "TextChannel") && (