Extract channel component (#27)
This commit is contained in:
parent
f0dec3d5af
commit
e4710c3445
|
@ -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>`
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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,30 +15,41 @@ 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}>
|
||||
<ChannelWrapper>
|
||||
<Channel
|
||||
channel={channel}
|
||||
theme={theme}
|
||||
isActive={true}
|
||||
activeView={true}
|
||||
isMuted={false}
|
||||
/>
|
||||
<ChatTopbar>
|
||||
<ChannelWrapper>
|
||||
{showCommunity && (
|
||||
<CommunityWrap theme={theme}>
|
||||
<Community community={community} theme={theme} />
|
||||
</CommunityWrap>
|
||||
)}
|
||||
<Channel
|
||||
channel={channel}
|
||||
theme={theme}
|
||||
isActive={true}
|
||||
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;
|
||||
|
|
|
@ -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};
|
||||
`;
|
|
@ -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",
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
};
|
Loading…
Reference in New Issue