From 7922343fa64b9d6b62f5a5bd0221abd2817428f3 Mon Sep 17 00:00:00 2001 From: Szymon Szlachtowicz <38212223+Szymx95@users.noreply.github.com> Date: Thu, 18 Nov 2021 19:23:33 +0100 Subject: [PATCH] Refactor dm and private chat creation (#133) --- .../src/components/Channels/Channels.tsx | 166 +++++++----------- packages/react-chat/src/components/Chat.tsx | 39 ++-- .../src/components/Chat/ChatBody.tsx | 21 +-- .../src/components/Chat/ChatCreation.tsx | 34 +--- .../src/components/Form/ChannelMenu.tsx | 13 +- .../src/components/Members/Member.tsx | 21 +-- .../src/components/Members/Members.tsx | 8 +- .../src/components/Members/MembersList.tsx | 8 +- .../src/components/Modals/ProfileModal.tsx | 2 +- .../components/NarrowMode/NarrowChannels.tsx | 6 - .../components/NarrowMode/NarrowMembers.tsx | 11 +- .../src/contexts/messengerProvider.tsx | 4 +- .../src/hooks/messenger/useMessenger.ts | 58 ++++-- packages/react-chat/src/models/ChannelData.ts | 7 + 14 files changed, 165 insertions(+), 233 deletions(-) diff --git a/packages/react-chat/src/components/Channels/Channels.tsx b/packages/react-chat/src/components/Channels/Channels.tsx index b03c554a..6833f462 100644 --- a/packages/react-chat/src/components/Channels/Channels.tsx +++ b/packages/react-chat/src/components/Channels/Channels.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useMemo } from "react"; +import React, { useEffect } from "react"; import styled from "styled-components"; import { useMessengerContext } from "../../contexts/messengerProvider"; @@ -7,65 +7,73 @@ import { CreateIcon } from "../Icons/CreateIcon"; import { Channel } from "./Channel"; interface ChannelsProps { - membersList: string[]; - groupList: string[][]; setCreateChat: (val: boolean) => void; onCommunityClick?: () => void; } -export function Channels({ - membersList, - groupList, - setCreateChat, +type GenerateChannelsProps = ChannelsProps & { + type: string; +}; + +function GenerateChannels({ + type, onCommunityClick, -}: ChannelsProps) { - const { - clearNotifications, - clearMentions, - mentions, - notifications, - activeChannel, - setActiveChannel, - channels, - } = useMessengerContext(); - const activeChannelId = useMemo(() => activeChannel.id, [activeChannel]); + setCreateChat, +}: GenerateChannelsProps) { + const { mentions, notifications, activeChannel, setActiveChannel, channels } = + useMessengerContext(); + return ( + <> + {Object.values(channels) + .filter((channel) => channel.type === type) + .map((channel) => ( + 0 && !channel.isMuted + ? notifications[channel.id] + : undefined + } + mention={ + mentions[channel.id] > 0 && !channel.isMuted + ? mentions[channel.id] + : undefined + } + onClick={() => { + setActiveChannel(channel); + if (onCommunityClick) { + onCommunityClick(); + } + setCreateChat(false); + }} + /> + ))} + + ); +} + +export function Channels({ setCreateChat, onCommunityClick }: ChannelsProps) { + const { clearNotifications, clearMentions, notifications, activeChannel } = + useMessengerContext(); useEffect(() => { - const channel = channels.find((channel) => channel.id === activeChannelId); - if (channel) { - if (notifications[channel.id] > 0) { - clearNotifications(channel.id); - clearMentions(channel.id); + if (activeChannel) { + if (notifications[activeChannel.id] > 0) { + clearNotifications(activeChannel.id); + clearMentions(activeChannel.id); } } - }, [notifications, activeChannelId]); + }, [notifications, activeChannel]); return ( - {channels.map((channel) => ( - 0 && !channel.isMuted - ? notifications[channel.id] - : undefined - } - mention={ - mentions[channel.id] > 0 && !channel.isMuted - ? mentions[channel.id] - : undefined - } - onClick={() => { - setActiveChannel(channel); - if (onCommunityClick) { - onCommunityClick(); - } - setCreateChat(false); - }} - /> - ))} + @@ -75,56 +83,16 @@ export function Channels({ - {groupList.length > 0 && - groupList.map((group) => ( - { - setActiveChannel({ - id: group.join(""), - name: group.join(", "), - type: "group", - }); - setCreateChat(false); - if (onCommunityClick) { - onCommunityClick(); - } - }} - /> - ))} - {membersList.length > 0 && - membersList.map((member) => ( - { - setActiveChannel({ - id: member, - name: member.slice(0, 10), - type: "dm", - description: "Contact", - }); - if (onCommunityClick) { - onCommunityClick(); - } - setCreateChat(false); - }} - /> - ))} + + diff --git a/packages/react-chat/src/components/Chat.tsx b/packages/react-chat/src/components/Chat.tsx index d4f2fe06..6fa9a2b6 100644 --- a/packages/react-chat/src/components/Chat.tsx +++ b/packages/react-chat/src/components/Chat.tsx @@ -12,10 +12,18 @@ import { CommunityModal } from "./Modals/CommunityModal"; import { EditModal } from "./Modals/EditModal"; import { ProfileModal } from "./Modals/ProfileModal"; +function Modals() { + return ( + <> + + + + + ); +} + export function Chat() { const [showMembers, setShowMembers] = useState(true); - const [membersList, setMembersList] = useState([]); - const [groupList, setGroupList] = useState([]); const [createChat, setCreateChat] = useState(false); const narrow = useNarrow(); @@ -25,38 +33,19 @@ export function Chat() { {!narrow && ( - + )} - {!createChat && ( setShowMembers(!showMembers)} showMembers={showMembers} - membersList={membersList} - groupList={groupList} - setMembersList={setMembersList} - setGroupList={setGroupList} setCreateChat={setCreateChat} /> )} - {showMembers && !narrow && !createChat && ( - - )} - {createChat && ( - - )} - - - + {showMembers && !narrow && !createChat && } + {createChat && } + ); } diff --git a/packages/react-chat/src/components/Chat/ChatBody.tsx b/packages/react-chat/src/components/Chat/ChatBody.tsx index 60c4f990..f322eeab 100644 --- a/packages/react-chat/src/components/Chat/ChatBody.tsx +++ b/packages/react-chat/src/components/Chat/ChatBody.tsx @@ -27,30 +27,22 @@ enum ChatBodyState { interface ChatBodyProps { onClick: () => void; showMembers: boolean; - membersList: string[]; - groupList: [][]; - setMembersList: any; - setGroupList: any; setCreateChat: (val: boolean) => void; } export function ChatBody({ onClick, showMembers, - membersList, - groupList, - setMembersList, - setGroupList, setCreateChat, }: ChatBodyProps) { const { messenger, activeChannel, communityData } = useMessengerContext(); const narrow = useNarrow(); const [showChannelMenu, setShowChannelMenu] = useState(false); - const [showState, setShowState] = useState(ChatBodyState.Chat); const [editGroup, setEditGroup] = useState(false); const className = useMemo(() => (narrow ? "narrow" : ""), [narrow]); + const [showState, setShowState] = useState(ChatBodyState.Chat); const switchShowState = useCallback( (state: ChatBodyState) => { if (narrow) { @@ -69,12 +61,7 @@ export function ChatBody({ return ( {editGroup && communityData ? ( - + ) : ( switchShowState(ChatBodyState.Members)} setShowChannelMenu={setShowChannelMenu} setEditGroup={setEditGroup} - setGroupList={setGroupList} /> )} @@ -146,8 +132,6 @@ export function ChatBody({ {showState === ChatBodyState.Channels && ( switchShowState(ChatBodyState.Channels)} - membersList={membersList} - groupList={groupList} setCreateChat={setCreateChat} /> )} @@ -156,7 +140,6 @@ export function ChatBody({ switchShowMembersList={() => switchShowState(ChatBodyState.Members) } - setMembersList={setMembersList} /> )} diff --git a/packages/react-chat/src/components/Chat/ChatCreation.tsx b/packages/react-chat/src/components/Chat/ChatCreation.tsx index 51d041b1..57dc1e37 100644 --- a/packages/react-chat/src/components/Chat/ChatCreation.tsx +++ b/packages/react-chat/src/components/Chat/ChatCreation.tsx @@ -10,23 +10,16 @@ import { Member } from "../Members/Member"; import { SearchBlock } from "../SearchBlock"; import { textMediumStyles } from "../Text"; interface ChatCreationProps { - setMembersList: any; - setGroupList: any; setCreateChat: (val: boolean) => void; editGroup?: boolean; } -export function ChatCreation({ - setMembersList, - setGroupList, - setCreateChat, - editGroup, -}: ChatCreationProps) { +export function ChatCreation({ setCreateChat, editGroup }: ChatCreationProps) { const identity = useIdentity(); const [query, setQuery] = useState(""); const [styledGroup, setStyledGroup] = useState([]); - const { contacts, setActiveChannel } = useMessengerContext(); + const { contacts, setChannel } = useMessengerContext(); const addMember = useCallback( (member: string) => { @@ -47,28 +40,17 @@ export function ChatCreation({ const createChat = (group: string[]) => { group.length > 1 - ? (setGroupList((prevGroups: string[][]) => { - prevGroups.push(group); - return prevGroups; - }), - setActiveChannel({ + ? setChannel({ id: group.join(""), name: group.join(", "), type: "group", - })) - : (setMembersList((prevMembers: string[]) => { - if (prevMembers.find((chat) => chat === group[0])) { - return prevMembers; - } else { - return [...prevMembers, group[0]]; - } - }), - setActiveChannel({ + }) + : setChannel({ id: group[0], name: group[0], type: "dm", description: "Contact", - })); + }); setCreateChat(false); }; @@ -112,9 +94,7 @@ export function ChatCreation({ - editGroup ? setMembersList(styledGroup) : createChat(styledGroup) - } + onClick={() => createChat(styledGroup)} > Confirm diff --git a/packages/react-chat/src/components/Form/ChannelMenu.tsx b/packages/react-chat/src/components/Form/ChannelMenu.tsx index 0239db83..e6c2cad5 100644 --- a/packages/react-chat/src/components/Form/ChannelMenu.tsx +++ b/packages/react-chat/src/components/Form/ChannelMenu.tsx @@ -20,7 +20,6 @@ interface ChannelMenuProps { switchMemberList: () => void; setShowChannelMenu: (val: boolean) => void; setEditGroup: (val: boolean) => void; - setGroupList: any; } export const ChannelMenu = ({ @@ -28,11 +27,9 @@ export const ChannelMenu = ({ switchMemberList, setShowChannelMenu, setEditGroup, - setGroupList, }: ChannelMenuProps) => { const narrow = useNarrow(); - const { clearNotifications, setActiveChannel, channels } = - useMessengerContext(); + const { clearNotifications, removeChannel } = useMessengerContext(); const { setModal } = useModal(EditModalName); return ( @@ -77,16 +74,12 @@ export const ChannelMenu = ({ Mark as Read - {channel.type === "group" && ( + {(channel.type === "group" || channel.type === "dm") && ( {" "} { - setGroupList((prevGroups: string[][]) => { - const idx = prevGroups.indexOf(channel.name.split(", ")); - return idx >= 0 ? prevGroups.splice(idx, 1) : []; - }); - setActiveChannel(channels[0]); + removeChannel(channel.id); setShowChannelMenu(false); }} > diff --git a/packages/react-chat/src/components/Members/Member.tsx b/packages/react-chat/src/components/Members/Member.tsx index d3b0dbe9..0e69c37f 100644 --- a/packages/react-chat/src/components/Members/Member.tsx +++ b/packages/react-chat/src/components/Members/Member.tsx @@ -1,6 +1,7 @@ import React, { useState } from "react"; import styled from "styled-components"; +import { useMessengerContext } from "../../contexts/messengerProvider"; import { Contact } from "../../models/Contact"; import { Icon } from "../Chat/ChatMessages"; import { ContactMenu } from "../Form/ContactMenu"; @@ -10,7 +11,6 @@ interface MemberProps { contact: Contact; isOnline?: boolean; switchShowMembers?: () => void; - setMembersList?: any; onClick?: () => void; } @@ -18,24 +18,21 @@ export function Member({ contact, isOnline, switchShowMembers, - setMembersList, onClick, }: MemberProps) { - const startDialog = (member: string) => { - setMembersList((prevMembers: string[]) => { - if (prevMembers.find((chat) => chat === member)) { - return prevMembers; - } else { - return [...prevMembers, member]; - } - }); - }; + const { setChannel } = useMessengerContext(); const [showMenu, setShowMenu] = useState(false); const onMemberClick = () => { switchShowMembers?.(); - startDialog(contact.id); + setChannel({ + id: contact.id, + name: contact.customName ?? contact.trueName, + type: "dm", + description: "DM", + members: [contact], + }); }; return ( diff --git a/packages/react-chat/src/components/Members/Members.tsx b/packages/react-chat/src/components/Members/Members.tsx index 83b59df9..e0ebed8a 100644 --- a/packages/react-chat/src/components/Members/Members.tsx +++ b/packages/react-chat/src/components/Members/Members.tsx @@ -3,15 +3,11 @@ import styled from "styled-components"; import { MembersList } from "./MembersList"; -interface MembersProps { - setMembersList: any; -} - -export function Members({ setMembersList }: MembersProps) { +export function Members() { return ( Members - + ); } diff --git a/packages/react-chat/src/components/Members/MembersList.tsx b/packages/react-chat/src/components/Members/MembersList.tsx index 9b708838..a4b9c867 100644 --- a/packages/react-chat/src/components/Members/MembersList.tsx +++ b/packages/react-chat/src/components/Members/MembersList.tsx @@ -11,13 +11,9 @@ import { Member, MemberData, MemberIcon } from "./Member"; interface MembersListProps { switchShowMembers?: () => void; - setMembersList: any; } -export function MembersList({ - switchShowMembers, - setMembersList, -}: MembersListProps) { +export function MembersList({ switchShowMembers }: MembersListProps) { const { contacts } = useMessengerContext(); const identity = useIdentity(); @@ -43,7 +39,6 @@ export function MembersList({ contact={contact} isOnline={contact.online} switchShowMembers={switchShowMembers} - setMembersList={setMembersList} /> ))} @@ -58,7 +53,6 @@ export function MembersList({ contact={contact} isOnline={contact.online} switchShowMembers={switchShowMembers} - setMembersList={setMembersList} /> ))} diff --git a/packages/react-chat/src/components/Modals/ProfileModal.tsx b/packages/react-chat/src/components/Modals/ProfileModal.tsx index c3d25cce..21a1914b 100644 --- a/packages/react-chat/src/components/Modals/ProfileModal.tsx +++ b/packages/react-chat/src/components/Modals/ProfileModal.tsx @@ -89,7 +89,7 @@ export const ProfileModal = () => { setCustomNameInput(e.currentTarget.value)} /> {contact.customName && ( diff --git a/packages/react-chat/src/components/NarrowMode/NarrowChannels.tsx b/packages/react-chat/src/components/NarrowMode/NarrowChannels.tsx index ca1ec421..b7be4282 100644 --- a/packages/react-chat/src/components/NarrowMode/NarrowChannels.tsx +++ b/packages/react-chat/src/components/NarrowMode/NarrowChannels.tsx @@ -7,15 +7,11 @@ import { NarrowTopbar } from "./NarrowTopbar"; interface NarrowChannelsProps { setShowChannels: (val: boolean) => void; - membersList: string[]; - groupList: string[][]; setCreateChat: (val: boolean) => void; } export function NarrowChannels({ setShowChannels, - membersList, - groupList, setCreateChat, }: NarrowChannelsProps) { return ( @@ -23,8 +19,6 @@ export function NarrowChannels({ setShowChannels(false)} - membersList={membersList} - groupList={groupList} setCreateChat={setCreateChat} /> diff --git a/packages/react-chat/src/components/NarrowMode/NarrowMembers.tsx b/packages/react-chat/src/components/NarrowMode/NarrowMembers.tsx index 24e0007f..8f8666cd 100644 --- a/packages/react-chat/src/components/NarrowMode/NarrowMembers.tsx +++ b/packages/react-chat/src/components/NarrowMode/NarrowMembers.tsx @@ -7,20 +7,13 @@ import { NarrowTopbar } from "./NarrowTopbar"; interface NarrowMembersProps { switchShowMembersList: () => void; - setMembersList: any; } -export function NarrowMembers({ - switchShowMembersList, - setMembersList, -}: NarrowMembersProps) { +export function NarrowMembers({ switchShowMembersList }: NarrowMembersProps) { return ( - + ); } diff --git a/packages/react-chat/src/contexts/messengerProvider.tsx b/packages/react-chat/src/contexts/messengerProvider.tsx index a27fbdbb..94d0509c 100644 --- a/packages/react-chat/src/contexts/messengerProvider.tsx +++ b/packages/react-chat/src/contexts/messengerProvider.tsx @@ -20,7 +20,9 @@ const MessengerContext = createContext({ id: "", name: "", }, - channels: [], + channels: {}, + setChannel: () => undefined, + removeChannel: () => undefined, setActiveChannel: () => undefined, }); diff --git a/packages/react-chat/src/hooks/messenger/useMessenger.ts b/packages/react-chat/src/hooks/messenger/useMessenger.ts index eb52e4f2..f4a5e1bd 100644 --- a/packages/react-chat/src/hooks/messenger/useMessenger.ts +++ b/packages/react-chat/src/hooks/messenger/useMessenger.ts @@ -7,7 +7,7 @@ import { Messenger, } from "status-communities/dist/cjs"; -import { ChannelData } from "../../models/ChannelData"; +import { ChannelData, ChannelsData } from "../../models/ChannelData"; import { ChatMessage } from "../../models/ChatMessage"; import { CommunityData } from "../../models/CommunityData"; import { Contacts } from "../../models/Contact"; @@ -34,7 +34,9 @@ export type MessengerType = { communityData: CommunityData | undefined; contacts: Contacts; setContacts: React.Dispatch>; - channels: ChannelData[]; + channels: ChannelsData; + setChannel: (channel: ChannelData) => void; + removeChannel: (channelId: string) => void; activeChannel: ChannelData; setActiveChannel: (channel: ChannelData) => void; }; @@ -148,24 +150,56 @@ export function useMessenger( [chatId, messenger] ); - const channels = useMemo(() => { + const [channels, setChannels] = useState({}); + + const setChannel = useCallback((channel: ChannelData) => { + setChannels((prev) => { + return { ...prev, [channel.id]: channel }; + }); + setActiveChannel(channel); + }, []); + + const removeChannel = useCallback( + (channelId: string) => { + setChannels((prev) => { + delete prev[channelId]; + return prev; + }); + const newActiveChannel: ChannelData = Object.values(channels)?.[0] ?? { + id: "", + name: "", + }; + setActiveChannel(newActiveChannel); + }, + [channels] + ); + + useEffect(() => { if (community?.chats) { - return Array.from(community.chats.values()).map((chat) => { - return { + for (const chat of community.chats.values()) { + setChannel({ id: chat.id, name: chat.communityChat?.identity?.displayName ?? "", description: chat.communityChat?.identity?.description ?? "", type: "channel", - }; - }); - } else { - return []; + }); + } } }, [community]); useEffect(() => { - if (channels.length > 0) setActiveChannel(channels[0]); - }, [channels]); + Object.values(channels) + .filter((channel) => channel.type === "dm") + .forEach((channel) => { + const contact = contacts?.[channel?.members?.[0]?.id ?? ""]; + if (contact && channel.name !== (contact?.customName ?? channel.name)) { + setChannel({ + ...channel, + name: contact?.customName ?? channel.name, + }); + } + }); + }, [contacts]); const communityData = useMemo(() => { if (community?.description) { @@ -200,6 +234,8 @@ export function useMessenger( contacts, setContacts, channels, + setChannel, + removeChannel, activeChannel, setActiveChannel, mentions, diff --git a/packages/react-chat/src/models/ChannelData.ts b/packages/react-chat/src/models/ChannelData.ts index 3064315d..8617c2df 100644 --- a/packages/react-chat/src/models/ChannelData.ts +++ b/packages/react-chat/src/models/ChannelData.ts @@ -1,3 +1,5 @@ +import { Contact } from "./Contact"; + export type ChannelData = { id: string; name: string; @@ -5,4 +7,9 @@ export type ChannelData = { description?: string; icon?: string; isMuted?: boolean; + members?: Contact[]; +}; + +export type ChannelsData = { + [id: string]: ChannelData; };