Add theme Provider (#53)

This commit is contained in:
Maria Rushkova 2021-10-08 10:16:49 +02:00 committed by GitHub
parent 02647e967d
commit 5ffd8a537d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 163 additions and 385 deletions

View File

@ -1,8 +1,6 @@
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import styled from "styled-components"; import styled from "styled-components";
import { Theme } from "../../styles/themes";
const userAgent = window.navigator.userAgent; const userAgent = window.navigator.userAgent;
const platform = window.navigator.platform; const platform = window.navigator.platform;
const macosPlatforms = ["Macintosh", "MacIntel", "MacPPC", "Mac68K"]; const macosPlatforms = ["Macintosh", "MacIntel", "MacPPC", "Mac68K"];
@ -10,11 +8,10 @@ const windowsPlatforms = ["Win32", "Win64", "Windows", "WinCE"];
const iosPlatforms = ["iPhone", "iPad", "iPod"]; const iosPlatforms = ["iPhone", "iPad", "iPod"];
interface DownloadButtonProps { interface DownloadButtonProps {
theme: Theme;
className?: string; className?: string;
} }
export const DownloadButton = ({ theme, className }: DownloadButtonProps) => { export const DownloadButton = ({ className }: DownloadButtonProps) => {
const [link, setlink] = useState("https://status.im/get/"); const [link, setlink] = useState("https://status.im/get/");
const [os, setOs] = useState<string | null>(null); const [os, setOs] = useState<string | null>(null);
@ -51,7 +48,6 @@ export const DownloadButton = ({ theme, className }: DownloadButtonProps) => {
<Link <Link
className={className} className={className}
href={link} href={link}
theme={theme}
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
> >

View File

@ -4,14 +4,12 @@ import styled from "styled-components";
import { useNarrow } from "../contexts/narrowProvider"; import { useNarrow } from "../contexts/narrowProvider";
import { ChannelData, channels } from "../helpers/channelsMock"; import { ChannelData, channels } from "../helpers/channelsMock";
import { CommunityData } from "../helpers/communityMock"; import { CommunityData } from "../helpers/communityMock";
import { Theme } from "../styles/themes";
import { Community } from "./Community"; import { Community } from "./Community";
import { MutedIcon } from "./Icons/MutedIcon"; import { MutedIcon } from "./Icons/MutedIcon";
import { textMediumStyles } from "./Text"; import { textMediumStyles } from "./Text";
interface ChannelsProps { interface ChannelsProps {
theme: Theme;
community: CommunityData; community: CommunityData;
notifications: { [id: string]: number }; notifications: { [id: string]: number };
clearNotifications: (id: string) => void; clearNotifications: (id: string) => void;
@ -21,7 +19,6 @@ interface ChannelsProps {
} }
export function Channels({ export function Channels({
theme,
community, community,
notifications, notifications,
setActiveChannel, setActiveChannel,
@ -39,18 +36,13 @@ export function Channels({
}, [notifications, activeChannelId]); }, [notifications, activeChannelId]);
return ( return (
<ChannelsWrapper theme={theme}> <ChannelsWrapper>
<StyledCommunity <StyledCommunity onClick={onCommunityClick} community={community} />
onClick={onCommunityClick}
theme={theme}
community={community}
/>
<ChannelList> <ChannelList>
{channels.map((channel) => ( {channels.map((channel) => (
<Channel <Channel
key={channel.id} key={channel.id}
channel={channel} channel={channel}
theme={theme}
isActive={channel.id === activeChannelId} isActive={channel.id === activeChannelId}
isMuted={channel.isMuted || false} isMuted={channel.isMuted || false}
notification={ notification={
@ -69,7 +61,6 @@ export function Channels({
} }
interface ChannelProps { interface ChannelProps {
theme: Theme;
channel: ChannelData; channel: ChannelData;
notification?: number; notification?: number;
isActive: boolean; isActive: boolean;
@ -79,7 +70,6 @@ interface ChannelProps {
} }
export function Channel({ export function Channel({
theme,
channel, channel,
isActive, isActive,
isMuted, isMuted,
@ -99,7 +89,6 @@ export function Channel({
(isActive && !activeView) || (isActive && narrow) ? "active" : "" (isActive && !activeView) || (isActive && narrow) ? "active" : ""
} }
style={{ width: narrow && activeView ? "calc(100% - 162px)" : "100%" }} style={{ width: narrow && activeView ? "calc(100% - 162px)" : "100%" }}
theme={theme}
onClick={onClick} onClick={onClick}
> >
<ChannelInfo> <ChannelInfo>
@ -108,13 +97,11 @@ export function Channel({
backgroundImage: channel.icon ? `url(${channel.icon}` : "", backgroundImage: channel.icon ? `url(${channel.icon}` : "",
}} }}
className={className} className={className}
theme={theme}
> >
{!channel.icon && channel.name.slice(0, 1).toUpperCase()} {!channel.icon && channel.name.slice(0, 1).toUpperCase()}
</ChannelLogo> </ChannelLogo>
<ChannelTextInfo> <ChannelTextInfo>
<ChannelName <ChannelName
theme={theme}
className={ className={
isActive || narrow isActive || narrow
? "active" ? "active"
@ -128,25 +115,19 @@ export function Channel({
# {channel.name} # {channel.name}
</ChannelName> </ChannelName>
{activeView && ( {activeView && (
<ChannelDescription theme={theme}> <ChannelDescription> {channel.description}</ChannelDescription>
{" "}
{channel.description}
</ChannelDescription>
)} )}
</ChannelTextInfo> </ChannelTextInfo>
</ChannelInfo> </ChannelInfo>
{notification && notification > 0 && !activeView && ( {notification && notification > 0 && !activeView && (
<NotificationBagde theme={theme}>{notification}</NotificationBagde> <NotificationBagde>{notification}</NotificationBagde>
)} )}
{isMuted && !notification && <MutedIcon theme={theme} />} {isMuted && !notification && <MutedIcon />}
</ChannelWrapper> </ChannelWrapper>
); );
} }
interface ThemeProps {
theme: Theme;
}
const ChannelsWrapper = styled.div<ThemeProps>` const ChannelsWrapper = styled.div`
width: 21%; width: 21%;
height: 100%; height: 100%;
min-width: 196px; min-width: 196px;
@ -161,7 +142,7 @@ const StyledCommunity = styled(Community)`
margin: 0 0 16px; margin: 0 0 16px;
`; `;
const ChannelDescription = styled.p<ThemeProps>` const ChannelDescription = styled.p`
font-size: 12px; font-size: 12px;
line-height: 16px; line-height: 16px;
letter-spacing: 0.1px; letter-spacing: 0.1px;
@ -181,7 +162,7 @@ export const ChannelList = styled.div`
} }
`; `;
const ChannelWrapper = styled.div<ThemeProps>` const ChannelWrapper = styled.div`
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
@ -207,7 +188,7 @@ const ChannelTextInfo = styled.div`
overflow: hidden; overflow: hidden;
`; `;
export const ChannelLogo = styled.div<ThemeProps>` export const ChannelLogo = styled.div`
width: 24px; width: 24px;
height: 24px; height: 24px;
display: flex; display: flex;
@ -239,7 +220,7 @@ export const ChannelLogo = styled.div<ThemeProps>`
} }
`; `;
export const ChannelName = styled.p<ThemeProps>` export const ChannelName = styled.p`
font-weight: 500; font-weight: 500;
opacity: 0.7; opacity: 0.7;
color: ${({ theme }) => theme.primary}; color: ${({ theme }) => theme.primary};
@ -259,7 +240,7 @@ export const ChannelName = styled.p<ThemeProps>`
} }
`; `;
const NotificationBagde = styled.div<ThemeProps>` const NotificationBagde = styled.div`
width: 24px; width: 24px;
height: 24px; height: 24px;
border-radius: 50%; border-radius: 50%;

View File

@ -47,7 +47,6 @@ export function Chat({ theme, community, fetchMetadata }: ChatProps) {
<Channels <Channels
notifications={notifications} notifications={notifications}
clearNotifications={clearNotifications} clearNotifications={clearNotifications}
theme={theme}
community={community} community={community}
setActiveChannel={setActiveChannel} setActiveChannel={setActiveChannel}
activeChannelId={activeChannel.id} activeChannelId={activeChannel.id}
@ -73,18 +72,13 @@ export function Chat({ theme, community, fetchMetadata }: ChatProps) {
fetchMetadata={fetchMetadata} fetchMetadata={fetchMetadata}
/> />
{showMembers && !narrow && ( {showMembers && !narrow && (
<Members <Members community={community} setShowChannels={setShowChannels} />
theme={theme}
community={community}
setShowChannels={setShowChannels}
/>
)} )}
<CommunityModal <CommunityModal
isVisible={isModalVisible} isVisible={isModalVisible}
onClose={() => setIsModalVisible(false)} onClose={() => setIsModalVisible(false)}
icon={community.icon} icon={community.icon}
name={community.name} name={community.name}
theme={theme}
subtitle="Public Community" subtitle="Public Community"
description={community.description} description={community.description}
publicKey="0xD95DBdaB08A9FED2D71ac9C3028AAc40905d8CF3" publicKey="0xD95DBdaB08A9FED2D71ac9C3028AAc40905d8CF3"

View File

@ -72,26 +72,20 @@ export function ChatBody({
}, [showMembersList]); }, [showMembersList]);
return ( return (
<ChatBodyWrapper theme={theme} className={className}> <ChatBodyWrapper className={className}>
<ChatTopbar <ChatTopbar
className={ className={
narrow && (showChannelsList || showMembersList) ? "narrow" : "" narrow && (showChannelsList || showMembersList) ? "narrow" : ""
} }
theme={theme}
> >
<ChannelWrapper className={className}> <ChannelWrapper className={className}>
{(showCommunity || narrow) && ( {(showCommunity || narrow) && (
<CommunityWrap theme={theme} className={className}> <CommunityWrap className={className}>
<Community <Community onClick={onCommunityClick} community={community} />
onClick={onCommunityClick}
community={community}
theme={theme}
/>
</CommunityWrap> </CommunityWrap>
)} )}
<Channel <Channel
channel={channel} channel={channel}
theme={theme}
isActive={narrow ? showChannelsList : true} isActive={narrow ? showChannelsList : true}
activeView={true} activeView={true}
isMuted={false} isMuted={false}
@ -105,11 +99,10 @@ export function ChatBody({
? "active" ? "active"
: "" : ""
} }
theme={theme}
> >
<MembersIcon theme={theme} /> <MembersIcon />
</MemberBtn> </MemberBtn>
{!messenger && <Loading theme={theme} />} {!messenger && <Loading />}
</ChatTopbar> </ChatTopbar>
{messenger ? ( {messenger ? (
<> <>
@ -122,22 +115,20 @@ export function ChatBody({
messenger ? ( messenger ? (
<ChatMessages <ChatMessages
messages={messages} messages={messages}
theme={theme}
fetchMetadata={fetchMetadata} fetchMetadata={fetchMetadata}
/> />
) : ( ) : (
<LoadingSkeleton theme={theme} /> <LoadingSkeleton />
) )
) : ( ) : (
<EmptyChannel theme={theme} channel={channel} /> <EmptyChannel channel={channel} />
)} )}
<ChatInput theme={theme} addMessage={sendMessage} /> <ChatInput addMessage={sendMessage} theme={theme} />
</> </>
)} )}
{showChannelsList && narrow && ( {showChannelsList && narrow && (
<NarrowChannels <NarrowChannels
theme={theme}
community={community.name} community={community.name}
notifications={notifications} notifications={notifications}
setActiveChannel={setActiveChannel} setActiveChannel={setActiveChannel}
@ -147,7 +138,6 @@ export function ChatBody({
)} )}
{showMembersList && narrow && ( {showMembersList && narrow && (
<NarrowMembers <NarrowMembers
theme={theme}
community={community} community={community}
setShowChannels={setShowChannelsList} setShowChannels={setShowChannelsList}
setShowMembersList={setShowMembersList} setShowMembersList={setShowMembersList}
@ -156,18 +146,15 @@ export function ChatBody({
</> </>
) : ( ) : (
<> <>
<LoadingSkeleton theme={theme} /> <LoadingSkeleton />
<ChatInput theme={theme} addMessage={sendMessage} /> <ChatInput addMessage={sendMessage} theme={theme} />
</> </>
)} )}
</ChatBodyWrapper> </ChatBodyWrapper>
); );
} }
interface ThemeProps {
theme: Theme;
}
const ChatBodyWrapper = styled.div<ThemeProps>` const ChatBodyWrapper = styled.div`
display: flex; display: flex;
flex-direction: column; flex-direction: column;
flex: 1; flex: 1;
@ -188,7 +175,7 @@ const ChannelWrapper = styled.div`
} }
`; `;
const ChatTopbar = styled.div<ThemeProps>` const ChatTopbar = styled.div`
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
padding: 5px 8px; padding: 5px 8px;
@ -204,7 +191,7 @@ const ChatTopbar = styled.div<ThemeProps>`
} }
`; `;
const CommunityWrap = styled.div<ThemeProps>` const CommunityWrap = styled.div`
padding-right: 10px; padding-right: 10px;
margin-right: 16px; margin-right: 16px;
position: relative; position: relative;
@ -227,7 +214,7 @@ const CommunityWrap = styled.div<ThemeProps>`
} }
`; `;
const MemberBtn = styled.button<ThemeProps>` const MemberBtn = styled.button`
width: 32px; width: 32px;
height: 32px; height: 32px;
border-radius: 8px; border-radius: 8px;

View File

@ -42,7 +42,7 @@ export function ChatInput({ theme, addMessage }: ChatInputProps) {
<Picker <Picker
onSelect={addEmoji} onSelect={addEmoji}
theme={theme === lightTheme ? "light" : "dark"} theme={theme === lightTheme ? "light" : "dark"}
set="apple" set="twitter"
color={theme.tertiary} color={theme.tertiary}
emojiSize={26} emojiSize={26}
style={{ style={{
@ -59,7 +59,7 @@ export function ChatInput({ theme, addMessage }: ChatInputProps) {
)} )}
<AddPictureBtn> <AddPictureBtn>
<PictureIcon theme={theme} /> <PictureIcon />
<AddPictureInput <AddPictureInput
type="file" type="file"
multiple={true} multiple={true}
@ -77,14 +77,12 @@ export function ChatInput({ theme, addMessage }: ChatInputProps) {
/> />
</AddPictureBtn> </AddPictureBtn>
<InputImageWrapper <InputImageWrapper
theme={theme}
style={{ height: `${inputHeight + (image ? 73 : 0)}px` }} style={{ height: `${inputHeight + (image ? 73 : 0)}px` }}
> >
{image && ( {image && (
<ImagePreview src={image} onClick={() => setImageUint(undefined)} /> <ImagePreview src={image} onClick={() => setImageUint(undefined)} />
)} )}
<Input <Input
theme={theme}
placeholder={"Message"} placeholder={"Message"}
value={content} value={content}
onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) => { onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) => {
@ -107,22 +105,18 @@ export function ChatInput({ theme, addMessage }: ChatInputProps) {
/> />
</InputImageWrapper> </InputImageWrapper>
<AddEmojiBtn onClick={() => setShowEmoji(!showEmoji)}> <AddEmojiBtn onClick={() => setShowEmoji(!showEmoji)}>
<EmojiIcon theme={theme} isActive={showEmoji} /> <EmojiIcon isActive={showEmoji} />
</AddEmojiBtn> </AddEmojiBtn>
<AddStickerBtn> <AddStickerBtn>
<StickerIcon theme={theme} /> <StickerIcon />
</AddStickerBtn> </AddStickerBtn>
<AddGifBtn> <AddGifBtn>
<GifIcon theme={theme} /> <GifIcon />
</AddGifBtn> </AddGifBtn>
</InputWrapper> </InputWrapper>
); );
} }
interface ThemeProps {
theme: Theme;
}
const InputWrapper = styled.div` const InputWrapper = styled.div`
display: flex; display: flex;
align-items: center; align-items: center;
@ -138,7 +132,7 @@ const ImagePreview = styled.img`
margin-top: 9px; margin-top: 9px;
`; `;
const InputImageWrapper = styled.div<ThemeProps>` const InputImageWrapper = styled.div`
width: 100%; width: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -149,7 +143,7 @@ const InputImageWrapper = styled.div<ThemeProps>`
margin-left: 10px; margin-left: 10px;
`; `;
const Input = styled.textarea<ThemeProps>` const Input = styled.textarea`
width: 100%; width: 100%;
height: 40px; height: 40px;
background: ${({ theme }) => theme.inputColor}; background: ${({ theme }) => theme.inputColor};

View File

@ -4,7 +4,6 @@ import styled from "styled-components";
import { ChatMessage } from "../../models/ChatMessage"; import { ChatMessage } from "../../models/ChatMessage";
import { Metadata } from "../../models/Metadata"; import { Metadata } from "../../models/Metadata";
import { Theme } from "../../styles/themes";
/* eslint-disable no-useless-escape */ /* eslint-disable no-useless-escape */
const regEx = const regEx =
@ -13,13 +12,11 @@ const regEx =
type ChatMessageContentProps = { type ChatMessageContentProps = {
message: ChatMessage; message: ChatMessage;
theme: Theme;
fetchMetadata?: (url: string) => Promise<Metadata | undefined>; fetchMetadata?: (url: string) => Promise<Metadata | undefined>;
}; };
export function ChatMessageContent({ export function ChatMessageContent({
message, message,
theme,
fetchMetadata, fetchMetadata,
}: ChatMessageContentProps) { }: ChatMessageContentProps) {
const { content, image } = useMemo(() => message, [message]); const { content, image } = useMemo(() => message, [message]);
@ -40,13 +37,7 @@ export function ChatMessageContent({
? match ? match
: "https://" + match; : "https://" + match;
newSplit.push( newSplit.push(
<Link <Link key={idx} href={link} target="_blank" rel="noopener noreferrer">
key={idx}
href={link}
target="_blank"
rel="noopener noreferrer"
theme={theme}
>
{match} {match}
</Link>, </Link>,
split[idx + 1] split[idx + 1]

View File

@ -3,7 +3,6 @@ import styled from "styled-components";
import { ChatMessage } from "../../models/ChatMessage"; import { ChatMessage } from "../../models/ChatMessage";
import { Metadata } from "../../models/Metadata"; import { Metadata } from "../../models/Metadata";
import { Theme } from "../../styles/themes";
import { UserIcon } from "../Icons/UserIcon"; import { UserIcon } from "../Icons/UserIcon";
import { textSmallStyles } from "../Text"; import { textSmallStyles } from "../Text";
@ -11,15 +10,10 @@ import { ChatMessageContent } from "./ChatMessageContent";
type ChatMessagesProps = { type ChatMessagesProps = {
messages: ChatMessage[]; messages: ChatMessage[];
theme: Theme;
fetchMetadata?: (url: string) => Promise<Metadata | undefined>; fetchMetadata?: (url: string) => Promise<Metadata | undefined>;
}; };
export function ChatMessages({ export function ChatMessages({ messages, fetchMetadata }: ChatMessagesProps) {
messages,
theme,
fetchMetadata,
}: ChatMessagesProps) {
const [scrollOnBot, setScrollOnBot] = useState(false); const [scrollOnBot, setScrollOnBot] = useState(false);
const ref = useRef<HTMLHeadingElement>(null); const ref = useRef<HTMLHeadingElement>(null);
const today = useMemo(() => new Date().getDay(), []); const today = useMemo(() => new Date().getDay(), []);
@ -64,22 +58,19 @@ export function ChatMessages({
)} )}
<MessageWrapper> <MessageWrapper>
<Icon> <Icon>
<UserIcon theme={theme} /> <UserIcon />
</Icon> </Icon>
<ContentWrapper> <ContentWrapper>
<MessageHeaderWrapper> <MessageHeaderWrapper>
<UserNameWrapper theme={theme}> <UserNameWrapper>
{message.sender.slice(0, 10)} {message.sender.slice(0, 10)}
</UserNameWrapper> </UserNameWrapper>
<TimeWrapper theme={theme}> <TimeWrapper>{message.date.toLocaleString()}</TimeWrapper>
{message.date.toLocaleString()}
</TimeWrapper>
</MessageHeaderWrapper> </MessageHeaderWrapper>
<MessageText theme={theme}> <MessageText>
<ChatMessageContent <ChatMessageContent
message={message} message={message}
theme={theme}
fetchMetadata={fetchMetadata} fetchMetadata={fetchMetadata}
/> />
</MessageText> </MessageText>
@ -92,10 +83,6 @@ export function ChatMessages({
); );
} }
interface ThemeProps {
theme: Theme;
}
const MessagesWrapper = styled.div` const MessagesWrapper = styled.div`
height: calc(100% - 44px); height: calc(100% - 44px);
overflow: auto; overflow: auto;
@ -159,13 +146,13 @@ export const Icon = styled.div`
flex-shrink: 0; flex-shrink: 0;
`; `;
const UserNameWrapper = styled.div<ThemeProps>` const UserNameWrapper = styled.div`
font-size: 15px; font-size: 15px;
line-height: 22px; line-height: 22px;
color: ${({ theme }) => theme.tertiary}; color: ${({ theme }) => theme.tertiary};
`; `;
const TimeWrapper = styled.div<ThemeProps>` const TimeWrapper = styled.div`
font-size: 10px; font-size: 10px;
line-height: 14px; line-height: 14px;
letter-spacing: 0.2px; letter-spacing: 0.2px;
@ -174,7 +161,7 @@ const TimeWrapper = styled.div<ThemeProps>`
margin-left: 4px; margin-left: 4px;
`; `;
const MessageText = styled.div<ThemeProps>` const MessageText = styled.div`
overflow-wrap: anywhere; overflow-wrap: anywhere;
width: 100%; width: 100%;
white-space: pre-wrap; white-space: pre-wrap;

View File

@ -1,23 +1,16 @@
import React from "react"; import React from "react";
import { CommunityData } from "../helpers/communityMock"; import { CommunityData } from "../helpers/communityMock";
import { Theme } from "../styles/themes";
import { CommunityIdentity } from "./CommunityIdentity"; import { CommunityIdentity } from "./CommunityIdentity";
interface CommunityProps { interface CommunityProps {
theme: Theme;
community: CommunityData; community: CommunityData;
onClick: () => void; onClick: () => void;
className?: string; className?: string;
} }
export function Community({ export function Community({ community, onClick, className }: CommunityProps) {
theme,
community,
onClick,
className,
}: CommunityProps) {
const { name, icon, members } = community; const { name, icon, members } = community;
return ( return (
@ -27,7 +20,6 @@ export function Community({
name={name} name={name}
icon={icon} icon={icon}
subtitle={`${members} members`} subtitle={`${members} members`}
theme={theme}
/> />
</button> </button>
</> </>

View File

@ -1,15 +1,12 @@
import React from "react"; import React from "react";
import styled from "styled-components"; import styled from "styled-components";
import { Theme } from "../styles/themes";
import { textMediumStyles } from "./Text"; import { textMediumStyles } from "./Text";
export interface CommunityIdentityProps { export interface CommunityIdentityProps {
icon: string; icon: string;
name: string; name: string;
subtitle: string; subtitle: string;
theme: Theme;
className?: string; className?: string;
} }
@ -18,14 +15,13 @@ export const CommunityIdentity = ({
name, name,
subtitle, subtitle,
className, className,
theme,
}: CommunityIdentityProps) => { }: CommunityIdentityProps) => {
return ( return (
<Row className={className}> <Row className={className}>
<Logo src={icon} alt={`${name} logo`} /> <Logo src={icon} alt={`${name} logo`} />
<Column> <Column>
<Name theme={theme}>{name}</Name> <Name>{name}</Name>
<Subtitle theme={theme}>{subtitle}</Subtitle> <Subtitle>{subtitle}</Subtitle>
</Column> </Column>
</Row> </Row>
); );

View File

@ -2,17 +2,15 @@ import React from "react";
import styled from "styled-components"; import styled from "styled-components";
import { ChannelData } from "../helpers/channelsMock"; import { ChannelData } from "../helpers/channelsMock";
import { Theme } from "../styles/themes";
import { ChannelInfo, ChannelLogo, ChannelName } from "./Channels"; import { ChannelInfo, ChannelLogo, ChannelName } from "./Channels";
import { textMediumStyles } from "./Text"; import { textMediumStyles } from "./Text";
type EmptyChannelProps = { type EmptyChannelProps = {
theme: Theme;
channel: ChannelData; channel: ChannelData;
}; };
export function EmptyChannel({ theme, channel }: EmptyChannelProps) { export function EmptyChannel({ channel }: EmptyChannelProps) {
return ( return (
<Wrapper> <Wrapper>
<ChannelInfoEmpty> <ChannelInfoEmpty>
@ -20,26 +18,19 @@ export function EmptyChannel({ theme, channel }: EmptyChannelProps) {
style={{ style={{
backgroundImage: channel.icon ? `url(${channel.icon}` : "", backgroundImage: channel.icon ? `url(${channel.icon}` : "",
}} }}
theme={theme}
> >
{" "} {" "}
{!channel.icon && channel.name.slice(0, 1).toUpperCase()} {!channel.icon && channel.name.slice(0, 1).toUpperCase()}
</ChannelLogoEmpty> </ChannelLogoEmpty>
<ChannelNameEmpty theme={theme} className={"active"}> <ChannelNameEmpty className={"active"}>{channel.name}</ChannelNameEmpty>
{channel.name}
</ChannelNameEmpty>
</ChannelInfoEmpty> </ChannelInfoEmpty>
<EmptyText theme={theme}> <EmptyText>
Welcome to the beginning of the <span>#{channel.name}</span> channel! Welcome to the beginning of the <span>#{channel.name}</span> channel!
</EmptyText> </EmptyText>
</Wrapper> </Wrapper>
); );
} }
interface ThemeProps {
theme: Theme;
}
const Wrapper = styled.div` const Wrapper = styled.div`
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -68,7 +59,7 @@ const ChannelNameEmpty = styled(ChannelName)`
margin-bottom: 16px; margin-bottom: 16px;
`; `;
const EmptyText = styled.p<ThemeProps>` const EmptyText = styled.p`
display: inline-block; display: inline-block;
color: ${({ theme }) => theme.secondary}; color: ${({ theme }) => theme.secondary};

View File

@ -1,7 +1,6 @@
import React from "react"; import React from "react";
import styled from "styled-components"; import styled from "styled-components";
import { Theme } from "../../styles/themes";
import { copy } from "../../utils/copy"; import { copy } from "../../utils/copy";
import { reduceString } from "../../utils/reduceString"; import { reduceString } from "../../utils/reduceString";
import { textMediumStyles, textSmallStyles } from "../Text"; import { textMediumStyles, textSmallStyles } from "../Text";
@ -9,18 +8,15 @@ import { textMediumStyles, textSmallStyles } from "../Text";
interface CopyInputProps { interface CopyInputProps {
label: string; label: string;
value: string; value: string;
theme: Theme;
} }
export const CopyInput = ({ label, value, theme }: CopyInputProps) => ( export const CopyInput = ({ label, value }: CopyInputProps) => (
<div> <div>
<Label theme={theme}>{label}</Label> <Label>{label}</Label>
<Wrapper theme={theme}> <Wrapper>
<Text theme={theme}>{reduceString(value, 15, 15)}</Text> <Text>{reduceString(value, 15, 15)}</Text>
<CopyButtonWrapper theme={theme}> <CopyButtonWrapper>
<CopyButton theme={theme} onClick={() => copy(value)}> <CopyButton onClick={() => copy(value)}>Copy</CopyButton>
Copy
</CopyButton>
</CopyButtonWrapper> </CopyButtonWrapper>
</Wrapper> </Wrapper>
</div> </div>

View File

@ -1,11 +1,8 @@
import React from "react"; import React from "react";
import styled from "styled-components"; import styled from "styled-components";
import { Theme } from "../../styles/themes"; export const CrossIcon = () => (
export const CrossIcon = ({ theme }: { theme: Theme }) => (
<Icon <Icon
theme={theme}
width="12" width="12"
height="12" height="12"
viewBox="0 0 12 12" viewBox="0 0 12 12"

View File

@ -1,21 +1,17 @@
import React from "react"; import React from "react";
import styled from "styled-components"; import styled from "styled-components";
import { Theme } from "../../styles/themes";
interface ThemeProps { interface ThemeProps {
theme: Theme;
isActive?: boolean; isActive?: boolean;
} }
export const EmojiIcon = ({ theme, isActive }: ThemeProps) => { export const EmojiIcon = ({ isActive }: ThemeProps) => {
return ( return (
<Icon <Icon
width="20" width="20"
height="20" height="20"
viewBox="0 0 20 20" viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
theme={theme}
> >
<path <path
className={isActive ? "active" : ""} className={isActive ? "active" : ""}
@ -39,7 +35,7 @@ export const EmojiIcon = ({ theme, isActive }: ThemeProps) => {
); );
}; };
const Icon = styled.svg<ThemeProps>` const Icon = styled.svg`
& > path { & > path {
fill: ${({ theme }) => theme.secondary}; fill: ${({ theme }) => theme.secondary};
} }

View File

@ -1,21 +1,17 @@
import React from "react"; import React from "react";
import styled from "styled-components"; import styled from "styled-components";
import { Theme } from "../../styles/themes";
interface ThemeProps { interface ThemeProps {
theme: Theme;
isActive?: boolean; isActive?: boolean;
} }
export const GifIcon = ({ theme, isActive }: ThemeProps) => { export const GifIcon = ({ isActive }: ThemeProps) => {
return ( return (
<Icon <Icon
width="20" width="20"
height="20" height="20"
viewBox="0 0 20 20" viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
theme={theme}
> >
<path <path
className={isActive ? "active" : ""} className={isActive ? "active" : ""}
@ -39,7 +35,7 @@ export const GifIcon = ({ theme, isActive }: ThemeProps) => {
); );
}; };
const Icon = styled.svg<ThemeProps>` const Icon = styled.svg`
& > path { & > path {
fill: ${({ theme }) => theme.secondary}; fill: ${({ theme }) => theme.secondary};
} }

View File

@ -1,8 +1,6 @@
import React from "react"; import React from "react";
import styled, { keyframes } from "styled-components"; import styled, { keyframes } from "styled-components";
import { Theme } from "../../styles/themes";
const rotation = keyframes` const rotation = keyframes`
from { from {
transform: rotate(0deg); transform: rotate(0deg);
@ -12,13 +10,12 @@ const rotation = keyframes`
} }
`; `;
export const LoadingIcon = ({ theme }: { theme: Theme }) => ( export const LoadingIcon = () => (
<Icon <Icon
width="13" width="13"
height="12" height="12"
viewBox="0 0 13 12" viewBox="0 0 13 12"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
theme={theme}
> >
<path <path
fillRule="evenodd" fillRule="evenodd"

View File

@ -1,20 +1,13 @@
import React from "react"; import React from "react";
import styled from "styled-components"; import styled from "styled-components";
import { Theme } from "../../styles/themes"; export const MembersIcon = () => {
interface ThemeProps {
theme: Theme;
}
export const MembersIcon = ({ theme }: ThemeProps) => {
return ( return (
<Icon <Icon
width="32" width="32"
height="32" height="32"
viewBox="0 0 32 32" viewBox="0 0 32 32"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
theme={theme}
> >
<path <path
fillRule="evenodd" fillRule="evenodd"
@ -26,7 +19,7 @@ export const MembersIcon = ({ theme }: ThemeProps) => {
); );
}; };
const Icon = styled.svg<ThemeProps>` const Icon = styled.svg`
& > path { & > path {
fill: ${({ theme }) => theme.primary}; fill: ${({ theme }) => theme.primary};
} }

View File

@ -1,20 +1,13 @@
import React from "react"; import React from "react";
import styled from "styled-components"; import styled from "styled-components";
import { Theme } from "../../styles/themes"; export const MutedIcon = () => {
interface ThemeProps {
theme: Theme;
}
export const MutedIcon = ({ theme }: ThemeProps) => {
return ( return (
<Icon <Icon
width="14" width="14"
height="14" height="14"
viewBox="0 0 14 14" viewBox="0 0 14 14"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
theme={theme}
> >
<path <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" 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"
@ -28,7 +21,7 @@ export const MutedIcon = ({ theme }: ThemeProps) => {
); );
}; };
const Icon = styled.svg<ThemeProps>` const Icon = styled.svg`
& > path { & > path {
fill: ${({ theme }) => theme.primary}; fill: ${({ theme }) => theme.primary};
} }

View File

@ -1,20 +1,13 @@
import React from "react"; import React from "react";
import styled from "styled-components"; import styled from "styled-components";
import { Theme } from "../../styles/themes"; export const PictureIcon = () => {
interface ThemeProps {
theme: Theme;
}
export const PictureIcon = ({ theme }: ThemeProps) => {
return ( return (
<Icon <Icon
width="20" width="20"
height="18" height="18"
viewBox="0 0 20 18" viewBox="0 0 20 18"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
theme={theme}
> >
<path <path
fillRule="evenodd" fillRule="evenodd"
@ -30,7 +23,7 @@ export const PictureIcon = ({ theme }: ThemeProps) => {
); );
}; };
const Icon = styled.svg<ThemeProps>` const Icon = styled.svg`
& > path { & > path {
fill: ${({ theme }) => theme.secondary}; fill: ${({ theme }) => theme.secondary};
} }

View File

@ -1,11 +1,8 @@
import React from "react"; import React from "react";
import styled from "styled-components"; import styled from "styled-components";
import { Theme } from "../../styles/themes"; export const StatusLogo = () => (
export const StatusLogo = ({ theme }: { theme: Theme }) => (
<Icon <Icon
theme={theme}
width="171" width="171"
height="64" height="64"
viewBox="0 0 171 64" viewBox="0 0 171 64"

View File

@ -1,21 +1,17 @@
import React from "react"; import React from "react";
import styled from "styled-components"; import styled from "styled-components";
import { Theme } from "../../styles/themes";
interface ThemeProps { interface ThemeProps {
theme: Theme;
isActive?: boolean; isActive?: boolean;
} }
export const StickerIcon = ({ theme, isActive }: ThemeProps) => { export const StickerIcon = ({ isActive }: ThemeProps) => {
return ( return (
<Icon <Icon
width="20" width="20"
height="20" height="20"
viewBox="0 0 20 20" viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
theme={theme}
> >
<path <path
className={isActive ? "active" : ""} className={isActive ? "active" : ""}
@ -31,7 +27,7 @@ export const StickerIcon = ({ theme, isActive }: ThemeProps) => {
); );
}; };
const Icon = styled.svg<ThemeProps>` const Icon = styled.svg`
& > path { & > path {
fill: ${({ theme }) => theme.secondary}; fill: ${({ theme }) => theme.secondary};
} }

View File

@ -1,20 +1,16 @@
import React from "react"; import React from "react";
import styled from "styled-components"; import styled from "styled-components";
import { Theme } from "../../styles/themes";
interface UserIconProps { interface UserIconProps {
theme: Theme;
memberView?: boolean; memberView?: boolean;
} }
export const UserIcon = ({ theme, memberView }: UserIconProps) => { export const UserIcon = ({ memberView }: UserIconProps) => {
return ( return (
<Icon <Icon
viewBox="0 0 34 34" viewBox="0 0 34 34"
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
theme={theme}
memberView={memberView} memberView={memberView}
> >
<ellipse cx="17" cy="10.3883" rx="6.94445" ry="6.94445" /> <ellipse cx="17" cy="10.3883" rx="6.94445" ry="6.94445" />

View File

@ -3,39 +3,31 @@ import styled from "styled-components";
import { useNarrow } from "../contexts/narrowProvider"; import { useNarrow } from "../contexts/narrowProvider";
import { CommunityData } from "../helpers/communityMock"; import { CommunityData } from "../helpers/communityMock";
import { Theme } from "../styles/themes";
import { Icon } from "./Chat/ChatMessages"; import { Icon } from "./Chat/ChatMessages";
import { UserIcon } from "./Icons/UserIcon"; import { UserIcon } from "./Icons/UserIcon";
interface MembersProps { interface MembersProps {
theme: Theme;
community: CommunityData; community: CommunityData;
setShowChannels: (val: boolean) => void; setShowChannels: (val: boolean) => void;
} }
export function Members({ theme, community, setShowChannels }: MembersProps) { export function Members({ community, setShowChannels }: MembersProps) {
return ( return (
<MembersWrapper theme={theme}> <MembersWrapper>
<MemberHeading theme={theme}>Members</MemberHeading> <MemberHeading>Members</MemberHeading>
<MembersList <MembersList community={community} setShowChannels={setShowChannels} />
theme={theme}
community={community}
setShowChannels={setShowChannels}
/>
</MembersWrapper> </MembersWrapper>
); );
} }
interface MembersListProps { interface MembersListProps {
theme: Theme;
community: CommunityData; community: CommunityData;
setShowChannels: (val: boolean) => void; setShowChannels: (val: boolean) => void;
setShowMembers?: (val: boolean) => void; setShowMembers?: (val: boolean) => void;
} }
export function MembersList({ export function MembersList({
theme,
community, community,
setShowChannels, setShowChannels,
setShowMembers, setShowMembers,
@ -43,22 +35,21 @@ export function MembersList({
return ( return (
<MembersListWrap> <MembersListWrap>
<MemberCategory> <MemberCategory>
<MemberCategoryName theme={theme}>You</MemberCategoryName> <MemberCategoryName>You</MemberCategoryName>
<MemberData> <MemberData>
<MemberIcon> <MemberIcon>
<UserIcon theme={theme} memberView={true} /> <UserIcon memberView={true} />
</MemberIcon> </MemberIcon>
<MemberName theme={theme}>Guest564732</MemberName> <MemberName>Guest564732</MemberName>
</MemberData> </MemberData>
</MemberCategory> </MemberCategory>
<MemberCategory> <MemberCategory>
<MemberCategoryName theme={theme}>Online</MemberCategoryName> <MemberCategoryName>Online</MemberCategoryName>
{community.membersList {community.membersList
.filter((member) => member.isOnline) .filter((member) => member.isOnline)
.map((member) => ( .map((member) => (
<Member <Member
key={member.id} key={member.id}
theme={theme}
member={member} member={member}
isOnline={member.isOnline} isOnline={member.isOnline}
setShowChannels={setShowChannels} setShowChannels={setShowChannels}
@ -67,13 +58,12 @@ export function MembersList({
))} ))}
</MemberCategory> </MemberCategory>
<MemberCategory> <MemberCategory>
<MemberCategoryName theme={theme}>Offline</MemberCategoryName> <MemberCategoryName>Offline</MemberCategoryName>
{community.membersList {community.membersList
.filter((member) => !member.isOnline) .filter((member) => !member.isOnline)
.map((member) => ( .map((member) => (
<Member <Member
key={member.id} key={member.id}
theme={theme}
member={member} member={member}
isOnline={member.isOnline} isOnline={member.isOnline}
setShowChannels={setShowChannels} setShowChannels={setShowChannels}
@ -86,7 +76,6 @@ export function MembersList({
} }
interface MemberProps { interface MemberProps {
theme: Theme;
member: any; member: any;
isOnline: boolean; isOnline: boolean;
setShowChannels: (val: boolean) => void; setShowChannels: (val: boolean) => void;
@ -94,7 +83,6 @@ interface MemberProps {
} }
export function Member({ export function Member({
theme,
member, member,
isOnline, isOnline,
setShowChannels, setShowChannels,
@ -118,20 +106,15 @@ export function Member({
backgroundImage: member.avatar ? `url(${member.avatar})` : "unset", backgroundImage: member.avatar ? `url(${member.avatar})` : "unset",
}} }}
className={isOnline ? "online" : ""} className={isOnline ? "online" : ""}
theme={theme}
> >
{!member.avatar && <UserIcon theme={theme} memberView={true} />} {!member.avatar && <UserIcon memberView={true} />}
</MemberIcon> </MemberIcon>
<MemberName theme={theme}>{member.name}</MemberName> <MemberName>{member.name}</MemberName>
</MemberData> </MemberData>
); );
} }
interface ThemeProps { const MembersWrapper = styled.div`
theme: Theme;
}
const MembersWrapper = styled.div<ThemeProps>`
width: 18%; width: 18%;
height: 100%; height: 100%;
min-width: 164px; min-width: 164px;
@ -141,7 +124,7 @@ const MembersWrapper = styled.div<ThemeProps>`
padding: 16px; padding: 16px;
`; `;
const MemberHeading = styled.h2<ThemeProps>` const MemberHeading = styled.h2`
font-weight: 500; font-weight: 500;
font-size: 15px; font-size: 15px;
line-height: 22px; line-height: 22px;
@ -149,7 +132,7 @@ const MemberHeading = styled.h2<ThemeProps>`
margin-bottom: 16px; margin-bottom: 16px;
`; `;
const MemberCategoryName = styled.h3<ThemeProps>` const MemberCategoryName = styled.h3`
font-weight: normal; font-weight: normal;
font-size: 13px; font-size: 13px;
line-height: 18px; line-height: 18px;
@ -157,7 +140,7 @@ const MemberCategoryName = styled.h3<ThemeProps>`
margin-bottom: 8px; margin-bottom: 8px;
`; `;
const MemberName = styled.p<ThemeProps>` const MemberName = styled.p`
font-weight: 500; font-weight: 500;
font-size: 15px; font-size: 15px;
line-height: 22px; line-height: 22px;
@ -191,7 +174,7 @@ const MemberData = styled.div`
margin-bottom: 16px; margin-bottom: 16px;
`; `;
const MemberIcon = styled(Icon)<ThemeProps>` const MemberIcon = styled(Icon)`
width: 24px; width: 24px;
height: 24px; height: 24px;
position: relative; position: relative;

View File

@ -26,39 +26,29 @@ export const CommunityModal = ({
subtitle, subtitle,
description, description,
publicKey, publicKey,
theme,
}: CommunityModalProps) => { }: CommunityModalProps) => {
const narrow = useNarrow(); const narrow = useNarrow();
return ( return (
<Modal theme={theme} isVisible={isVisible} onClose={onClose}> <Modal isVisible={isVisible} onClose={onClose}>
<Section theme={theme}> <Section>
<CommunityIdentity <CommunityIdentity icon={icon} name={name} subtitle={subtitle} />
theme={theme}
icon={icon}
name={name}
subtitle={subtitle}
/>
</Section> </Section>
<Section theme={theme}> <Section>
<Text theme={theme}>{description}</Text> <Text>{description}</Text>
</Section> </Section>
<Section theme={theme}> <Section>
<CopyInput <CopyInput value={publicKey} label="Community public key" />
theme={theme} <Hint>
value={publicKey}
label="Community public key"
/>
<Hint theme={theme}>
To access this community, paste community public key in Status desktop To access this community, paste community public key in Status desktop
or mobile app. or mobile app.
{narrow && <StyledDownloadButton theme={theme} />} {narrow && <StyledDownloadButton />}
</Hint> </Hint>
</Section> </Section>
{!narrow && ( {!narrow && (
<BottomSection theme={theme}> <BottomSection>
<StatusLogo theme={theme} /> <StatusLogo />
<DownloadButton theme={theme} /> <DownloadButton />
</BottomSection> </BottomSection>
)} )}
</Modal> </Modal>

View File

@ -2,14 +2,12 @@ import React, { ReactNode, useCallback, useEffect } from "react";
import { createPortal } from "react-dom"; import { createPortal } from "react-dom";
import styled from "styled-components"; import styled from "styled-components";
import { Theme } from "../../styles/themes";
import { CrossIcon } from "../Icons/CrossIcon"; import { CrossIcon } from "../Icons/CrossIcon";
export interface BasicModalProps { export interface BasicModalProps {
isVisible: boolean; isVisible: boolean;
onClose: () => void; onClose: () => void;
className?: string; className?: string;
theme: Theme;
} }
export interface ModalProps extends BasicModalProps { export interface ModalProps extends BasicModalProps {
@ -21,7 +19,6 @@ export const Modal = ({
onClose, onClose,
children, children,
className, className,
theme,
}: ModalProps) => { }: ModalProps) => {
const listenKeyboard = useCallback( const listenKeyboard = useCallback(
(event: KeyboardEvent) => { (event: KeyboardEvent) => {
@ -45,10 +42,10 @@ export const Modal = ({
return createPortal( return createPortal(
<ModalView> <ModalView>
<ModalOverlay onClick={onClose} theme={theme} /> <ModalOverlay onClick={onClose} />
<ModalBody theme={theme} className={className}> <ModalBody className={className}>
<CloseButton onClick={onClose}> <CloseButton onClick={onClose}>
<CrossIcon theme={theme} /> <CrossIcon />
</CloseButton> </CloseButton>
{children} {children}
</ModalBody> </ModalBody>

View File

@ -2,13 +2,11 @@ import React from "react";
import styled from "styled-components"; import styled from "styled-components";
import { ChannelData, channels } from "../../helpers/channelsMock"; import { ChannelData, channels } from "../../helpers/channelsMock";
import { Theme } from "../../styles/themes";
import { Channel, ChannelList } from "../Channels"; import { Channel, ChannelList } from "../Channels";
import { NarrowTopbar } from "./NarrowTopbar"; import { NarrowTopbar } from "./NarrowTopbar";
interface NarrowChannelsProps { interface NarrowChannelsProps {
theme: Theme;
community: string; community: string;
notifications: { [id: string]: number }; notifications: { [id: string]: number };
setActiveChannel: (val: ChannelData) => void; setActiveChannel: (val: ChannelData) => void;
@ -17,7 +15,6 @@ interface NarrowChannelsProps {
} }
export function NarrowChannels({ export function NarrowChannels({
theme,
community, community,
notifications, notifications,
setActiveChannel, setActiveChannel,
@ -25,14 +22,13 @@ export function NarrowChannels({
setShowChannels, setShowChannels,
}: NarrowChannelsProps) { }: NarrowChannelsProps) {
return ( return (
<ListWrapper theme={theme}> <ListWrapper>
<NarrowTopbar theme={theme} list="Channels" community={community} /> <NarrowTopbar list="Channels" community={community} />
<ChannelList> <ChannelList>
{channels.map((channel) => ( {channels.map((channel) => (
<Channel <Channel
key={channel.id} key={channel.id}
channel={channel} channel={channel}
theme={theme}
isActive={channel.id === activeChannelId} isActive={channel.id === activeChannelId}
isMuted={channel.isMuted || false} isMuted={channel.isMuted || false}
notification={ notification={
@ -51,11 +47,7 @@ export function NarrowChannels({
); );
} }
interface ThemeProps { const ListWrapper = styled.div`
theme: Theme;
}
const ListWrapper = styled.div<ThemeProps>`
padding: 82px 18px 18px; padding: 82px 18px 18px;
background: ${({ theme }) => theme.bodyBackgroundColor}; background: ${({ theme }) => theme.bodyBackgroundColor};
`; `;

View File

@ -2,33 +2,25 @@ import React from "react";
import styled from "styled-components"; import styled from "styled-components";
import { CommunityData } from "../../helpers/communityMock"; import { CommunityData } from "../../helpers/communityMock";
import { Theme } from "../../styles/themes";
import { MembersList } from "../Members"; import { MembersList } from "../Members";
import { NarrowTopbar } from "./NarrowTopbar"; import { NarrowTopbar } from "./NarrowTopbar";
interface NarrowMembersProps { interface NarrowMembersProps {
theme: Theme;
community: CommunityData; community: CommunityData;
setShowChannels: (val: boolean) => void; setShowChannels: (val: boolean) => void;
setShowMembersList: (val: boolean) => void; setShowMembersList: (val: boolean) => void;
} }
export function NarrowMembers({ export function NarrowMembers({
theme,
community, community,
setShowChannels, setShowChannels,
setShowMembersList, setShowMembersList,
}: NarrowMembersProps) { }: NarrowMembersProps) {
return ( return (
<ListWrapper theme={theme}> <ListWrapper>
<NarrowTopbar <NarrowTopbar list="Community members" community={community.name} />
theme={theme}
list="Community members"
community={community.name}
/>
<MembersList <MembersList
theme={theme}
community={community} community={community}
setShowChannels={setShowChannels} setShowChannels={setShowChannels}
setShowMembers={setShowMembersList} setShowMembers={setShowMembersList}
@ -37,11 +29,7 @@ export function NarrowMembers({
); );
} }
interface ThemeProps { const ListWrapper = styled.div`
theme: Theme;
}
const ListWrapper = styled.div<ThemeProps>`
padding: 82px 18px 18px; padding: 82px 18px 18px;
background: ${({ theme }) => theme.bodyBackgroundColor}; background: ${({ theme }) => theme.bodyBackgroundColor};
`; `;

View File

@ -1,28 +1,21 @@
import React from "react"; import React from "react";
import styled from "styled-components"; import styled from "styled-components";
import { Theme } from "../../styles/themes";
interface NarrowTopbarProps { interface NarrowTopbarProps {
theme: Theme;
list: string; list: string;
community: string; community: string;
} }
export function NarrowTopbar({ theme, list, community }: NarrowTopbarProps) { export function NarrowTopbar({ list, community }: NarrowTopbarProps) {
return ( return (
<TopbarWrapper theme={theme}> <TopbarWrapper>
<Heading theme={theme}>{list}</Heading> <Heading>{list}</Heading>
<SubHeading theme={theme}>{community}</SubHeading> <SubHeading>{community}</SubHeading>
</TopbarWrapper> </TopbarWrapper>
); );
} }
interface ThemeProps { const TopbarWrapper = styled.div`
theme: Theme;
}
const TopbarWrapper = styled.div<ThemeProps>`
display: flex; display: flex;
justify-content: center; justify-content: center;
flex-direction: column; flex-direction: column;
@ -32,12 +25,12 @@ const TopbarWrapper = styled.div<ThemeProps>`
position: relative; position: relative;
`; `;
const Heading = styled.p<ThemeProps>` const Heading = styled.p`
font-weight: 500; font-weight: 500;
color: ${({ theme }) => theme.primary}; color: ${({ theme }) => theme.primary};
`; `;
const SubHeading = styled.p<ThemeProps>` const SubHeading = styled.p`
font-weight: 500; font-weight: 500;
color: ${({ theme }) => theme.secondary}; color: ${({ theme }) => theme.secondary};
`; `;

View File

@ -1,4 +1,5 @@
import React, { useRef } from "react"; import React, { useRef } from "react";
import { ThemeProvider } from "styled-components";
import { NarrowProvider } from "../contexts/narrowProvider"; import { NarrowProvider } from "../contexts/narrowProvider";
import { CommunityData } from "../helpers/communityMock"; import { CommunityData } from "../helpers/communityMock";
@ -17,15 +18,17 @@ interface ReactChatProps {
export function ReactChat({ theme, community, fetchMetadata }: ReactChatProps) { export function ReactChat({ theme, community, fetchMetadata }: ReactChatProps) {
const ref = useRef<HTMLHeadingElement>(null); const ref = useRef<HTMLHeadingElement>(null);
return ( return (
<NarrowProvider myRef={ref}> <ThemeProvider theme={theme}>
<div ref={ref}> <NarrowProvider myRef={ref}>
<GlobalStyle /> <div ref={ref}>
<Chat <GlobalStyle />
theme={theme} <Chat
community={community} community={community}
fetchMetadata={fetchMetadata} fetchMetadata={fetchMetadata}
/> theme={theme}
</div> />
</NarrowProvider> </div>
</NarrowProvider>
</ThemeProvider>
); );
} }

View File

@ -1,24 +1,19 @@
import React from "react"; import React from "react";
import styled from "styled-components"; import styled from "styled-components";
import { Theme } from "../../styles/themes";
import { LoadingIcon } from "../Icons/LoadingIcon"; import { LoadingIcon } from "../Icons/LoadingIcon";
import { textSmallStyles } from "../Text"; import { textSmallStyles } from "../Text";
interface LoadingProps { export const Loading = () => {
theme: Theme;
}
export const Loading = ({ theme }: LoadingProps) => {
return ( return (
<LoadingBlock theme={theme}> <LoadingBlock>
<LoadingIcon theme={theme} /> <LoadingIcon />
<LoadingText>Loading messages...</LoadingText> <LoadingText>Loading messages...</LoadingText>
</LoadingBlock> </LoadingBlock>
); );
}; };
const LoadingBlock = styled.div<LoadingProps>` const LoadingBlock = styled.div`
display: flex; display: flex;
align-items: center; align-items: center;
position: absolute; position: absolute;
@ -34,7 +29,7 @@ const LoadingBlock = styled.div<LoadingProps>`
z-index: 2; z-index: 2;
`; `;
const LoadingText = styled.p<LoadingProps>` const LoadingText = styled.p`
color: ${({ theme }) => theme.primary}; color: ${({ theme }) => theme.primary};
margin-left: 8px; margin-left: 8px;
font-weight: 500; font-weight: 500;

View File

@ -1,56 +1,45 @@
import React from "react"; import React from "react";
import styled from "styled-components"; import styled from "styled-components";
import { Theme } from "../../styles/themes";
import { MessageSkeleton } from "./MessageSkeleton"; import { MessageSkeleton } from "./MessageSkeleton";
import { Skeleton } from "./Skeleton"; import { Skeleton } from "./Skeleton";
interface LoadingSkeletonProps { export const LoadingSkeleton = () => {
theme: Theme;
}
export const LoadingSkeleton = ({ theme }: LoadingSkeletonProps) => {
return ( return (
<Loading> <Loading>
<MessageSkeleton theme={theme}> <MessageSkeleton>
<Skeleton theme={theme} /> <Skeleton />
</MessageSkeleton> </MessageSkeleton>
<MessageSkeleton theme={theme}> <MessageSkeleton>
<Skeleton theme={theme} /> <Skeleton />
</MessageSkeleton> </MessageSkeleton>
<MessageSkeleton theme={theme}> <MessageSkeleton>
<Skeleton theme={theme} /> <Skeleton />
</MessageSkeleton> </MessageSkeleton>
<MessageSkeleton theme={theme}> <MessageSkeleton>
<Skeleton theme={theme} /> <Skeleton />
</MessageSkeleton> </MessageSkeleton>
<MessageSkeleton theme={theme}> <MessageSkeleton>
<Skeleton theme={theme} /> <Skeleton />
<Skeleton theme={theme} width="30%" /> <Skeleton width="30%" />
</MessageSkeleton> </MessageSkeleton>
<MessageSkeleton theme={theme}> <MessageSkeleton>
<Skeleton theme={theme} width="70%" /> <Skeleton width="70%" />
</MessageSkeleton> </MessageSkeleton>
<MessageSkeleton theme={theme}> <MessageSkeleton>
<Skeleton theme={theme} width="40%" /> <Skeleton width="40%" />
<Skeleton theme={theme} width="25%" /> <Skeleton width="25%" />
<Skeleton theme={theme} width="30%" /> <Skeleton width="30%" />
</MessageSkeleton> </MessageSkeleton>
<MessageSkeleton theme={theme}> <MessageSkeleton>
<Skeleton theme={theme} width="50%" /> <Skeleton width="50%" />
<Skeleton <Skeleton width="147px" height="196px" borderRadius="16px" />
theme={theme}
width="147px"
height="196px"
borderRadius="16px"
/>
</MessageSkeleton> </MessageSkeleton>
<MessageSkeleton theme={theme}> <MessageSkeleton>
<Skeleton theme={theme} width="50%" /> <Skeleton width="50%" />
</MessageSkeleton> </MessageSkeleton>
<MessageSkeleton theme={theme}> <MessageSkeleton>
<Skeleton theme={theme} width="70%" /> <Skeleton width="70%" />
</MessageSkeleton> </MessageSkeleton>
</Loading> </Loading>
); );

View File

@ -1,28 +1,20 @@
import React, { ReactNode } from "react"; import React, { ReactNode } from "react";
import styled from "styled-components"; import styled from "styled-components";
import { Theme } from "../../styles/themes";
import { Skeleton } from "./Skeleton"; import { Skeleton } from "./Skeleton";
interface MessageSkeletonProps { interface MessageSkeletonProps {
theme: Theme;
children: ReactNode; children: ReactNode;
} }
export const MessageSkeleton = ({ theme, children }: MessageSkeletonProps) => { export const MessageSkeleton = ({ children }: MessageSkeletonProps) => {
return ( return (
<MessageWrapper> <MessageWrapper>
<AvatarSkeleton <AvatarSkeleton width="40px" height="40px" borderRadius="50%" />
width="40px"
height="40px"
borderRadius="50%"
theme={theme}
/>
<ContentWrapper> <ContentWrapper>
<MessageHeaderWrapper> <MessageHeaderWrapper>
<UserNameSkeleton theme={theme} width="132px" /> <UserNameSkeleton width="132px" />
<TimeSkeleton theme={theme} width="47px" height="14px" /> <TimeSkeleton width="47px" height="14px" />
</MessageHeaderWrapper> </MessageHeaderWrapper>
<MessageBodyWrapper>{children}</MessageBodyWrapper> <MessageBodyWrapper>{children}</MessageBodyWrapper>
</ContentWrapper> </ContentWrapper>

View File

@ -1,9 +1,6 @@
import styled, { keyframes } from "styled-components"; import styled, { keyframes } from "styled-components";
import { Theme } from "../../styles/themes";
interface SkeletonProps { interface SkeletonProps {
theme: Theme;
width?: string; width?: string;
height?: string; height?: string;
borderRadius?: string; borderRadius?: string;