Add narrow members (#40)
This commit is contained in:
parent
370f6c65e4
commit
655399b03d
|
@ -90,7 +90,10 @@ export function Channel({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ChannelWrapper
|
<ChannelWrapper
|
||||||
className={isActive && !activeView ? "active" : ""}
|
className={
|
||||||
|
(isActive && !activeView) || (isActive && narrow) ? "active" : ""
|
||||||
|
}
|
||||||
|
style={{ width: narrow && activeView ? "calc(100% - 162px)" : "100%" }}
|
||||||
theme={theme}
|
theme={theme}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
>
|
>
|
||||||
|
@ -108,7 +111,7 @@ export function Channel({
|
||||||
<ChannelName
|
<ChannelName
|
||||||
theme={theme}
|
theme={theme}
|
||||||
className={
|
className={
|
||||||
isActive
|
isActive || narrow
|
||||||
? "active"
|
? "active"
|
||||||
: notification && notification > 0
|
: notification && notification > 0
|
||||||
? "notified"
|
? "notified"
|
||||||
|
@ -158,6 +161,9 @@ const ChannelDescription = styled.p<ThemeProps>`
|
||||||
line-height: 16px;
|
line-height: 16px;
|
||||||
letter-spacing: 0.1px;
|
letter-spacing: 0.1px;
|
||||||
color: ${({ theme }) => theme.secondary};
|
color: ${({ theme }) => theme.secondary};
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const ChannelList = styled.div`
|
export const ChannelList = styled.div`
|
||||||
|
@ -186,11 +192,14 @@ const ChannelWrapper = styled.div<ThemeProps>`
|
||||||
export const ChannelInfo = styled.div`
|
export const ChannelInfo = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
overflow: hidden;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const ChannelTextInfo = styled.div`
|
const ChannelTextInfo = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const ChannelLogo = styled.div<ThemeProps>`
|
export const ChannelLogo = styled.div<ThemeProps>`
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useState } from "react";
|
import React, { useCallback, useMemo, useState } from "react";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
|
|
||||||
import { useNarrow } from "../../contexts/narrowProvider";
|
import { useNarrow } from "../../contexts/narrowProvider";
|
||||||
|
@ -11,7 +11,7 @@ import { Community } from "../Community";
|
||||||
import { EmptyChannel } from "../EmptyChannel";
|
import { EmptyChannel } from "../EmptyChannel";
|
||||||
import { MembersIcon } from "../Icons/MembersIcon";
|
import { MembersIcon } from "../Icons/MembersIcon";
|
||||||
import { NarrowChannels } from "../NarrowMode/NarrowChannels";
|
import { NarrowChannels } from "../NarrowMode/NarrowChannels";
|
||||||
import { NarrowTopbar } from "../NarrowMode/NarrowTopbar";
|
import { NarrowMembers } from "../NarrowMode/NarrowMembers";
|
||||||
|
|
||||||
import { ChatInput } from "./ChatInput";
|
import { ChatInput } from "./ChatInput";
|
||||||
import { ChatMessages } from "./ChatMessages";
|
import { ChatMessages } from "./ChatMessages";
|
||||||
|
@ -44,59 +44,78 @@ export function ChatBody({
|
||||||
activeChannelId,
|
activeChannelId,
|
||||||
}: ChatBodyProps) {
|
}: ChatBodyProps) {
|
||||||
const narrow = useNarrow();
|
const narrow = useNarrow();
|
||||||
const [showChannelsList, setShowChannels] = useState(false);
|
const [showChannelsList, setShowChannelsList] = useState(false);
|
||||||
const [showMembersList, setShowMembersList] = useState(false);
|
const [showMembersList, setShowMembersList] = useState(false);
|
||||||
|
const className = useMemo(() => (narrow ? "narrow" : ""), [narrow]);
|
||||||
|
|
||||||
|
const switchChannelList = useCallback(() => {
|
||||||
|
setShowMembersList(false);
|
||||||
|
setShowChannelsList(true);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const switchMemberList = useCallback(() => {
|
||||||
|
setShowChannelsList(false);
|
||||||
|
setShowMembersList(!showMembersList);
|
||||||
|
}, [showMembersList]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ChatBodyWrapper theme={theme}>
|
<ChatBodyWrapper theme={theme} className={className}>
|
||||||
<ChatTopbar>
|
<ChatTopbar>
|
||||||
<ChannelWrapper>
|
<ChannelWrapper className={className}>
|
||||||
{(showCommunity || narrow) && (
|
{(showCommunity || narrow) && (
|
||||||
<CommunityWrap theme={theme}>
|
<CommunityWrap theme={theme} className={className}>
|
||||||
<Community community={community} theme={theme} />
|
<Community community={community} theme={theme} />
|
||||||
</CommunityWrap>
|
</CommunityWrap>
|
||||||
)}
|
)}
|
||||||
<Channel
|
<Channel
|
||||||
channel={channel}
|
channel={channel}
|
||||||
theme={theme}
|
theme={theme}
|
||||||
isActive={true}
|
isActive={narrow ? showChannelsList : true}
|
||||||
activeView={true}
|
activeView={true}
|
||||||
isMuted={false}
|
isMuted={false}
|
||||||
onClick={() => (narrow ? setShowChannels(true) : undefined)}
|
onClick={() => (narrow ? switchChannelList() : undefined)}
|
||||||
/>
|
/>
|
||||||
</ChannelWrapper>
|
</ChannelWrapper>
|
||||||
<MemberBtn
|
<MemberBtn
|
||||||
onClick={narrow ? () => setShowMembersList(true) : onClick}
|
onClick={narrow ? () => switchMemberList() : onClick}
|
||||||
className={showMembers ? "active" : ""}
|
className={
|
||||||
|
(showMembers && !narrow) || (showMembersList && narrow)
|
||||||
|
? "active"
|
||||||
|
: ""
|
||||||
|
}
|
||||||
theme={theme}
|
theme={theme}
|
||||||
>
|
>
|
||||||
<MembersIcon theme={theme} />
|
<MembersIcon theme={theme} />
|
||||||
</MemberBtn>
|
</MemberBtn>
|
||||||
</ChatTopbar>
|
</ChatTopbar>
|
||||||
{!showChannelsList &&
|
{!showChannelsList && !showMembersList && (
|
||||||
!showMembersList &&
|
<>
|
||||||
(messages.length > 0 ? (
|
{" "}
|
||||||
<ChatMessages messages={messages} theme={theme} />
|
{messages.length > 0 ? (
|
||||||
) : (
|
<ChatMessages messages={messages} theme={theme} />
|
||||||
<EmptyChannel theme={theme} channel={channel} />
|
) : (
|
||||||
))}
|
<EmptyChannel theme={theme} channel={channel} />
|
||||||
<ChatInput theme={theme} addMessage={sendMessage} />
|
)}
|
||||||
|
<ChatInput theme={theme} addMessage={sendMessage} />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
{showChannelsList && narrow && (
|
{showChannelsList && narrow && (
|
||||||
<NarrowChannels
|
<NarrowChannels
|
||||||
theme={theme}
|
theme={theme}
|
||||||
community={community.name}
|
community={community.name}
|
||||||
notifications={notifications}
|
notifications={notifications}
|
||||||
setActiveChannel={setActiveChannel}
|
setActiveChannel={setActiveChannel}
|
||||||
setShowChannels={setShowChannels}
|
setShowChannels={setShowChannelsList}
|
||||||
activeChannelId={activeChannelId}
|
activeChannelId={activeChannelId}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{showMembersList && narrow && (
|
{showMembersList && narrow && (
|
||||||
<NarrowTopbar
|
<NarrowMembers
|
||||||
theme={theme}
|
theme={theme}
|
||||||
list="Community members"
|
community={community}
|
||||||
community={community.name}
|
setShowChannels={setShowChannelsList}
|
||||||
onClick={() => setShowMembersList(false)}
|
setShowMembersList={setShowMembersList}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</ChatBodyWrapper>
|
</ChatBodyWrapper>
|
||||||
|
@ -112,24 +131,36 @@ const ChatBodyWrapper = styled.div<ThemeProps>`
|
||||||
flex: 1;
|
flex: 1;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background: ${({ theme }) => theme.bodyBackgroundColor};
|
background: ${({ theme }) => theme.bodyBackgroundColor};
|
||||||
|
|
||||||
|
&.narrow {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const ChannelWrapper = styled.div`
|
const ChannelWrapper = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
|
&.narrow {
|
||||||
|
width: calc(100% - 46px);
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const ChatTopbar = styled.div`
|
const ChatTopbar = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: 0 8px;
|
padding: 5px 8px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const CommunityWrap = styled.div<ThemeProps>`
|
const CommunityWrap = styled.div<ThemeProps>`
|
||||||
padding-right: 16px;
|
padding-right: 10px;
|
||||||
margin-right: 16px;
|
margin-right: 16px;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
|
&.narrow {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
&:after {
|
&:after {
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
|
@ -17,49 +17,69 @@ export function Members({ theme, community, setShowChannels }: MembersProps) {
|
||||||
return (
|
return (
|
||||||
<MembersWrapper theme={theme}>
|
<MembersWrapper theme={theme}>
|
||||||
<MemberHeading theme={theme}>Members</MemberHeading>
|
<MemberHeading theme={theme}>Members</MemberHeading>
|
||||||
<MembersList>
|
<MembersList
|
||||||
<MemberCategory>
|
theme={theme}
|
||||||
<MemberCategoryName theme={theme}>You</MemberCategoryName>
|
community={community}
|
||||||
<MemberData>
|
setShowChannels={setShowChannels}
|
||||||
<MemberIcon>
|
/>
|
||||||
<UserIcon theme={theme} memberView={true} />
|
|
||||||
</MemberIcon>
|
|
||||||
<MemberName theme={theme}>Guest564732</MemberName>
|
|
||||||
</MemberData>
|
|
||||||
</MemberCategory>
|
|
||||||
<MemberCategory>
|
|
||||||
<MemberCategoryName theme={theme}>Online</MemberCategoryName>
|
|
||||||
{community.membersList
|
|
||||||
.filter((member) => member.isOnline)
|
|
||||||
.map((member) => (
|
|
||||||
<Member
|
|
||||||
key={member.id}
|
|
||||||
theme={theme}
|
|
||||||
member={member}
|
|
||||||
isOnline={member.isOnline}
|
|
||||||
setShowChannels={setShowChannels}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</MemberCategory>
|
|
||||||
<MemberCategory>
|
|
||||||
<MemberCategoryName theme={theme}>Offline</MemberCategoryName>
|
|
||||||
{community.membersList
|
|
||||||
.filter((member) => !member.isOnline)
|
|
||||||
.map((member) => (
|
|
||||||
<Member
|
|
||||||
key={member.id}
|
|
||||||
theme={theme}
|
|
||||||
member={member}
|
|
||||||
isOnline={member.isOnline}
|
|
||||||
setShowChannels={setShowChannels}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</MemberCategory>
|
|
||||||
</MembersList>
|
|
||||||
</MembersWrapper>
|
</MembersWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface MembersListProps {
|
||||||
|
theme: Theme;
|
||||||
|
community: CommunityData;
|
||||||
|
setShowChannels: (val: boolean) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function MembersList({
|
||||||
|
theme,
|
||||||
|
community,
|
||||||
|
setShowChannels,
|
||||||
|
}: MembersListProps) {
|
||||||
|
return (
|
||||||
|
<MembersListWrap>
|
||||||
|
<MemberCategory>
|
||||||
|
<MemberCategoryName theme={theme}>You</MemberCategoryName>
|
||||||
|
<MemberData>
|
||||||
|
<MemberIcon>
|
||||||
|
<UserIcon theme={theme} memberView={true} />
|
||||||
|
</MemberIcon>
|
||||||
|
<MemberName theme={theme}>Guest564732</MemberName>
|
||||||
|
</MemberData>
|
||||||
|
</MemberCategory>
|
||||||
|
<MemberCategory>
|
||||||
|
<MemberCategoryName theme={theme}>Online</MemberCategoryName>
|
||||||
|
{community.membersList
|
||||||
|
.filter((member) => member.isOnline)
|
||||||
|
.map((member) => (
|
||||||
|
<Member
|
||||||
|
key={member.id}
|
||||||
|
theme={theme}
|
||||||
|
member={member}
|
||||||
|
isOnline={member.isOnline}
|
||||||
|
setShowChannels={setShowChannels}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</MemberCategory>
|
||||||
|
<MemberCategory>
|
||||||
|
<MemberCategoryName theme={theme}>Offline</MemberCategoryName>
|
||||||
|
{community.membersList
|
||||||
|
.filter((member) => !member.isOnline)
|
||||||
|
.map((member) => (
|
||||||
|
<Member
|
||||||
|
key={member.id}
|
||||||
|
theme={theme}
|
||||||
|
member={member}
|
||||||
|
isOnline={member.isOnline}
|
||||||
|
setShowChannels={setShowChannels}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</MemberCategory>
|
||||||
|
</MembersListWrap>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
interface MemberProps {
|
interface MemberProps {
|
||||||
theme: Theme;
|
theme: Theme;
|
||||||
member: any;
|
member: any;
|
||||||
|
@ -131,7 +151,7 @@ const MemberName = styled.p<ThemeProps>`
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const MembersList = styled.div`
|
const MembersListWrap = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
import React from "react";
|
||||||
|
import styled from "styled-components";
|
||||||
|
|
||||||
|
import { CommunityData } from "../../helpers/communityMock";
|
||||||
|
import { Theme } from "../../styles/themes";
|
||||||
|
import { MembersList } from "../Members";
|
||||||
|
|
||||||
|
import { NarrowTopbar } from "./NarrowTopbar";
|
||||||
|
|
||||||
|
interface NarrowMembersProps {
|
||||||
|
theme: Theme;
|
||||||
|
community: CommunityData;
|
||||||
|
setShowChannels: (val: boolean) => void;
|
||||||
|
setShowMembersList: (val: boolean) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function NarrowMembers({
|
||||||
|
theme,
|
||||||
|
community,
|
||||||
|
setShowChannels,
|
||||||
|
setShowMembersList,
|
||||||
|
}: NarrowMembersProps) {
|
||||||
|
return (
|
||||||
|
<ListWrapper>
|
||||||
|
<NarrowTopbar
|
||||||
|
theme={theme}
|
||||||
|
list="Community members"
|
||||||
|
community={community.name}
|
||||||
|
onClick={() => setShowMembersList(false)}
|
||||||
|
/>
|
||||||
|
<MembersList
|
||||||
|
theme={theme}
|
||||||
|
community={community}
|
||||||
|
setShowChannels={setShowChannels}
|
||||||
|
/>
|
||||||
|
</ListWrapper>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const ListWrapper = styled.div`
|
||||||
|
padding: 18px;
|
||||||
|
`;
|
|
@ -4,6 +4,10 @@ export const GlobalStyle = createGlobalStyle`
|
||||||
* {
|
* {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
|
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
body,
|
body,
|
||||||
|
|
Loading…
Reference in New Issue