Refactor and add replies to group chats (#149)

This commit is contained in:
Szymon Szlachtowicz 2021-12-07 15:26:22 +01:00 committed by GitHub
parent 8b79cf397e
commit 44da36dfdf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 199 additions and 158 deletions

View File

@ -4,22 +4,16 @@ import styled from "styled-components";
import { useMessengerContext } from "../../contexts/messengerProvider";
import { useNarrow } from "../../contexts/narrowProvider";
import { Reply } from "../../hooks/useReply";
import { Channel } from "../Channels/Channel";
import { Community } from "../Community";
import { ChannelMenu } from "../Form/ChannelMenu";
import { MembersIcon } from "../Icons/MembersIcon";
import { MoreIcon } from "../Icons/MoreIcon";
import { NarrowChannels } from "../NarrowMode/NarrowChannels";
import { NarrowMembers } from "../NarrowMode/NarrowMembers";
import { CommunitySkeleton } from "../Skeleton/CommunitySkeleton";
import { Loading } from "../Skeleton/Loading";
import { LoadingSkeleton } from "../Skeleton/LoadingSkeleton";
import { ChatCreation } from "./ChatCreation";
import { ChatInput } from "./ChatInput";
import { ChatMessages } from "./ChatMessages";
import { ChatTopbar } from "./ChatTopbar";
enum ChatBodyState {
export enum ChatBodyState {
Chat,
Channels,
Members,
@ -33,7 +27,6 @@ interface ChatBodyProps {
export function ChatBody({ onClick, showMembers }: ChatBodyProps) {
const { messenger, activeChannel, communityData } = useMessengerContext();
const narrow = useNarrow();
const [showChannelMenu, setShowChannelMenu] = useState(false);
const [editGroup, setEditGroup] = useState(false);
const className = useMemo(() => (narrow ? "narrow" : ""), [narrow]);
@ -65,57 +58,14 @@ export function ChatBody({ onClick, showMembers }: ChatBodyProps) {
/>
) : (
<ChatTopbar
className={narrow && showState !== ChatBodyState.Chat ? "narrow" : ""}
>
<ChannelWrapper className={className}>
{messenger && communityData ? (
<>
{narrow && (
<CommunityWrap className={className}>
<Community />
</CommunityWrap>
)}
<Channel
channel={activeChannel}
isActive={
narrow ? showState === ChatBodyState.Channels : false
}
activeView={true}
onClick={() => switchShowState(ChatBodyState.Channels)}
/>
</>
) : (
<SkeletonWrapper>
<CommunitySkeleton />
</SkeletonWrapper>
)}
</ChannelWrapper>
<MenuWrapper>
{!narrow && (
<MemberBtn
className={className}
onClick={onClick}
className={showMembers ? "active" : ""}
>
<MembersIcon />
</MemberBtn>
)}
<MoreBtn onClick={() => setShowChannelMenu(!showChannelMenu)}>
<MoreIcon />
</MoreBtn>
</MenuWrapper>
{!messenger && !communityData && <Loading />}
{showChannelMenu && (
<ChannelMenu
channel={activeChannel}
switchMemberList={() => switchShowState(ChatBodyState.Members)}
setShowChannelMenu={setShowChannelMenu}
setEditGroup={setEditGroup}
showMembers={showMembers}
showState={showState}
switchShowState={switchShowState}
/>
)}
</ChatTopbar>
)}
{messenger ? (
<>
{showState === ChatBodyState.Chat && (
@ -164,91 +114,3 @@ const ChatBodyWrapper = styled.div`
width: 100%;
}
`;
const ChannelWrapper = styled.div`
display: flex;
align-items: center;
max-width: 85%;
&.narrow {
width: calc(100% - 46px);
}
`;
const SkeletonWrapper = styled.div`
padding: 8px;
`;
const ChatTopbar = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
padding: 5px 8px;
background: ${({ theme }) => theme.bodyBackgroundColor};
position: relative;
&.narrow {
width: 100%;
}
`;
const CommunityWrap = styled.div`
padding-right: 10px;
margin-right: 16px;
position: relative;
&.narrow {
margin-right: 8px;
}
&:after {
content: "";
position: absolute;
right: 0;
top: 50%;
width: 2px;
height: 24px;
transform: translateY(-50%);
border-radius: 1px;
background: ${({ theme }) => theme.primary};
opacity: 0.1;
}
`;
const MenuWrapper = styled.div`
display: flex;
align-items: center;
`;
const MemberBtn = styled.button`
width: 32px;
height: 32px;
border-radius: 8px;
padding: 0;
&:hover {
background: ${({ theme }) => theme.border};
}
&:active,
&.active {
background: ${({ theme }) => theme.inputColor};
}
`;
const MoreBtn = styled.button`
width: 32px;
height: 32px;
border-radius: 8px;
padding: 0;
margin: 0 8px;
&:hover {
background: ${({ theme }) => theme.border};
}
&:active,
&.active {
background: ${({ theme }) => theme.inputColor};
}
`;

View File

@ -79,7 +79,7 @@ export function ChatCreation({
{query && (
<SearchBlock
query={query}
dsicludeList={styledGroup}
discludeList={styledGroup}
onClick={addMember}
/>
)}

View File

@ -284,7 +284,7 @@ export function ChatInput({ reply, setReply }: ChatInputProps) {
{query && (
<SearchBlock
query={query}
dsicludeList={[]}
discludeList={[]}
onClick={addMention}
onBotttom
/>

View File

@ -0,0 +1,173 @@
import React, { useState } from "react";
import styled from "styled-components";
import { useMessengerContext } from "../../contexts/messengerProvider";
import { useNarrow } from "../../contexts/narrowProvider";
import { Channel } from "../Channels/Channel";
import { Community } from "../Community";
import { ChannelMenu } from "../Form/ChannelMenu";
import { MembersIcon } from "../Icons/MembersIcon";
import { MoreIcon } from "../Icons/MoreIcon";
import { CommunitySkeleton } from "../Skeleton/CommunitySkeleton";
import { Loading } from "../Skeleton/Loading";
import { ChatBodyState } from "./ChatBody";
type ChatTopbarProps = {
showState: ChatBodyState;
className: string;
onClick: () => void;
switchShowState: (state: ChatBodyState) => void;
showMembers: boolean;
setEditGroup: React.Dispatch<React.SetStateAction<boolean>>;
};
export function ChatTopbar({
showState,
className,
onClick,
switchShowState,
showMembers,
setEditGroup,
}: ChatTopbarProps) {
const { messenger, activeChannel, communityData } = useMessengerContext();
const narrow = useNarrow();
const [showChannelMenu, setShowChannelMenu] = useState(false);
return (
<Topbar
className={narrow && showState !== ChatBodyState.Chat ? "narrow" : ""}
>
<ChannelWrapper className={className}>
{messenger && communityData ? (
<>
{narrow && (
<CommunityWrap className={className}>
<Community />
</CommunityWrap>
)}
<Channel
channel={activeChannel}
isActive={narrow ? showState === ChatBodyState.Channels : false}
activeView={true}
onClick={() => switchShowState(ChatBodyState.Channels)}
/>
</>
) : (
<SkeletonWrapper>
<CommunitySkeleton />
</SkeletonWrapper>
)}
</ChannelWrapper>
<MenuWrapper>
{!narrow && (
<MemberBtn onClick={onClick} className={showMembers ? "active" : ""}>
<MembersIcon />
</MemberBtn>
)}
<MoreBtn onClick={() => setShowChannelMenu(!showChannelMenu)}>
<MoreIcon />
</MoreBtn>
</MenuWrapper>
{!messenger && !communityData && <Loading />}
{showChannelMenu && (
<ChannelMenu
channel={activeChannel}
switchMemberList={() => switchShowState(ChatBodyState.Members)}
setShowChannelMenu={setShowChannelMenu}
setEditGroup={setEditGroup}
/>
)}
</Topbar>
);
}
const ChannelWrapper = styled.div`
display: flex;
align-items: center;
max-width: 85%;
&.narrow {
width: calc(100% - 46px);
}
`;
const SkeletonWrapper = styled.div`
padding: 8px;
`;
const Topbar = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
padding: 5px 8px;
background: ${({ theme }) => theme.bodyBackgroundColor};
position: relative;
&.narrow {
width: 100%;
}
`;
const CommunityWrap = styled.div`
padding-right: 10px;
margin-right: 16px;
position: relative;
&.narrow {
margin-right: 8px;
}
&:after {
content: "";
position: absolute;
right: 0;
top: 50%;
width: 2px;
height: 24px;
transform: translateY(-50%);
border-radius: 1px;
background: ${({ theme }) => theme.primary};
opacity: 0.1;
}
`;
const MenuWrapper = styled.div`
display: flex;
align-items: center;
`;
const MemberBtn = styled.button`
width: 32px;
height: 32px;
border-radius: 8px;
padding: 0;
&:hover {
background: ${({ theme }) => theme.border};
}
&:active,
&.active {
background: ${({ theme }) => theme.inputColor};
}
`;
const MoreBtn = styled.button`
width: 32px;
height: 32px;
border-radius: 8px;
padding: 0;
margin: 0 8px;
&:hover {
background: ${({ theme }) => theme.border};
}
&:active,
&.active {
background: ${({ theme }) => theme.inputColor};
}
`;

View File

@ -8,14 +8,14 @@ import { Member } from "./Members/Member";
interface SearchBlockProps {
query: string;
dsicludeList: string[];
discludeList: string[];
onClick: (member: string) => void;
onBotttom?: boolean;
}
export const SearchBlock = ({
query,
dsicludeList,
discludeList,
onClick,
onBotttom,
}: SearchBlockProps) => {
@ -24,8 +24,8 @@ export const SearchBlock = ({
const searchList = useMemo(() => {
return Object.values(contacts)
.filter((member) => member.id.includes(query))
.filter((member) => !dsicludeList.includes(member.id));
}, [query, dsicludeList, contacts]);
.filter((member) => !discludeList.includes(member.id));
}, [query, discludeList, contacts]);
if (searchList.length === 0) {
return null;
@ -37,7 +37,7 @@ export const SearchBlock = ({
<ContactsList>
{Object.values(contacts)
.filter((member) => member.id.includes(query))
.filter((member) => !dsicludeList.includes(member.id))
.filter((member) => !discludeList.includes(member.id))
.map((member) => (
<Member
key={member.id}

View File

@ -65,7 +65,8 @@ export function useGroupChats(
msg.text ?? "",
new Date(msg.clock ?? 0),
sender,
image
image,
msg.responseTo
),
msg.chatId
);

View File

@ -217,7 +217,7 @@ export function useMessenger(
}
if (content) {
if (activeChannel.type === "group") {
await groupChat?.sendMessage(activeChannel.id, content);
await groupChat?.sendMessage(activeChannel.id, content, responseTo);
} else {
await messenger?.sendMessage(activeChannel.id, content, responseTo);
}

View File

@ -68,7 +68,11 @@ export class GroupChats {
*
* @param text text message to send
*/
public async sendMessage(chatId: string, content: Content): Promise<void> {
public async sendMessage(
chatId: string,
content: Content,
responseTo?: string
): Promise<void> {
const now = Date.now();
const chat = this.chats[chatId];
if (chat) {
@ -78,7 +82,8 @@ export class GroupChats {
now,
now,
chatId,
content
content,
responseTo
);
const wakuMessage = await WakuMessage.fromBytes(
chatMessage.encode(),