From 7982489ab63bbeb9def63dd2eee33f8f4eee3824 Mon Sep 17 00:00:00 2001
From: Paul <paulmakles@gmail.com>
Date: Fri, 2 Jul 2021 13:35:50 +0100
Subject: [PATCH] Link to profiles from message / member sidebar.

---
 src/components/common/messaging/Message.tsx   |  8 +++++--
 .../navigation/items/ButtonItem.tsx           | 23 ++++++++++++-------
 .../navigation/right/MemberSidebar.tsx        | 16 ++++++-------
 src/context/intermediate/Intermediate.tsx     |  2 +-
 4 files changed, 30 insertions(+), 19 deletions(-)

diff --git a/src/components/common/messaging/Message.tsx b/src/components/common/messaging/Message.tsx
index 0c53694..8c27c51 100644
--- a/src/components/common/messaging/Message.tsx
+++ b/src/components/common/messaging/Message.tsx
@@ -14,6 +14,7 @@ import { useContext } from "preact/hooks";
 import { AppContext } from "../../../context/revoltjs/RevoltClient";
 import { memo } from "preact/compat";
 import { MessageReply } from "./attachments/MessageReply";
+import { useIntermediate } from "../../../context/intermediate/Intermediate";
 
 interface Props {
     attachContext?: boolean
@@ -29,10 +30,13 @@ function Message({ attachContext, message, contrast, content: replacement, head:
     // TODO: of dependencies. We only need to update on u/avatar.
     const user = useUser(message.author);
     const client = useContext(AppContext);
+    const { openScreen } = useIntermediate();
 
     const content = message.content as string;
     const head = preferHead || (message.replies && message.replies.length > 0);
+
     const userContext = attachContext ? attachContextMenu('Menu', { user: message.author, contextualChannel: message.channel }) : undefined as any; // ! FIXME: tell fatal to make this type generic
+    const openProfile = () => openScreen({ id: 'profile', user_id: message.author });
 
     return (
         <div id={message._id}>
@@ -46,13 +50,13 @@ function Message({ attachContext, message, contrast, content: replacement, head:
                 onContextMenu={attachContext ? attachContextMenu('Menu', { message, contextualChannel: message.channel, queued }) : undefined}>
                 <MessageInfo>
                     { head ?
-                        <UserIcon target={user} size={36} onContextMenu={userContext} /> :
+                        <UserIcon target={user} size={36} onContextMenu={userContext} onClick={openProfile} /> :
                         <MessageDetail message={message} position="left" /> }
                 </MessageInfo>
                 <MessageContent>
                     { head && <span className="detail">
                         <span className="author">
-                            <Username user={user} onContextMenu={userContext} />
+                            <Username user={user} onContextMenu={userContext} onClick={openProfile} />
                         </span>
                         <MessageDetail message={message} position="top" />
                     </span> }
diff --git a/src/components/navigation/items/ButtonItem.tsx b/src/components/navigation/items/ButtonItem.tsx
index 139ec67..176f5f8 100644
--- a/src/components/navigation/items/ButtonItem.tsx
+++ b/src/components/navigation/items/ButtonItem.tsx
@@ -14,7 +14,7 @@ import { isTouchscreenDevice } from "../../../lib/isTouchscreenDevice";
 import { useIntermediate } from '../../../context/intermediate/Intermediate';
 import { stopPropagation } from '../../../lib/stopPropagation';
 
-interface CommonProps {
+type CommonProps = Omit<JSX.HTMLAttributes<HTMLDivElement>, 'children' | 'as'> & {
     active?: boolean
     alert?: 'unread' | 'mention'
     alertCount?: number
@@ -26,11 +26,12 @@ type UserProps = CommonProps & {
     channel?: Channels.DirectMessageChannel
 }
 
-export function UserButton({ active, alert, alertCount, user, context, channel }: UserProps) {
+export function UserButton(props: UserProps) {
+    const { active, alert, alertCount, user, context, channel, ...divProps } = props;
     const { openScreen } = useIntermediate();
 
     return (
-        <div
+        <div {...divProps}
             className={classNames(styles.item, styles.user)}
             data-active={active}
             data-alert={typeof alert === 'string'}
@@ -85,7 +86,9 @@ type ChannelProps = CommonProps & {
     compact?: boolean
 }
 
-export function ChannelButton({ active, alert, alertCount, channel, user, compact }: ChannelProps) {
+export function ChannelButton(props: ChannelProps) {
+    const { active, alert, alertCount, channel, user, compact, ...divProps } = props;
+
     if (channel.channel_type === 'SavedMessages') throw "Invalid channel type.";
     if (channel.channel_type === 'DirectMessage') {
         if (typeof user === 'undefined') throw "No user provided.";
@@ -95,9 +98,10 @@ export function ChannelButton({ active, alert, alertCount, channel, user, compac
     const { openScreen } = useIntermediate();
 
     return (
-        <div data-active={active}
+        <div {...divProps}
+            data-active={active}
             data-alert={typeof alert === 'string'}
-            aria-label={{}} /*TOFIX: ADD ARIA LABEL*/
+            aria-label={{}} /*FIXME: ADD ARIA LABEL*/
             className={classNames(styles.item, { [styles.compact]: compact })}
             onContextMenu={attachContextMenu('Menu', { channel: channel._id, unread: typeof channel.unread !== 'undefined' })}>
             <ChannelIcon className={styles.avatar} target={channel} size={compact ? 24 : 32} />
@@ -138,9 +142,12 @@ type ButtonProps = CommonProps & {
     compact?: boolean
 }
 
-export default function ButtonItem({ active, alert, alertCount, onClick, className, children, compact }: ButtonProps) {
+export default function ButtonItem(props: ButtonProps) {
+    const { active, alert, alertCount, onClick, className, children, compact, ...divProps } = props;
+
     return (
-        <div className={classNames(styles.item, { [styles.compact]: compact, [styles.normal]: !compact }, className)}
+        <div {...divProps}
+            className={classNames(styles.item, { [styles.compact]: compact, [styles.normal]: !compact }, className)}
             onClick={onClick}
             data-active={active}
             data-alert={typeof alert === 'string'}>
diff --git a/src/components/navigation/right/MemberSidebar.tsx b/src/components/navigation/right/MemberSidebar.tsx
index 9738354..96b3728 100644
--- a/src/components/navigation/right/MemberSidebar.tsx
+++ b/src/components/navigation/right/MemberSidebar.tsx
@@ -8,11 +8,12 @@ import { UserButton } from "../items/ButtonItem";
 import { ChannelDebugInfo } from "./ChannelDebugInfo";
 import { Channels, Servers, Users } from "revolt.js/dist/api/objects";
 import { GenericSidebarBase, GenericSidebarList } from "../SidebarBase";
+import { useIntermediate } from "../../../context/intermediate/Intermediate";
 import { ClientboundNotification } from "revolt.js/dist/websocket/notifications";
+import { AppContext, ClientStatus, StatusContext } from "../../../context/revoltjs/RevoltClient";
 import { HookContext, useChannel, useForceUpdate, useUsers } from "../../../context/revoltjs/hooks";
 
 import placeholderSVG from "../items/placeholder.svg";
-import { AppContext, ClientStatus, StatusContext } from "../../../context/revoltjs/RevoltClient";
 
 interface Props {
     ctx: HookContext
@@ -31,6 +32,7 @@ export default function MemberSidebar(props: { channel?: Channels.Channel }) {
 }
 
 export function GroupMemberSidebar({ channel, ctx }: Props & { channel: Channels.GroupChannel }) {
+    const { openScreen } = useIntermediate();
     const users = useUsers(undefined, ctx);
     let members = channel.recipients
         .map(x => users.find(y => y?._id === x))
@@ -112,13 +114,11 @@ export function GroupMemberSidebar({ channel, ctx }: Props & { channel: Channels
                 {members.map(
                     user =>
                         user && (
-                            // <LinkProfile user_id={user._id}>
-                                <UserButton
-                                    key={user._id}
-                                    user={user}
-                                    context={channel}
-                                />
-                            // </LinkProfile>
+                            <UserButton
+                                key={user._id}
+                                user={user}
+                                context={channel}
+                                onClick={() => openScreen({ id: 'profile', user_id: user._id })} />
                         )
                 )}
             </GenericSidebarList>
diff --git a/src/context/intermediate/Intermediate.tsx b/src/context/intermediate/Intermediate.tsx
index ff723c0..3fb8167 100644
--- a/src/context/intermediate/Intermediate.tsx
+++ b/src/context/intermediate/Intermediate.tsx
@@ -98,7 +98,7 @@ export default function Intermediate(props: Props) {
         const navigate = (path: string) => history.push(path);
 
         const subs = [
-            internalSubscribe("Intermediate", "open_profile", openProfile),
+            internalSubscribe("Intermediate", "openProfile", openProfile),
             internalSubscribe("Intermediate", "navigate", navigate)
         ]
 
-- 
GitLab