From 64d2dec3f9c890f7ea1eeb8194bdf2f8633110ab Mon Sep 17 00:00:00 2001 From: Maria Rushkova <66270386+mrushkova@users.noreply.github.com> Date: Tue, 4 Jan 2022 07:58:06 +0100 Subject: [PATCH] UI changes (#166) * Change read mark for messages * Change logout button * Change dm chat description * Fix creating dm channel * Fix reaction icon * Add tooltips to reaction buttons * Add reaction picker * Add reaction svg sizes * Extract Reactions --- .../src/components/ActivityCenter.tsx | 3 +- .../src/components/Chat/ChatCreation.tsx | 12 ++- .../components/Chat/ChatMessageContent.tsx | 2 +- .../src/components/Form/ReactionPicker.tsx | 65 +++++++++++++++ .../src/components/Form/Reactions.tsx | 80 +++++++++++++++++++ .../src/components/Icons/LogoutIcon.tsx | 2 +- .../src/components/Icons/ReactionIcon.tsx | 13 ++- .../src/components/Icons/ReadMessageIcon.tsx | 33 ++++++++ .../src/components/Members/Member.tsx | 19 +++-- .../src/components/Members/MembersList.tsx | 15 +++- .../src/components/Messages/UiMessage.tsx | 58 +++----------- 11 files changed, 229 insertions(+), 73 deletions(-) create mode 100644 packages/react-chat/src/components/Form/ReactionPicker.tsx create mode 100644 packages/react-chat/src/components/Form/Reactions.tsx create mode 100644 packages/react-chat/src/components/Icons/ReadMessageIcon.tsx diff --git a/packages/react-chat/src/components/ActivityCenter.tsx b/packages/react-chat/src/components/ActivityCenter.tsx index 7333075..a1e838d 100644 --- a/packages/react-chat/src/components/ActivityCenter.tsx +++ b/packages/react-chat/src/components/ActivityCenter.tsx @@ -22,6 +22,7 @@ import { HideIcon } from "./Icons/HideIcon"; import { Icon } from "./Icons/Icon"; import { MoreIcon } from "./Icons/MoreIcon"; import { ReadIcon } from "./Icons/ReadIcon"; +import { ReadMessageIcon } from "./Icons/ReadMessageIcon"; import { ReplyIcon } from "./Icons/ReplyActivityIcon"; import { ShowIcon } from "./Icons/ShowIcon"; import { UntrustworthIcon } from "./Icons/UntrustworthIcon"; @@ -247,7 +248,7 @@ function ActivityMessage({ }} className={`${activity.isRead && "read"}`} > - + diff --git a/packages/react-chat/src/components/Chat/ChatCreation.tsx b/packages/react-chat/src/components/Chat/ChatCreation.tsx index fdc0a68..75ffa4a 100644 --- a/packages/react-chat/src/components/Chat/ChatCreation.tsx +++ b/packages/react-chat/src/components/Chat/ChatCreation.tsx @@ -27,7 +27,8 @@ export function ChatCreation({ (member) => member?.customName ?? member.trueName ) ?? [] ); - const { contacts, createGroupChat, addMembers } = useMessengerContext(); + const { contacts, createGroupChat, addMembers, setChannel } = + useMessengerContext(); const setChatState = useChatState()[1]; const addMember = useCallback( @@ -50,7 +51,14 @@ export function ChatCreation({ if (identity) { const newGroup = group.slice(); newGroup.push(bufToHex(identity.publicKey)); - group.length > 1 ? createGroupChat(newGroup) : createGroupChat(newGroup); + group.length > 1 + ? createGroupChat(newGroup) + : setChannel({ + id: newGroup[0], + name: newGroup[0], + type: "dm", + description: `Chatkey: ${newGroup[0]} `, + }); setChatState(ChatState.ChatBody); } }; diff --git a/packages/react-chat/src/components/Chat/ChatMessageContent.tsx b/packages/react-chat/src/components/Chat/ChatMessageContent.tsx index bed14e7..62bd1ee 100644 --- a/packages/react-chat/src/components/Chat/ChatMessageContent.tsx +++ b/packages/react-chat/src/components/Chat/ChatMessageContent.tsx @@ -197,7 +197,7 @@ const ContentWrapper = styled.div` `; const MentionBLock = styled.div` - display: inline-block; + display: inline-flex; color: ${({ theme }) => theme.mentionColor}; background: ${({ theme }) => theme.mentionBgHover}; border-radius: 4px; diff --git a/packages/react-chat/src/components/Form/ReactionPicker.tsx b/packages/react-chat/src/components/Form/ReactionPicker.tsx new file mode 100644 index 0000000..9900420 --- /dev/null +++ b/packages/react-chat/src/components/Form/ReactionPicker.tsx @@ -0,0 +1,65 @@ +import { Emoji, getEmojiDataFromNative } from "emoji-mart"; +import data from "emoji-mart/data/all.json"; +import React from "react"; +import styled from "styled-components"; + +const emojiHeart = getEmojiDataFromNative("❤️", "twitter", data); +const emojiLike = getEmojiDataFromNative("👍", "twitter", data); +const emojiDislike = getEmojiDataFromNative("👎", "twitter", data); +const emojiLaughing = getEmojiDataFromNative("😆", "twitter", data); +const emojiDisappointed = getEmojiDataFromNative("😥", "twitter", data); +const emojiRage = getEmojiDataFromNative("😡", "twitter", data); + +const emojiArr = [ + emojiHeart, + emojiLike, + emojiDislike, + emojiLaughing, + emojiDisappointed, + emojiRage, +]; + +export function ReactionPicker() { + return ( + + {emojiArr.map((emoji) => ( + + {" "} + + + ))} + + ); +} + +const Wrapper = styled.div` + width: 266px; + display: flex; + justify-content: space-between; + position: absolute; + right: 20px; + top: -78px; + background: ${({ theme }) => theme.bodyBackgroundColor}; + box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.08); + border-radius: 16px 16px 4px 16px; + padding: 8px 12px; + visibility: hidden; +`; + +const EmojiBtn = styled.button` + width: 40px; + height: 40px; + display: flex; + justify-content: center; + align-items: center; + border-radius: 8px; + + &:hover { + background: ${({ theme }) => theme.inputColor}; + } +`; diff --git a/packages/react-chat/src/components/Form/Reactions.tsx b/packages/react-chat/src/components/Form/Reactions.tsx new file mode 100644 index 0000000..21d3bdf --- /dev/null +++ b/packages/react-chat/src/components/Form/Reactions.tsx @@ -0,0 +1,80 @@ +import React from "react"; +import styled from "styled-components"; + +import { Reply } from "../../hooks/useReply"; +import { ChatMessage } from "../../models/ChatMessage"; +import { ReactionSvg } from "../Icons/ReactionIcon"; +import { ReplySvg } from "../Icons/ReplyIcon"; + +import { Tooltip } from "./Tooltip"; + +interface ReactionsProps { + message: ChatMessage; + showReactions: boolean; + setShowReactions: (val: boolean) => void; + setReply: (val: Reply | undefined) => void; +} + +export function Reactions({ + message, + showReactions, + setShowReactions, + setReply, +}: ReactionsProps) { + return ( + + setShowReactions(!showReactions)}> + + + + + setReply({ + sender: message.sender, + content: message.content, + image: message.image, + id: message.id, + }) + } + > + + + + + ); +} + +const Wrapper = styled.div` + display: flex; + position: absolute; + right: 20px; + top: -18px; + box-shadow: 0px 4px 12px rgba(0, 34, 51, 0.08); + border-radius: 8px; + background: ${({ theme }) => theme.bodyBackgroundColor}; + padding: 2px; + visibility: hidden; +`; + +const ReactionBtn = styled.button` + width: 32px; + height: 32px; + display: flex; + justify-content: center; + align-items: center; + border-radius: 8px; + align-self: center; + position: relative; + + &:hover { + background: ${({ theme }) => theme.buttonBgHover}; + } + + &:hover > svg { + fill: ${({ theme }) => theme.tertiary}; + } + + &:hover > div { + visibility: visible; + } +`; diff --git a/packages/react-chat/src/components/Icons/LogoutIcon.tsx b/packages/react-chat/src/components/Icons/LogoutIcon.tsx index 1efe7da..4e9534a 100644 --- a/packages/react-chat/src/components/Icons/LogoutIcon.tsx +++ b/packages/react-chat/src/components/Icons/LogoutIcon.tsx @@ -17,5 +17,5 @@ export const LogoutIcon = () => { }; const Icon = styled.svg` - fill: ${({ theme }) => theme.primary}; + fill: ${({ theme }) => theme.tertiary}; `; diff --git a/packages/react-chat/src/components/Icons/ReactionIcon.tsx b/packages/react-chat/src/components/Icons/ReactionIcon.tsx index 22703b8..6e3b376 100644 --- a/packages/react-chat/src/components/Icons/ReactionIcon.tsx +++ b/packages/react-chat/src/components/Icons/ReactionIcon.tsx @@ -2,14 +2,16 @@ import React from "react"; import styled from "styled-components"; type ReactionProps = { + width: number; + height: number; className?: string; }; -export function ReactionSvg({ className }: ReactionProps) { +export function ReactionSvg({ width, height, className }: ReactionProps) { return ( - - - - - ); } diff --git a/packages/react-chat/src/components/Icons/ReadMessageIcon.tsx b/packages/react-chat/src/components/Icons/ReadMessageIcon.tsx new file mode 100644 index 0000000..f2e6039 --- /dev/null +++ b/packages/react-chat/src/components/Icons/ReadMessageIcon.tsx @@ -0,0 +1,33 @@ +import React from "react"; +import styled from "styled-components"; + +interface ReadMessageIconProps { + isRead?: boolean; +} + +export const ReadMessageIcon = ({ isRead }: ReadMessageIconProps) => { + return ( + + + + ); +}; + +const Icon = styled.svg` + fill: ${({ theme }) => theme.tertiary}; + + &.read { + fill: ${({ theme }) => theme.secondary}; + } +`; diff --git a/packages/react-chat/src/components/Members/Member.tsx b/packages/react-chat/src/components/Members/Member.tsx index 996e64d..72a618a 100644 --- a/packages/react-chat/src/components/Members/Member.tsx +++ b/packages/react-chat/src/components/Members/Member.tsx @@ -29,14 +29,16 @@ export function Member({ const [showMenu, setShowMenu] = useState(false); const onMemberClick = () => { - switchShowMembers?.(); - setChannel({ - id: contact.id, - name: contact?.customName ?? contact.trueName, - type: "dm", - description: "Contact", - members: [contact], - }); + if (!isYou) { + switchShowMembers?.(); + setChannel({ + id: contact.id, + name: contact?.customName ?? contact.trueName, + type: "dm", + description: `Chatkey: ${contact.id} `, + members: [contact], + }); + } }; return ( @@ -82,6 +84,7 @@ export const MemberData = styled.div` &.you { margin-bottom: 0; + cursor: default; } `; diff --git a/packages/react-chat/src/components/Members/MembersList.tsx b/packages/react-chat/src/components/Members/MembersList.tsx index 7d780de..b4756a0 100644 --- a/packages/react-chat/src/components/Members/MembersList.tsx +++ b/packages/react-chat/src/components/Members/MembersList.tsx @@ -9,7 +9,7 @@ import { useSetIdentity, } from "../../contexts/identityProvider"; import { useMessengerContext } from "../../contexts/messengerProvider"; -import { TopBtn } from "../Chat/ChatTopbar"; +import { buttonStyles } from "../Buttons/buttonStyle"; import { LogoutIcon } from "../Icons/LogoutIcon"; import { Member } from "./Member"; @@ -56,12 +56,11 @@ export function MembersList({ switchShowMembers }: MembersListProps) { customName: nickname, trueName: utils.bufToHex(identity.publicKey), }} - switchShowMembers={switchShowMembers} isYou={true} /> - logout(undefined)}> + logout(undefined)}> - + )} @@ -124,3 +123,11 @@ const Row = styled.div` align-items: center; justify-content: space-between; `; + +const LogoutBtn = styled.button` + ${buttonStyles} + width: 32px; + height: 32px; + border-radius: 50%; + padding: 0; +`; diff --git a/packages/react-chat/src/components/Messages/UiMessage.tsx b/packages/react-chat/src/components/Messages/UiMessage.tsx index f161010..a134740 100644 --- a/packages/react-chat/src/components/Messages/UiMessage.tsx +++ b/packages/react-chat/src/components/Messages/UiMessage.tsx @@ -11,9 +11,9 @@ import { ChatMessage } from "../../models/ChatMessage"; import { equalDate } from "../../utils"; import { ChatMessageContent } from "../Chat/ChatMessageContent"; import { ContactMenu } from "../Form/ContactMenu"; +import { ReactionPicker } from "../Form/ReactionPicker"; +import { Reactions } from "../Form/Reactions"; import { Icon } from "../Icons/Icon"; -import { ReactionSvg } from "../Icons/ReactionIcon"; -import { ReplySvg } from "../Icons/ReplyIcon"; import { UntrustworthIcon } from "../Icons/UntrustworthIcon"; import { UserLogo } from "../Members/UserLogo"; @@ -62,6 +62,7 @@ export function UiMessage({ [message.sender, contacts] ); const [showMenu, setShowMenu] = useState(false); + const [showReactions, setShowReactions] = useState(false); const [mentioned, setMentioned] = useState(false); useEffect(() => { @@ -147,23 +148,13 @@ export function UiMessage({ - - - - - - setReply({ - sender: message.sender, - content: message.content, - image: message.image, - id: message.id, - }) - } - > - - - + {showReactions && } + ); @@ -173,32 +164,3 @@ const UserMessageWrapper = styled.div` width: 100%; display: flex; `; - -const Reactions = styled.div` - display: flex; - position: absolute; - right: 20px; - top: -18px; - box-shadow: 0px 4px 12px rgba(0, 34, 51, 0.08); - border-radius: 8px; - background: ${({ theme }) => theme.bodyBackgroundColor}; - visibility: hidden; -`; - -const ReactionBtn = styled.button` - width: 32px; - height: 32px; - display: flex; - justify-content: center; - align-items: center; - border-radius: 8px; - align-self: center; - - &:hover { - background: ${({ theme }) => theme.buttonBgHover}; - } - - &:hover > svg { - fill: ${({ theme }) => theme.tertiary}; - } -`;