From 454ee7fd6e993005a712c896ed8ddf2ab0ca024c Mon Sep 17 00:00:00 2001
From: Paul <paulmakles@gmail.com>
Date: Tue, 22 Jun 2021 11:56:37 +0100
Subject: [PATCH] Add server creation button. Add profile links / app links
 back. Add quoting / mentioning back.

---
 .../common/messaging/MessageBox.tsx           | 26 ++++++++--
 src/components/markdown/Renderer.tsx          |  5 +-
 src/components/navigation/SidebarBase.tsx     | 10 ++--
 .../navigation/left/HomeSidebar.tsx           |  2 +-
 .../navigation/left/ServerListSidebar.tsx     | 47 +++++--------------
 src/context/index.tsx                         | 16 +++----
 src/context/intermediate/Intermediate.tsx     | 36 +++++++-------
 src/lib/ContextMenus.tsx                      | 20 ++++----
 src/lib/eventEmitter.ts                       |  5 +-
 src/pages/settings/Settings.module.scss       |  4 +-
 10 files changed, 88 insertions(+), 83 deletions(-)

diff --git a/src/components/common/messaging/MessageBox.tsx b/src/components/common/messaging/MessageBox.tsx
index ed0f78e..ffcc45a 100644
--- a/src/components/common/messaging/MessageBox.tsx
+++ b/src/components/common/messaging/MessageBox.tsx
@@ -6,20 +6,20 @@ import IconButton from "../../ui/IconButton";
 import { Send } from '@styled-icons/feather';
 import Axios, { CancelTokenSource } from "axios";
 import { useTranslation } from "../../../lib/i18n";
-import { useCallback, useContext, useState } from "preact/hooks";
 import { connectState } from "../../../redux/connector";
 import { WithDispatcher } from "../../../redux/reducers";
 import { takeError } from "../../../context/revoltjs/util";
 import TextAreaAutoSize from "../../../lib/TextAreaAutoSize";
 import { AppContext } from "../../../context/revoltjs/RevoltClient";
 import { isTouchscreenDevice } from "../../../lib/isTouchscreenDevice";
+import { internalEmit, internalSubscribe } from "../../../lib/eventEmitter";
+import { useCallback, useContext, useEffect, useState } from "preact/hooks";
 import { useIntermediate } from "../../../context/intermediate/Intermediate";
 import { FileUploader, grabFiles, uploadFile } from "../../../context/revoltjs/FileUploads";
 import { SingletonMessageRenderer, SMOOTH_SCROLL_ON_RECEIVE } from "../../../lib/renderer/Singleton";
 
 import FilePreview from './bars/FilePreview';
 import { debounce } from "../../../lib/debounce";
-import { internalEmit } from "../../../lib/eventEmitter";
 
 type Props = WithDispatcher & {
     channel: Channel;
@@ -71,6 +71,26 @@ function MessageBox({ channel, draft, dispatcher }: Props) {
         }
     }
 
+    useEffect(() => {
+        function append(content: string, action: 'quote' | 'mention') {
+            const text =
+                action === "quote"
+                    ? `${content
+                          .split("\n")
+                          .map(x => `> ${x}`)
+                          .join("\n")}\n\n`
+                    : `${content} `;
+
+            if (!draft || draft.length === 0) {
+                setMessage(text);
+            } else {
+                setMessage(`${draft}\n${text}`);
+            }
+        }
+
+        return internalSubscribe("MessageBox", "append", append);
+    }, [ draft ]);
+
     async function send() {
         if (uploadState.type === 'uploading' || uploadState.type === 'sending') return;
         
@@ -241,7 +261,7 @@ function MessageBox({ channel, draft, dispatcher }: Props) {
                     autoFocus
                     hideBorder
                     maxRows={5}
-                    padding={15}
+                    padding={14}
                     id="message"
                     value={draft ?? ''}
                     onKeyDown={e => {
diff --git a/src/components/markdown/Renderer.tsx b/src/components/markdown/Renderer.tsx
index 35dbef8..c2a8592 100644
--- a/src/components/markdown/Renderer.tsx
+++ b/src/components/markdown/Renderer.tsx
@@ -4,6 +4,7 @@ import { generateEmoji } from "./Emoji";
 import { useContext } from "preact/hooks";
 import { MarkdownProps } from "./Markdown";
 import styles from "./Markdown.module.scss";
+import { internalEmit } from "../../lib/eventEmitter";
 import { AppContext } from "../../context/revoltjs/RevoltClient";
 
 import Prism from "prismjs";
@@ -70,9 +71,9 @@ if (typeof window !== "undefined") {
         const pathname = url.pathname;
 
         if (pathname.startsWith("/@")) {
-            //InternalEventEmitter.emit("openProfile", pathname.substr(2));
+            internalEmit("Intermediate", "openProfile", pathname.substr(2));
         } else {
-            //InternalEventEmitter.emit("navigate", pathname);
+            internalEmit("Intermediate", "navigate", pathname.substr(2));
         }
     };
 }
diff --git a/src/components/navigation/SidebarBase.tsx b/src/components/navigation/SidebarBase.tsx
index b9060c0..4cf8b1a 100644
--- a/src/components/navigation/SidebarBase.tsx
+++ b/src/components/navigation/SidebarBase.tsx
@@ -7,19 +7,19 @@ export default styled.div`
     user-select: none;
     flex-direction: row;
     align-items: stretch;
-
-    ${ isTouchscreenDevice && css`
-        padding-bottom: 50px;
-    ` }
 `;
 
-export const GenericSidebarBase = styled.div`
+export const GenericSidebarBase = styled.div<{ padding?: boolean }>`
     height: 100%;
     width: 240px;
     display: flex;
     flex-shrink: 0;
     flex-direction: column;
     background: var(--secondary-background);
+
+    ${ props => props.padding && isTouchscreenDevice && css`
+        padding-bottom: 50px;
+    ` }
 `;
 
 export const GenericSidebarList = styled.div`
diff --git a/src/components/navigation/left/HomeSidebar.tsx b/src/components/navigation/left/HomeSidebar.tsx
index 4437ccc..ac05418 100644
--- a/src/components/navigation/left/HomeSidebar.tsx
+++ b/src/components/navigation/left/HomeSidebar.tsx
@@ -49,7 +49,7 @@ function HomeSidebar(props: Props) {
     channelsArr.sort((b, a) => a.timestamp.localeCompare(b.timestamp));
 
     return (
-        <GenericSidebarBase>
+        <GenericSidebarBase padding>
             <UserHeader user={client.user!} />
             <ConnectionStatus />
             <GenericSidebarList>
diff --git a/src/components/navigation/left/ServerListSidebar.tsx b/src/components/navigation/left/ServerListSidebar.tsx
index 798675c..c7e2fc9 100644
--- a/src/components/navigation/left/ServerListSidebar.tsx
+++ b/src/components/navigation/left/ServerListSidebar.tsx
@@ -1,14 +1,18 @@
+import IconButton from "../../ui/IconButton";
 import LineDivider from "../../ui/LineDivider";
 import { mapChannelWithUnread } from "./common";
 import styled, { css } from "styled-components";
 import ServerIcon from "../../common/ServerIcon";
 import { Children } from "../../../types/Preact";
+import { PlusCircle } from "@styled-icons/feather";
 import PaintCounter from "../../../lib/PaintCounter";
 import { attachContextMenu } from 'preact-context-menu';
 import { connectState } from "../../../redux/connector";
 import { Unreads } from "../../../redux/reducers/unreads";
 import { Channel, Servers } from "revolt.js/dist/api/objects";
 import { Link, useLocation, useParams } from "react-router-dom";
+import { isTouchscreenDevice } from "../../../lib/isTouchscreenDevice";
+import { useIntermediate } from "../../../context/intermediate/Intermediate";
 import { useChannels, useForceUpdate, useServers } from "../../../context/revoltjs/hooks";
 
 import logoSVG from '../../../assets/logo.svg';
@@ -49,6 +53,10 @@ const ServersBase = styled.div`
     height: 100%;
     display: flex;
     flex-direction: column;
+
+    ${ isTouchscreenDevice && css`
+        padding-bottom: 50px;
+    ` }
 `;
 
 const ServerList = styled.div`
@@ -128,7 +136,7 @@ export function ServerListSidebar({ unreads }: Props) {
     const { server: server_id } = useParams<{ server?: string }>();
     const server = servers.find(x => x!._id == server_id);
 
-    // const { openScreen } = useContext(IntermediateContext);
+    const { openScreen } = useIntermediate();
 
     let homeUnread: 'mention' | 'unread' | undefined;
     let alertCount = 0;
@@ -166,43 +174,12 @@ export function ServerListSidebar({ unreads }: Props) {
                         </Link>
                     )
                 }
+                <IconButton onClick={() => openScreen({ id: 'special_input', type: 'create_server' })}>
+                    <PlusCircle size={36} />
+                </IconButton>
                 <PaintCounter small />
             </ServerList>
         </ServersBase>
-        // ! FIXME: add overlay back
-        /*<div className={styles.servers}>
-            <div className={styles.list}>
-                <Link to={`/`}>
-                    <div className={styles.entry}
-                        data-active={typeof server === 'undefined' && !path.startsWith('/invite')}>
-                        <Icon size={36} unread={homeUnread} alertCount={alertCount}>
-                            <div className={styles.logo} />
-                        </Icon>
-                    </div>
-                </Link>
-                <LineDivider className={styles.divider} />
-                {
-                    servers.map(entry =>
-                        <Link to={`/server/${entry!._id}`}>
-                            <div className={styles.entry}
-                                data-active={entry!._id === server?._id}
-                                onContextMenu={attachContextMenu('Menu', { server: entry!._id })}>
-                                <Icon size={36} unread={entry.unread}>
-                                    <ServerIcon id={entry!._id} size={32} />
-                                </Icon>
-                            </div>
-                        </Link>
-                    )
-                }
-            </div>
-            <div className={styles.overlay}>
-                <div className={styles.actions}>
-                    <IconButton onClick={() => openScreen({ id: 'special_input', type: 'create_server' })}>
-                        <PlusCircle size={36} />
-                    </IconButton>
-                </div>
-            </div>
-            </div> */
     )
 }
 
diff --git a/src/context/index.tsx b/src/context/index.tsx
index fde2bfa..8496762 100644
--- a/src/context/index.tsx
+++ b/src/context/index.tsx
@@ -9,16 +9,16 @@ import Theme from "./Theme";
 
 export default function Context({ children }: { children: Children }) {
     return (
-        <State>
-            <Locale>
-                <Intermediate>
-                    <BrowserRouter>
+        <BrowserRouter>
+            <State>
+                <Locale>
+                    <Intermediate>
                         <ClientContext>
                             <Theme>{children}</Theme>
                         </ClientContext>
-                    </BrowserRouter>
-                </Intermediate>
-            </Locale>
-        </State>
+                    </Intermediate>
+                </Locale>
+            </State>
+        </BrowserRouter>
     );
 }
diff --git a/src/context/intermediate/Intermediate.tsx b/src/context/intermediate/Intermediate.tsx
index 1c6bc8e..67b5f01 100644
--- a/src/context/intermediate/Intermediate.tsx
+++ b/src/context/intermediate/Intermediate.tsx
@@ -1,9 +1,11 @@
 import { Attachment, Channels, EmbedImage, Servers } from "revolt.js/dist/api/objects";
 import { useContext, useEffect, useMemo, useState } from "preact/hooks";
+import { internalSubscribe } from "../../lib/eventEmitter";
 import { Action } from "../../components/ui/Modal";
 import { useHistory } from "react-router-dom";
 import { Children } from "../../types/Preact";
 import { createContext } from "preact";
+import { Prompt } from "react-router";
 import Modals from './Modals';
 
 export type Screen =
@@ -92,17 +94,15 @@ export default function Intermediate(props: Props) {
     }, []);
 
     useEffect(() => {
-//        const openProfile = (user_id: string) =>
-//            openScreen({ id: "profile", user_id });
-        // const navigate = (path: string) => history.push(path);
+        const openProfile = (user_id: string) => openScreen({ id: "profile", user_id });
+        const navigate = (path: string) => history.push(path);
 
-        // InternalEventEmitter.addListener("openProfile", openProfile);
-        // InternalEventEmitter.addListener("navigate", navigate);
+        const subs = [
+            internalSubscribe("Intermediate", "open_profile", openProfile),
+            internalSubscribe("Intermediate", "navigate", navigate)
+        ]
 
-        return () => {
-            // InternalEventEmitter.removeListener("openProfile", openProfile);
-            // InternalEventEmitter.removeListener("navigate", navigate);
-        };
+        return () => subs.map(unsub => unsub());
     }, []);
 
     return (
@@ -116,15 +116,19 @@ export default function Intermediate(props: Props) {
                         screen.id
                     } /** By specifying a key, we reset state whenever switching screen. */
                 />
-                {/*<Prompt
-                    when={screen.id !== 'none'}
-                    message={() => {
-                        openScreen({ id: 'none' });
-                        setTimeout(() => history.push(history.location), 0);
+                <Prompt
+                    when={[ 'modify_account', 'special_prompt', 'special_input', 'image_viewer', 'profile', 'channel_info', 'user_picker' ].includes(screen.id)}
+                    message={(_, action) => {
+                        if (action === 'POP') {
+                            openScreen({ id: 'none' });
+                            setTimeout(() => history.push(history.location), 0);
 
-                        return false;
+                            return false;
+                        }
+
+                        return true;
                     }}
-                />*/}
+                />
             </IntermediateActionsContext.Provider>
         </IntermediateContext.Provider>
     );
diff --git a/src/lib/ContextMenus.tsx b/src/lib/ContextMenus.tsx
index e0e3a37..80797e2 100644
--- a/src/lib/ContextMenus.tsx
+++ b/src/lib/ContextMenus.tsx
@@ -138,12 +138,12 @@ function ContextMenus(props: WithDispatcher) {
 
                 case "mention":
                     {
-                        // edit draft
-                        /*InternalEventEmitter.emit(
-                            "append_messagebox",
+                        internalEmit(
+                            "MessageBox",
+                            "append",
                             `<@${data.user}>`,
                             "mention"
-                        );*/
+                        );
                     }
                     break;
 
@@ -152,12 +152,12 @@ function ContextMenus(props: WithDispatcher) {
                     break;
                 case "quote_message":
                     {
-                        // edit draft
-                        /*InternalEventEmitter.emit(
-                            "append_messagebox",
+                        internalEmit(
+                            "MessageBox",
+                            "append",
                             data.content,
                             "quote"
-                        );*/
+                        );
                     }
                     break;
 
@@ -190,10 +190,10 @@ function ContextMenus(props: WithDispatcher) {
 
                 case "copy_file_link":
                     {
-                        const { _id, filename } = data.attachment;
+                        const { filename } = data.attachment;
                         writeClipboard(
                             // ! FIXME: do from r.js
-                            client.generateFileURL(data.attachment) + '/${encodeURI(filename)}',
+                            client.generateFileURL(data.attachment) + `/${encodeURI(filename)}`,
                         );
                     }
                     break;
diff --git a/src/lib/eventEmitter.ts b/src/lib/eventEmitter.ts
index 5eaf08d..5e76841 100644
--- a/src/lib/eventEmitter.ts
+++ b/src/lib/eventEmitter.ts
@@ -15,4 +15,7 @@ export function internalEmit(ns: string, event: string, ...args: any[]) {
 /// Event List
 // - MessageRenderer/edit_last
 // - MessageRenderer/edit_message
-// - MessageBox/focus
+// - Intermediate/open_profile
+// - Intermediate/navigate
+// - MessageBox/append
+// - TextArea/focus
diff --git a/src/pages/settings/Settings.module.scss b/src/pages/settings/Settings.module.scss
index dcb24eb..2540c1c 100644
--- a/src/pages/settings/Settings.module.scss
+++ b/src/pages/settings/Settings.module.scss
@@ -14,7 +14,7 @@
     100% {transform: scale(1.2); opacity: 0;};
 }
 
-[data-touchscreen-device="true"] .settings {
+.settings[data-mobile="true"] {
     flex-direction: column;
     background: var(--primary-header);
 
@@ -45,7 +45,7 @@
     }
 }
 
-:global(.app):not([data-touchscreen-device="true"]) .settings {
+.settings:not([data-mobile="true"]) {
     top: 0;
     left: 0;
     z-index: 10;
-- 
GitLab