Add icons (#19)

This commit is contained in:
Maria Rushkova 2021-09-30 08:35:53 +02:00 committed by GitHub
parent c07d912c39
commit e379aeca84
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 159 additions and 6 deletions

View File

@ -4,6 +4,8 @@ import styled from "styled-components";
import { ChannelData, channels } from "../helpers/channelsMock"; import { ChannelData, channels } from "../helpers/channelsMock";
import { Theme } from "../styles/themes"; import { Theme } from "../styles/themes";
import { MutedIcon } from "./Icons/MutedIcon";
interface ChannelsProps { interface ChannelsProps {
theme: Theme; theme: Theme;
icon: string; icon: string;
@ -50,6 +52,7 @@ export function Channels({
channel={channel} channel={channel}
theme={theme} theme={theme}
isActive={channel.id === activeChannelId} isActive={channel.id === activeChannelId}
isMuted={channel.isMuted || false}
notification={ notification={
notifications[channel.name] > 0 notifications[channel.name] > 0
? notifications[channel.name] ? notifications[channel.name]
@ -70,6 +73,7 @@ interface ChannelProps {
channel: ChannelData; channel: ChannelData;
notification?: number; notification?: number;
isActive: boolean; isActive: boolean;
isMuted: boolean;
activeView?: boolean; activeView?: boolean;
onClick?: () => void; onClick?: () => void;
} }
@ -78,6 +82,7 @@ export function Channel({
theme, theme,
channel, channel,
isActive, isActive,
isMuted,
activeView, activeView,
onClick, onClick,
notification, notification,
@ -106,6 +111,8 @@ export function Channel({
? "active" ? "active"
: notification && notification > 0 : notification && notification > 0
? "notified" ? "notified"
: isMuted
? "muted"
: "" : ""
} }
> >
@ -122,6 +129,7 @@ export function Channel({
{notification && notification > 0 && !activeView && ( {notification && notification > 0 && !activeView && (
<NotificationBagde theme={theme}>{notification}</NotificationBagde> <NotificationBagde theme={theme}>{notification}</NotificationBagde>
)} )}
{isMuted && !notification && <MutedIcon theme={theme} />}
</ChannelWrapper> </ChannelWrapper>
); );
} }

View File

@ -12,11 +12,12 @@ import { Members } from "./Members";
interface ChatProps { interface ChatProps {
theme: Theme; theme: Theme;
channelsON?: boolean; channelsON?: boolean;
membersON?: boolean;
} }
export function Chat({ theme, channelsON, membersON }: ChatProps) { export function Chat({ theme, channelsON }: ChatProps) {
const [activeChannel, setActiveChannel] = useState<ChannelData>(channels[0]); const [activeChannel, setActiveChannel] = useState<ChannelData>(channels[0]);
const [showMembers, setShowMembers] = useState(true);
const { const {
messenger, messenger,
messages, messages,
@ -48,11 +49,13 @@ export function Chat({ theme, channelsON, membersON }: ChatProps) {
channel={activeChannel} channel={activeChannel}
messages={messages} messages={messages}
sendMessage={sendMessage} sendMessage={sendMessage}
onClick={() => setShowMembers(!showMembers)}
showMembers={showMembers}
/> />
) : ( ) : (
<Loading>Connecting to waku</Loading> <Loading>Connecting to waku</Loading>
)} )}
{membersON && <Members theme={theme} />} {showMembers && <Members theme={theme} />}
</ChatWrapper> </ChatWrapper>
); );
} }

View File

@ -5,6 +5,7 @@ import { ChannelData } from "../../helpers/channelsMock";
import { ChatMessage } from "../../models/ChatMessage"; import { ChatMessage } from "../../models/ChatMessage";
import { Theme } from "../../styles/themes"; import { Theme } from "../../styles/themes";
import { Channel } from "../Channels"; import { Channel } from "../Channels";
import { MembersIcon } from "../Icons/MembersIcon";
import { ChatInput } from "./ChatInput"; import { ChatInput } from "./ChatInput";
import { ChatMessages } from "./ChatMessages"; import { ChatMessages } from "./ChatMessages";
@ -14,6 +15,8 @@ interface ChatBodyProps {
channel: ChannelData; channel: ChannelData;
messages: ChatMessage[]; messages: ChatMessage[];
sendMessage: (text: string) => void; sendMessage: (text: string) => void;
onClick: () => void;
showMembers: boolean;
} }
export function ChatBody({ export function ChatBody({
@ -21,6 +24,8 @@ export function ChatBody({
channel, channel,
messages, messages,
sendMessage, sendMessage,
onClick,
showMembers,
}: ChatBodyProps) { }: ChatBodyProps) {
return ( return (
<ChatBodyWrapper theme={theme}> <ChatBodyWrapper theme={theme}>
@ -30,7 +35,15 @@ export function ChatBody({
theme={theme} theme={theme}
isActive={true} isActive={true}
activeView={true} activeView={true}
isMuted={false}
/> />
<MemberBtn
onClick={onClick}
className={showMembers ? "active" : ""}
theme={theme}
>
<MembersIcon theme={theme} />
</MemberBtn>
</ChannelWrapper> </ChannelWrapper>
<ChatMessages messages={messages} theme={theme} /> <ChatMessages messages={messages} theme={theme} />
<ChatInput theme={theme} addMessage={sendMessage} /> <ChatInput theme={theme} addMessage={sendMessage} />
@ -50,5 +63,19 @@ const ChatBodyWrapper = styled.div<ThemeProps>`
`; `;
const ChannelWrapper = styled.div` const ChannelWrapper = styled.div`
padding-left: 8px; display: flex;
justify-content: space-between;
padding: 0 8px;
`;
const MemberBtn = styled.button<ThemeProps>`
width: 32px;
height: 32px;
border-radius: 8px;
padding: 0;
margin-top: 12px;
&.active {
background: ${({ theme }) => theme.inputColor};
}
`; `;

View File

@ -3,6 +3,7 @@ import styled from "styled-components";
import { ChatMessage } from "../../models/ChatMessage"; import { ChatMessage } from "../../models/ChatMessage";
import { Theme } from "../../styles/themes"; import { Theme } from "../../styles/themes";
import { UserIcon } from "../Icons/UserIcon";
type ChatMessagesProps = { type ChatMessagesProps = {
messages: ChatMessage[]; messages: ChatMessage[];
@ -21,7 +22,10 @@ export function ChatMessages({ messages, theme }: ChatMessagesProps) {
<MessagesWrapper ref={ref}> <MessagesWrapper ref={ref}>
{messages.map((message, idx) => ( {messages.map((message, idx) => (
<MessageWrapper key={idx}> <MessageWrapper key={idx}>
<Icon /> <Icon>
<UserIcon theme={theme} />
</Icon>
<ContentWrapper> <ContentWrapper>
<MessageHeaderWrapper> <MessageHeaderWrapper>
<UserNameWrapper theme={theme}> <UserNameWrapper theme={theme}>
@ -71,6 +75,9 @@ const MessageHeaderWrapper = styled.div`
const Icon = styled.div` const Icon = styled.div`
width: 40px; width: 40px;
height: 40px; height: 40px;
display: flex;
justify-content: center;
align-items: end;
border-radius: 50%; border-radius: 50%;
background-color: #bcbdff; background-color: #bcbdff;
`; `;

View File

@ -0,0 +1,33 @@
import React from "react";
import styled from "styled-components";
import { Theme } from "../../styles/themes";
interface ThemeProps {
theme: Theme;
}
export const MembersIcon = ({ theme }: ThemeProps) => {
return (
<Icon
width="32"
height="32"
viewBox="0 0 32 32"
xmlns="http://www.w3.org/2000/svg"
theme={theme}
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M18.2516 16.4656C18.4937 16.3433 18.7935 16.407 18.9707 16.6123C19.7042 17.4621 20.7893 18 22 18C24.2091 18 26 16.2091 26 14C26 11.7909 24.2091 10 22 10C21.7062 10 21.4199 10.0317 21.1441 10.0918C20.8792 10.1495 20.6011 10.0209 20.4804 9.77808C19.6623 8.13156 17.9633 7 16 7C14.0367 7 12.3377 8.13156 11.5196 9.77808C11.3989 10.0209 11.1208 10.1495 10.8559 10.0918C10.5801 10.0317 10.2938 10 10 10C7.79086 10 6 11.7909 6 14C6 16.2091 7.79086 18 10 18C11.2107 18 12.2957 17.4621 13.0293 16.6123C13.2065 16.407 13.5063 16.3433 13.7484 16.4656C14.4251 16.8074 15.1901 17 16 17C16.8099 17 17.5749 16.8074 18.2516 16.4656ZM19.5 12C19.5 13.933 17.933 15.5 16 15.5C14.067 15.5 12.5 13.933 12.5 12C12.5 10.067 14.067 8.5 16 8.5C17.933 8.5 19.5 10.067 19.5 12ZM20.0355 14.9526C19.912 15.1212 19.8848 15.3495 20.0116 15.5156C20.4684 16.114 21.1891 16.5 22 16.5C23.3807 16.5 24.5 15.3807 24.5 14C24.5 12.6193 23.3807 11.5 22 11.5C21.7431 11.5 21.4953 11.5387 21.262 11.6107C21.0961 11.6619 21 11.8264 21 12C21 13.1044 20.6419 14.1252 20.0355 14.9526ZM10.738 11.6107C10.5047 11.5387 10.2569 11.5 10 11.5C8.61929 11.5 7.5 12.6193 7.5 14C7.5 15.3807 8.61929 16.5 10 16.5C10.8109 16.5 11.5316 16.1139 11.9884 15.5156C12.1151 15.3495 12.088 15.1212 11.9645 14.9526C11.3581 14.1252 11 13.1044 11 12C11 11.8264 10.9039 11.6619 10.738 11.6107Z"
/>
<path d="M9.14735 25.0368C9.53098 25.1327 9.91944 24.9141 10.0836 24.5543C11.1079 22.3099 13.3718 20.75 16 20.75C18.6684 20.75 20.9613 22.3579 21.9625 24.6577C22.1289 25.0398 22.5478 25.2663 22.9456 25.142C23.3386 25.0192 23.5622 24.6006 23.4061 24.2196C22.2119 21.3039 19.3458 19.25 16 19.25C12.704 19.25 9.8736 21.2432 8.64834 24.0901C8.47629 24.4898 8.72515 24.9313 9.14735 25.0368Z" />
</Icon>
);
};
const Icon = styled.svg<ThemeProps>`
& > path {
fill: ${({ theme }) => theme.textPrimaryColor};
}
`;

View File

@ -0,0 +1,35 @@
import React from "react";
import styled from "styled-components";
import { Theme } from "../../styles/themes";
interface ThemeProps {
theme: Theme;
}
export const MutedIcon = ({ theme }: ThemeProps) => {
return (
<Icon
width="14"
height="14"
viewBox="0 0 14 14"
xmlns="http://www.w3.org/2000/svg"
theme={theme}
>
<path
d="M8.70186 2.11736C8.91545 1.90377 8.89277 1.54794 8.62625 1.40578C8.13934 1.14607 7.58479 0.999998 7.00002 0.999998C5.27863 0.999998 3.8192 2.26576 3.57576 3.96984L3.14144 7.01005C3.11619 7.18684 3.43245 7.38677 3.55873 7.26049L8.70186 2.11736Z"
fillOpacity="0.2"
/>
<path
d="M0.952001 11.9879C0.676901 12.282 0.68279 12.7434 0.969669 13.0303C1.26256 13.3232 1.73744 13.3232 2.03033 13.0303L3.91421 11.1464C4.00798 11.0527 4.13516 11 4.26777 11H4.5C4.77614 11 4.99359 11.2273 5.06171 11.4949C5.28197 12.3601 6.06626 13 7 13C7.93374 13 8.71803 12.3601 8.93829 11.4949C9.00641 11.2273 9.22386 11 9.5 11H11.5858C12.4767 11 12.9229 9.92286 12.2929 9.29289L11.7071 8.7071C11.2481 8.24811 10.9504 7.65264 10.8586 7.01005L10.543 4.80054C10.5207 4.64475 10.5731 4.48756 10.6844 4.37628L13.0303 2.03033C13.3232 1.73744 13.3232 1.26256 13.0303 0.969668C12.7435 0.682807 12.282 0.676903 11.988 0.951949C11.9822 0.958112 11.9763 0.964201 11.9703 0.970214L0.970328 11.9702C0.964295 11.9762 0.958185 11.9822 0.952001 11.9879Z"
fillOpacity="0.2"
/>
</Icon>
);
};
const Icon = styled.svg<ThemeProps>`
& > path {
fill: ${({ theme }) => theme.textPrimaryColor};
}
`;

View File

@ -0,0 +1,35 @@
import React from "react";
import styled from "styled-components";
import { Theme } from "../../styles/themes";
interface ThemeProps {
theme: Theme;
}
export const UserIcon = ({ theme }: ThemeProps) => {
return (
<Icon
width="34"
height="34"
viewBox="0 0 34 34"
fill="none"
xmlns="http://www.w3.org/2000/svg"
theme={theme}
>
<ellipse cx="17" cy="10.3883" rx="6.94445" ry="6.94445" />
<path
fillRule="evenodd"
clipRule="evenodd"
d="M6.14814 30.8957C4.70584 30.0257 4.143 28.2122 4.92859 26.7222C7.3653 22.1006 11.8615 19 17.005 19C22.1956 19 26.7268 22.1576 29.1477 26.8493C29.9221 28.3501 29.3384 30.163 27.8819 31.0177C24.6426 32.9186 20.9805 33.9995 17.1067 33.9995C13.1509 33.9995 9.42482 32.8723 6.14814 30.8957Z"
/>
</Icon>
);
};
const Icon = styled.svg<ThemeProps>`
& > path,
& > ellipse {
fill: ${({ theme }) => theme.iconUserColor};
}
`;

View File

@ -9,7 +9,7 @@ export function ReactChat() {
return ( return (
<div> <div>
<GlobalStyle /> <GlobalStyle />
<Chat channelsON={true} membersON={true} theme={lightTheme} /> <Chat channelsON={true} theme={lightTheme} />
</div> </div>
); );
} }

View File

@ -4,6 +4,7 @@ export type ChannelData = {
icon?: string; icon?: string;
members: number; members: number;
notifications?: number; notifications?: number;
isMuted?: boolean;
}; };
export const channels = [ export const channels = [
@ -28,5 +29,6 @@ export const channels = [
id: 4, id: 4,
name: "random", name: "random",
members: 6, members: 6,
isMuted: true,
}, },
]; ];

View File

@ -6,6 +6,7 @@ export type Theme = {
memberNameColor: string; memberNameColor: string;
guestNameColor: string; guestNameColor: string;
iconColor: string; iconColor: string;
iconUserColor: string;
iconTextColor: string; iconTextColor: string;
activeChannelBackground: string; activeChannelBackground: string;
notificationColor: string; notificationColor: string;
@ -20,6 +21,7 @@ export const lightTheme: Theme = {
memberNameColor: "#4360DF", memberNameColor: "#4360DF",
guestNameColor: "#887AF9", guestNameColor: "#887AF9",
iconColor: "#D37EF4", iconColor: "#D37EF4",
iconUserColor: "#717199",
iconTextColor: "rgba(255, 255, 255, 0.7)", iconTextColor: "rgba(255, 255, 255, 0.7)",
activeChannelBackground: "#E9EDF1", activeChannelBackground: "#E9EDF1",
notificationColor: "#4360DF", notificationColor: "#4360DF",
@ -34,6 +36,7 @@ export const darkTheme: Theme = {
memberNameColor: "#88B0FF", memberNameColor: "#88B0FF",
guestNameColor: "#887AF9", guestNameColor: "#887AF9",
iconColor: "#D37EF4", iconColor: "#D37EF4",
iconUserColor: "#717199",
iconTextColor: "rgba(0, 0, 0, 0.7)", iconTextColor: "rgba(0, 0, 0, 0.7)",
activeChannelBackground: "#2C2C2C", activeChannelBackground: "#2C2C2C",
notificationColor: "#887AF9", notificationColor: "#887AF9",