Extract channel component (#27)

This commit is contained in:
Maria Rushkova 2021-10-01 14:50:20 +02:00 committed by GitHub
parent f0dec3d5af
commit e4710c3445
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 153 additions and 66 deletions

View File

@ -2,26 +2,25 @@ import React, { useEffect } from "react";
import styled from "styled-components";
import { ChannelData, channels } from "../helpers/channelsMock";
import { CommunityData } from "../helpers/communityMock";
import { Theme } from "../styles/themes";
import { Community, MembersAmount } from "./Community";
import { MutedIcon } from "./Icons/MutedIcon";
interface ChannelsProps {
theme: Theme;
icon: string;
name: string;
community: CommunityData;
notifications: { [id: string]: number };
clearNotifications: (id: string) => void;
members: number;
setActiveChannel: (val: ChannelData) => void;
activeChannelId: number;
}
export function Channels({
theme,
icon,
name,
members,
community,
notifications,
setActiveChannel,
clearNotifications,
@ -38,13 +37,7 @@ export function Channels({
return (
<ChannelsWrapper theme={theme}>
<Community>
<CommunityLogo src={icon} alt={`${name} logo`} />
<CommunityInfo>
<CommunityName theme={theme}>{name}</CommunityName>
<MembersAmount theme={theme}>{members} members</MembersAmount>
</CommunityInfo>
</Community>
<Community community={community} theme={theme} />
<ChannelList>
{channels.map((channel) => (
<Channel
@ -146,41 +139,10 @@ const ChannelsWrapper = styled.div<ThemeProps>`
flex-direction: column;
`;
const Community = styled.div`
display: flex;
margin-bottom: 16px;
`;
const CommunityLogo = styled.img`
width: 36px;
height: 36px;
border-radius: 50%;
margin-left: 10px;
`;
const CommunityInfo = styled.div`
display: flex;
flex-direction: column;
margin-left: 8px;
`;
const CommunityName = styled.h1<ThemeProps>`
font-weight: 500;
font-size: 15px;
line-height: 22px;
color: ${({ theme }) => theme.textPrimaryColor};
`;
const MembersAmount = styled.p<ThemeProps>`
font-size: 12px;
line-height: 16px;
letter-spacing: 0.1px;
color: ${({ theme }) => theme.textSecondaryColor};
`;
const ChannelList = styled.div`
display: flex;
flex-direction: column;
margin-top: 16px;
`;
const ChannelWrapper = styled.div<ThemeProps>`

View File

@ -2,6 +2,7 @@ import React, { useState } from "react";
import styled from "styled-components";
import { ChannelData, channels } from "../helpers/channelsMock";
import { CommunityData } from "../helpers/communityMock";
import { useMessenger } from "../hooks/useMessenger";
import { Theme } from "../styles/themes";
@ -11,12 +12,13 @@ import { Members } from "./Members";
interface ChatProps {
theme: Theme;
channelsON?: boolean;
community: CommunityData;
}
export function Chat({ theme, channelsON }: ChatProps) {
export function Chat({ theme, community }: ChatProps) {
const [activeChannel, setActiveChannel] = useState<ChannelData>(channels[0]);
const [showMembers, setShowMembers] = useState(true);
const [showChannels, setShowChannels] = useState(false);
const {
messenger,
@ -31,14 +33,12 @@ export function Chat({ theme, channelsON }: ChatProps) {
return (
<ChatWrapper>
{channelsON && (
{showChannels && (
<Channels
notifications={notifications}
clearNotifications={clearNotifications}
theme={theme}
icon={"https://www.cryptokitties.co/icons/logo.svg"}
name={"CryptoKitties"}
members={186}
community={community}
setActiveChannel={setActiveChannel}
activeChannelId={activeChannel.id}
/>
@ -51,11 +51,19 @@ export function Chat({ theme, channelsON }: ChatProps) {
sendMessage={sendMessage}
onClick={() => setShowMembers(!showMembers)}
showMembers={showMembers}
community={community}
showCommunity={!showChannels}
/>
) : (
<Loading>Connecting to waku</Loading>
)}
{showMembers && <Members theme={theme} channel={activeChannel} />}
{showMembers && (
<Members
theme={theme}
channel={activeChannel}
setShowChannels={setShowChannels}
/>
)}
</ChatWrapper>
);
}

View File

@ -2,9 +2,11 @@ import React from "react";
import styled from "styled-components";
import { ChannelData } from "../../helpers/channelsMock";
import { CommunityData } from "../../helpers/communityMock";
import { ChatMessage } from "../../models/ChatMessage";
import { Theme } from "../../styles/themes";
import { Channel } from "../Channels";
import { Community } from "../Community";
import { MembersIcon } from "../Icons/MembersIcon";
import { ChatInput } from "./ChatInput";
@ -13,23 +15,33 @@ import { ChatMessages } from "./ChatMessages";
interface ChatBodyProps {
theme: Theme;
channel: ChannelData;
community: CommunityData;
messages: ChatMessage[];
sendMessage: (text: string) => void;
onClick: () => void;
showMembers: boolean;
showCommunity: boolean;
}
export function ChatBody({
theme,
channel,
community,
messages,
sendMessage,
onClick,
showMembers,
showCommunity,
}: ChatBodyProps) {
return (
<ChatBodyWrapper theme={theme}>
<ChatTopbar>
<ChannelWrapper>
{showCommunity && (
<CommunityWrap theme={theme}>
<Community community={community} theme={theme} />
</CommunityWrap>
)}
<Channel
channel={channel}
theme={theme}
@ -37,6 +49,7 @@ export function ChatBody({
activeView={true}
isMuted={false}
/>
</ChannelWrapper>
<MemberBtn
onClick={onClick}
className={showMembers ? "active" : ""}
@ -44,7 +57,7 @@ export function ChatBody({
>
<MembersIcon theme={theme} />
</MemberBtn>
</ChannelWrapper>
</ChatTopbar>
<ChatMessages messages={messages} theme={theme} />
<ChatInput theme={theme} addMessage={sendMessage} />
</ChatBodyWrapper>
@ -59,15 +72,39 @@ const ChatBodyWrapper = styled.div<ThemeProps>`
flex-direction: column;
flex: 1;
height: 100%;
background: ${({ theme }) => theme.bodyBackgroundColor};
background: ${({ theme }) => theme.textPrimaryColor};
`;
const ChannelWrapper = styled.div`
display: flex;
align-items: center;
`;
const ChatTopbar = styled.div`
display: flex;
justify-content: space-between;
padding: 0 8px;
`;
const CommunityWrap = styled.div<ThemeProps>`
padding-right: 16px;
margin-right: 16px;
position: relative;
&:after {
content: "";
position: absolute;
right: 0;
top: 50%;
width: 2px;
height: 24px;
transform: translateY(-50%);
border-radius: 1px;
background: ${({ theme }) => theme.bodyBackgroundColor};
opacity: 0.1;
}
`;
const MemberBtn = styled.button<ThemeProps>`
width: 32px;
height: 32px;

View File

@ -0,0 +1,57 @@
import React from "react";
import styled from "styled-components";
import { CommunityData } from "../helpers/communityMock";
import { Theme } from "../styles/themes";
interface CommunityProps {
theme: Theme;
community: CommunityData;
}
export function Community({ theme, community }: CommunityProps) {
return (
<CommunityWrap>
<CommunityLogo src={community.icon} alt={`${community.name} logo`} />
<CommunityInfo>
<CommunityName theme={theme}>{community.name}</CommunityName>
<MembersAmount theme={theme}>{community.members} members</MembersAmount>
</CommunityInfo>
</CommunityWrap>
);
}
interface ThemeProps {
theme: Theme;
}
const CommunityWrap = styled.div`
display: flex;
`;
const CommunityLogo = styled.img`
width: 36px;
height: 36px;
border-radius: 50%;
margin-left: 10px;
`;
const CommunityInfo = styled.div`
display: flex;
flex-direction: column;
margin-left: 8px;
`;
const CommunityName = styled.h1<ThemeProps>`
font-weight: 500;
font-size: 15px;
line-height: 22px;
color: ${({ theme }) => theme.textPrimaryColor};
`;
export const MembersAmount = styled.p<ThemeProps>`
font-size: 12px;
line-height: 16px;
letter-spacing: 0.1px;
color: ${({ theme }) => theme.textSecondaryColor};
`;

View File

@ -10,9 +10,10 @@ import { UserIcon } from "./Icons/UserIcon";
interface MembersProps {
theme: Theme;
channel: ChannelData;
setShowChannels: (val: boolean) => void;
}
export function Members({ theme, channel }: MembersProps) {
export function Members({ theme, channel, setShowChannels }: MembersProps) {
return (
<MembersWrapper theme={theme}>
<MemberHeading theme={theme}>Members</MemberHeading>
@ -36,6 +37,7 @@ export function Members({ theme, channel }: MembersProps) {
theme={theme}
member={member}
isOnline={member.isOnline}
setShowChannels={setShowChannels}
/>
))}
</MemberCategory>
@ -49,6 +51,7 @@ export function Members({ theme, channel }: MembersProps) {
theme={theme}
member={member}
isOnline={member.isOnline}
setShowChannels={setShowChannels}
/>
))}
</MemberCategory>
@ -61,11 +64,17 @@ interface MemberProps {
theme: Theme;
member: any;
isOnline: boolean;
setShowChannels: (val: boolean) => void;
}
export function Member({ theme, member, isOnline }: MemberProps) {
export function Member({
theme,
member,
isOnline,
setShowChannels,
}: MemberProps) {
return (
<MemberData>
<MemberData onClick={() => setShowChannels(true)}>
<MemberIcon
style={{
backgroundImage: member.avatar ? `url(${member.avatar})` : "unset",

View File

@ -1,5 +1,6 @@
import React from "react";
import { community } from "../helpers/communityMock";
import { GlobalStyle } from "../styles/GlobalStyle";
import { lightTheme } from "../styles/themes";
@ -9,7 +10,7 @@ export function ReactChat() {
return (
<div>
<GlobalStyle />
<Chat channelsON={true} theme={lightTheme} />
<Chat theme={lightTheme} community={community} />
</div>
);
}

View File

@ -0,0 +1,13 @@
export type CommunityData = {
id: number;
name: string;
icon: string;
members: number;
};
export const community = {
id: 1,
name: "CryptoKitties",
icon: "https://www.cryptokitties.co/icons/logo.svg",
members: 186,
};