Add theme Provider (#53)
This commit is contained in:
parent
02647e967d
commit
5ffd8a537d
|
@ -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"
|
||||||
>
|
>
|
||||||
|
|
|
@ -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%;
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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};
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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>
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
|
|
|
@ -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};
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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" />
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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};
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -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};
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -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};
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue