Refactor channels and providers (#134)
This commit is contained in:
parent
7922343fa6
commit
4852d90546
|
@ -1,4 +1,4 @@
|
|||
import React, { useMemo } from "react";
|
||||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
|
||||
import { useNarrow } from "../../contexts/narrowProvider";
|
||||
|
@ -7,12 +7,51 @@ import { GroupIcon } from "../Icons/GroupIcon";
|
|||
import { MutedIcon } from "../Icons/MutedIcon";
|
||||
import { textMediumStyles } from "../Text";
|
||||
|
||||
function RenderChannelName({
|
||||
channel,
|
||||
className,
|
||||
}: {
|
||||
channel: ChannelData;
|
||||
className?: string;
|
||||
}) {
|
||||
switch (channel.type) {
|
||||
case "group":
|
||||
return (
|
||||
<div className={className}>
|
||||
<GroupIcon />
|
||||
{channel.name}
|
||||
</div>
|
||||
);
|
||||
case "channel":
|
||||
return <div className={className}>{`# ${channel.name}`}</div>;
|
||||
case "dm":
|
||||
return <div className={className}>{channel.name}</div>;
|
||||
}
|
||||
}
|
||||
|
||||
function ChannelIcon({
|
||||
channel,
|
||||
activeView,
|
||||
}: {
|
||||
channel: ChannelData;
|
||||
activeView?: boolean;
|
||||
}) {
|
||||
const narrow = useNarrow();
|
||||
return (
|
||||
<ChannelLogo
|
||||
icon={channel.icon}
|
||||
className={activeView ? "active" : narrow ? "narrow" : ""}
|
||||
>
|
||||
{!channel.icon && channel.name.slice(0, 1).toUpperCase()}
|
||||
</ChannelLogo>
|
||||
);
|
||||
}
|
||||
|
||||
interface ChannelProps {
|
||||
channel: ChannelData;
|
||||
notification?: number;
|
||||
notified?: boolean;
|
||||
mention?: number;
|
||||
isActive: boolean;
|
||||
isMuted: boolean;
|
||||
activeView?: boolean;
|
||||
onClick?: () => void;
|
||||
}
|
||||
|
@ -20,75 +59,48 @@ interface ChannelProps {
|
|||
export function Channel({
|
||||
channel,
|
||||
isActive,
|
||||
isMuted,
|
||||
activeView,
|
||||
onClick,
|
||||
notification,
|
||||
notified,
|
||||
mention,
|
||||
}: ChannelProps) {
|
||||
const narrow = useNarrow();
|
||||
const className = useMemo(
|
||||
() => (narrow && !activeView ? "narrow" : activeView ? "active" : ""),
|
||||
[narrow]
|
||||
);
|
||||
|
||||
return (
|
||||
<ChannelWrapper
|
||||
className={
|
||||
(isActive && !activeView) || (isActive && narrow) ? "active" : ""
|
||||
}
|
||||
style={{ width: narrow && activeView ? "calc(100% - 162px)" : "100%" }}
|
||||
className={`${isActive && "active"}`}
|
||||
isNarrow={narrow && activeView}
|
||||
onClick={onClick}
|
||||
>
|
||||
<ChannelInfo>
|
||||
<ChannelLogo
|
||||
style={{
|
||||
backgroundImage: channel.icon ? `url(${channel.icon}` : "",
|
||||
}}
|
||||
className={className}
|
||||
>
|
||||
{!channel.icon && channel.name.slice(0, 1).toUpperCase()}
|
||||
</ChannelLogo>
|
||||
<ChannelIcon channel={channel} activeView={activeView} />
|
||||
<ChannelTextInfo>
|
||||
<ChannelName
|
||||
className={
|
||||
isActive || narrow
|
||||
? "active"
|
||||
: notification && notification > 0
|
||||
? "notified"
|
||||
: isMuted
|
||||
? "muted"
|
||||
: ""
|
||||
}
|
||||
>
|
||||
{channel.type && channel.type === "group" ? (
|
||||
<GroupIcon />
|
||||
) : channel.type === "dm" ? (
|
||||
""
|
||||
) : (
|
||||
"#"
|
||||
)}{" "}
|
||||
{channel.name}
|
||||
</ChannelName>
|
||||
channel={channel}
|
||||
active={isActive || narrow}
|
||||
muted={channel?.isMuted}
|
||||
notified={notified}
|
||||
/>
|
||||
{activeView && (
|
||||
<ChannelDescription>{channel.description}</ChannelDescription>
|
||||
)}
|
||||
</ChannelTextInfo>
|
||||
</ChannelInfo>
|
||||
{notification && notification > 0 && !activeView && mention && (
|
||||
{!activeView && !!mention && mention > 0 && !channel?.isMuted && (
|
||||
<NotificationBagde>{mention}</NotificationBagde>
|
||||
)}
|
||||
{isMuted && !notification && <MutedIcon />}
|
||||
{channel?.isMuted && <MutedIcon />}
|
||||
</ChannelWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
const ChannelWrapper = styled.div`
|
||||
const ChannelWrapper = styled.div<{ isNarrow?: boolean }>`
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 8px;
|
||||
cursor: pointer;
|
||||
|
||||
width: ${({ isNarrow }) => (isNarrow ? "calc(100% - 162px)" : "100%")};
|
||||
&.active {
|
||||
background-color: ${({ theme }) => theme.activeChannelBackground};
|
||||
border-radius: 8px;
|
||||
|
@ -109,7 +121,7 @@ const ChannelTextInfo = styled.div`
|
|||
white-space: nowrap;
|
||||
`;
|
||||
|
||||
export const ChannelLogo = styled.div`
|
||||
export const ChannelLogo = styled.div<{ icon?: string }>`
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
display: flex;
|
||||
|
@ -124,45 +136,37 @@ export const ChannelLogo = styled.div`
|
|||
background-color: ${({ theme }) => theme.iconColor};
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
backgroundimage: ${({ icon }) => icon && `url(${icon}`};
|
||||
color: ${({ theme }) => theme.iconTextColor};
|
||||
|
||||
&.active {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
font-size: 20px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
&.narrow {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
font-size: 20px;
|
||||
line-height: 20px;
|
||||
}
|
||||
`;
|
||||
|
||||
export const ChannelName = styled.div`
|
||||
font-weight: 500;
|
||||
opacity: 0.7;
|
||||
export const ChannelName = styled(RenderChannelName)<{
|
||||
muted?: boolean;
|
||||
notified?: boolean;
|
||||
active?: boolean;
|
||||
}>`
|
||||
font-weight: ${({ notified, muted, active }) =>
|
||||
notified && !muted && !active ? "600" : "500"};
|
||||
opacity: ${({ notified, muted, active }) =>
|
||||
muted ? "0.4" : notified || active ? "1.0" : "0.7"};
|
||||
color: ${({ theme }) => theme.primary};
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
|
||||
${textMediumStyles}
|
||||
|
||||
&.active,
|
||||
&.notified {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&.muted {
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
&.notified {
|
||||
font-weight: 600;
|
||||
}
|
||||
`;
|
||||
|
||||
const ChannelDescription = styled.p`
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import React, { useEffect } from "react";
|
||||
import styled from "styled-components";
|
||||
|
||||
import { ChatState, useChatState } from "../../contexts/chatStateProvider";
|
||||
import { useMessengerContext } from "../../contexts/messengerProvider";
|
||||
import { CreateIcon } from "../Icons/CreateIcon";
|
||||
|
||||
import { Channel } from "./Channel";
|
||||
|
||||
interface ChannelsProps {
|
||||
setCreateChat: (val: boolean) => void;
|
||||
onCommunityClick?: () => void;
|
||||
}
|
||||
|
||||
|
@ -15,13 +15,10 @@ type GenerateChannelsProps = ChannelsProps & {
|
|||
type: string;
|
||||
};
|
||||
|
||||
function GenerateChannels({
|
||||
type,
|
||||
onCommunityClick,
|
||||
setCreateChat,
|
||||
}: GenerateChannelsProps) {
|
||||
function GenerateChannels({ type, onCommunityClick }: GenerateChannelsProps) {
|
||||
const { mentions, notifications, activeChannel, setActiveChannel, channels } =
|
||||
useMessengerContext();
|
||||
const setChatState = useChatState()[1];
|
||||
return (
|
||||
<>
|
||||
{Object.values(channels)
|
||||
|
@ -31,23 +28,14 @@ function GenerateChannels({
|
|||
key={channel.id}
|
||||
channel={channel}
|
||||
isActive={channel.id === activeChannel.id}
|
||||
isMuted={channel.isMuted || false}
|
||||
notification={
|
||||
notifications[channel.id] > 0 && !channel.isMuted
|
||||
? notifications[channel.id]
|
||||
: undefined
|
||||
}
|
||||
mention={
|
||||
mentions[channel.id] > 0 && !channel.isMuted
|
||||
? mentions[channel.id]
|
||||
: undefined
|
||||
}
|
||||
notified={notifications?.[channel.id] > 0}
|
||||
mention={mentions?.[channel.id]}
|
||||
onClick={() => {
|
||||
setActiveChannel(channel);
|
||||
if (onCommunityClick) {
|
||||
onCommunityClick();
|
||||
}
|
||||
setCreateChat(false);
|
||||
setChatState(ChatState.ChatBody);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
|
@ -55,7 +43,7 @@ function GenerateChannels({
|
|||
);
|
||||
}
|
||||
|
||||
export function Channels({ setCreateChat, onCommunityClick }: ChannelsProps) {
|
||||
export function Channels({ onCommunityClick }: ChannelsProps) {
|
||||
const { clearNotifications, clearMentions, notifications, activeChannel } =
|
||||
useMessengerContext();
|
||||
useEffect(() => {
|
||||
|
@ -66,19 +54,15 @@ export function Channels({ setCreateChat, onCommunityClick }: ChannelsProps) {
|
|||
}
|
||||
}
|
||||
}, [notifications, activeChannel]);
|
||||
|
||||
const setChatState = useChatState()[1];
|
||||
return (
|
||||
<ChannelList>
|
||||
<GenerateChannels
|
||||
type={"channel"}
|
||||
onCommunityClick={onCommunityClick}
|
||||
setCreateChat={setCreateChat}
|
||||
/>
|
||||
<GenerateChannels type={"channel"} onCommunityClick={onCommunityClick} />
|
||||
|
||||
<Chats>
|
||||
<ChatsBar>
|
||||
<Heading>Chat</Heading>
|
||||
<EditBtn onClick={() => setCreateChat(true)}>
|
||||
<EditBtn onClick={() => setChatState(ChatState.ChatCreation)}>
|
||||
<CreateIcon />
|
||||
</EditBtn>
|
||||
</ChatsBar>
|
||||
|
@ -86,13 +70,8 @@ export function Channels({ setCreateChat, onCommunityClick }: ChannelsProps) {
|
|||
<GenerateChannels
|
||||
type={"group"}
|
||||
onCommunityClick={onCommunityClick}
|
||||
setCreateChat={setCreateChat}
|
||||
/>
|
||||
<GenerateChannels
|
||||
type={"dm"}
|
||||
onCommunityClick={onCommunityClick}
|
||||
setCreateChat={setCreateChat}
|
||||
/>
|
||||
<GenerateChannels type={"dm"} onCommunityClick={onCommunityClick} />
|
||||
</ChatsList>
|
||||
</Chats>
|
||||
</ChannelList>
|
||||
|
|
|
@ -16,17 +16,11 @@ export function EmptyChannel({ channel }: EmptyChannelProps) {
|
|||
return (
|
||||
<Wrapper>
|
||||
<ChannelInfoEmpty>
|
||||
<ChannelLogoEmpty
|
||||
style={{
|
||||
backgroundImage: channel.icon ? `url(${channel.icon}` : "",
|
||||
}}
|
||||
>
|
||||
<ChannelLogoEmpty icon={channel.icon}>
|
||||
{" "}
|
||||
{!channel.icon && channel.name.slice(0, 1).toUpperCase()}
|
||||
</ChannelLogoEmpty>
|
||||
<ChannelNameEmpty className={"active"}>
|
||||
{channel.name.slice(0, 10)}
|
||||
</ChannelNameEmpty>
|
||||
<ChannelNameEmpty active={true} channel={channel} />
|
||||
</ChannelInfoEmpty>
|
||||
|
||||
{channel.type === "dm" ? (
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import React, { useState } from "react";
|
||||
import styled from "styled-components";
|
||||
|
||||
import { ChatState, useChatState } from "../contexts/chatStateProvider";
|
||||
import { useNarrow } from "../contexts/narrowProvider";
|
||||
|
||||
import { Channels } from "./Channels/Channels";
|
||||
|
@ -23,9 +24,8 @@ function Modals() {
|
|||
}
|
||||
|
||||
export function Chat() {
|
||||
const [showMembers, setShowMembers] = useState(true);
|
||||
const [createChat, setCreateChat] = useState(false);
|
||||
|
||||
const [state] = useChatState();
|
||||
const [showMembers, setShowMembers] = useState(false);
|
||||
const narrow = useNarrow();
|
||||
|
||||
return (
|
||||
|
@ -33,18 +33,17 @@ export function Chat() {
|
|||
{!narrow && (
|
||||
<ChannelsWrapper>
|
||||
<StyledCommunity />
|
||||
<Channels setCreateChat={setCreateChat} />
|
||||
<Channels />
|
||||
</ChannelsWrapper>
|
||||
)}
|
||||
{!createChat && (
|
||||
{state === ChatState.ChatBody && (
|
||||
<ChatBody
|
||||
onClick={() => setShowMembers(!showMembers)}
|
||||
showMembers={showMembers}
|
||||
setCreateChat={setCreateChat}
|
||||
/>
|
||||
)}
|
||||
{showMembers && !narrow && !createChat && <Members />}
|
||||
{createChat && <ChatCreation setCreateChat={setCreateChat} />}
|
||||
{showMembers && !narrow && state === ChatState.ChatBody && <Members />}
|
||||
{state === ChatState.ChatCreation && <ChatCreation />}
|
||||
<Modals />
|
||||
</ChatWrapper>
|
||||
);
|
||||
|
|
|
@ -27,14 +27,9 @@ enum ChatBodyState {
|
|||
interface ChatBodyProps {
|
||||
onClick: () => void;
|
||||
showMembers: boolean;
|
||||
setCreateChat: (val: boolean) => void;
|
||||
}
|
||||
|
||||
export function ChatBody({
|
||||
onClick,
|
||||
showMembers,
|
||||
setCreateChat,
|
||||
}: ChatBodyProps) {
|
||||
export function ChatBody({ onClick, showMembers }: ChatBodyProps) {
|
||||
const { messenger, activeChannel, communityData } = useMessengerContext();
|
||||
const narrow = useNarrow();
|
||||
const [showChannelMenu, setShowChannelMenu] = useState(false);
|
||||
|
@ -61,7 +56,7 @@ export function ChatBody({
|
|||
return (
|
||||
<ChatBodyWrapper className={className}>
|
||||
{editGroup && communityData ? (
|
||||
<ChatCreation setCreateChat={setCreateChat} editGroup={editGroup} />
|
||||
<ChatCreation editGroup={editGroup} />
|
||||
) : (
|
||||
<ChatTopbar
|
||||
className={narrow && showState !== ChatBodyState.Chat ? "narrow" : ""}
|
||||
|
@ -78,10 +73,9 @@ export function ChatBody({
|
|||
<Channel
|
||||
channel={activeChannel}
|
||||
isActive={
|
||||
narrow ? showState === ChatBodyState.Channels : true
|
||||
narrow ? showState === ChatBodyState.Channels : false
|
||||
}
|
||||
activeView={true}
|
||||
isMuted={false}
|
||||
onClick={() => switchShowState(ChatBodyState.Channels)}
|
||||
/>
|
||||
</>
|
||||
|
@ -132,7 +126,6 @@ export function ChatBody({
|
|||
{showState === ChatBodyState.Channels && (
|
||||
<NarrowChannels
|
||||
setShowChannels={() => switchShowState(ChatBodyState.Channels)}
|
||||
setCreateChat={setCreateChat}
|
||||
/>
|
||||
)}
|
||||
{showState === ChatBodyState.Members && (
|
||||
|
|
|
@ -2,6 +2,7 @@ import React, { useCallback, useState } from "react";
|
|||
import { bufToHex } from "status-communities/dist/cjs/utils";
|
||||
import styled from "styled-components";
|
||||
|
||||
import { ChatState, useChatState } from "../../contexts/chatStateProvider";
|
||||
import { useIdentity } from "../../contexts/identityProvider";
|
||||
import { useMessengerContext } from "../../contexts/messengerProvider";
|
||||
import { buttonStyles } from "../Buttons/buttonStyle";
|
||||
|
@ -10,16 +11,16 @@ import { Member } from "../Members/Member";
|
|||
import { SearchBlock } from "../SearchBlock";
|
||||
import { textMediumStyles } from "../Text";
|
||||
interface ChatCreationProps {
|
||||
setCreateChat: (val: boolean) => void;
|
||||
editGroup?: boolean;
|
||||
}
|
||||
|
||||
export function ChatCreation({ setCreateChat, editGroup }: ChatCreationProps) {
|
||||
export function ChatCreation({ editGroup }: ChatCreationProps) {
|
||||
const identity = useIdentity();
|
||||
const [query, setQuery] = useState("");
|
||||
const [styledGroup, setStyledGroup] = useState<string[]>([]);
|
||||
|
||||
const { contacts, setChannel } = useMessengerContext();
|
||||
const setChatState = useChatState()[1];
|
||||
|
||||
const addMember = useCallback(
|
||||
(member: string) => {
|
||||
|
@ -51,7 +52,7 @@ export function ChatCreation({ setCreateChat, editGroup }: ChatCreationProps) {
|
|||
type: "dm",
|
||||
description: "Contact",
|
||||
});
|
||||
setCreateChat(false);
|
||||
setChatState(ChatState.ChatBody);
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import React, { useState } from "react";
|
||||
import { Identity } from "status-communities/dist/cjs";
|
||||
|
||||
import { ChatStateProvider } from "../contexts/chatStateProvider";
|
||||
import { IdentityProvider } from "../contexts/identityProvider";
|
||||
import { MessengerProvider } from "../contexts/messengerProvider";
|
||||
|
||||
|
@ -18,7 +19,9 @@ export function ChatLoader({ communityKey }: ChatLoaderProps) {
|
|||
return (
|
||||
<IdentityProvider identity={identity}>
|
||||
<MessengerProvider identity={identity} communityKey={communityKey}>
|
||||
<ChatStateProvider>
|
||||
<Chat />
|
||||
</ChatStateProvider>
|
||||
</MessengerProvider>
|
||||
</IdentityProvider>
|
||||
);
|
||||
|
|
|
@ -2,7 +2,6 @@ import React, { useMemo } from "react";
|
|||
import { bufToHex } from "status-communities/dist/cjs/utils";
|
||||
import styled from "styled-components";
|
||||
|
||||
import { useFriends } from "../../contexts/friendsProvider";
|
||||
import { useIdentity } from "../../contexts/identityProvider";
|
||||
import { useModal } from "../../contexts/modalProvider";
|
||||
import { useManageContact } from "../../hooks/useManageContact";
|
||||
|
@ -33,10 +32,8 @@ export function ContactMenu({ id, setShowMenu }: ContactMenuProps) {
|
|||
);
|
||||
|
||||
const { setModal } = useModal(ProfileModalName);
|
||||
const { friends, setFriends } = useFriends();
|
||||
|
||||
const userIsFriend = useMemo(() => friends.includes(id), [friends, id]);
|
||||
const { contact, setBlocked, setIsUntrustworthy } = useManageContact(id);
|
||||
const { contact, setBlocked, setIsUntrustworthy, setIsUserFriend } =
|
||||
useManageContact(id);
|
||||
|
||||
if (!contact) return null;
|
||||
return (
|
||||
|
@ -63,13 +60,13 @@ export function ContactMenu({ id, setShowMenu }: ContactMenuProps) {
|
|||
<ProfileSvg width={16} height={16} />
|
||||
<MenuText>View Profile</MenuText>
|
||||
</MenuItem>
|
||||
{!userIsFriend && (
|
||||
<MenuItem onClick={() => setFriends((prev) => [...prev, id])}>
|
||||
{!contact.isFriend && (
|
||||
<MenuItem onClick={() => setIsUserFriend(true)}>
|
||||
<AddContactSvg width={16} height={16} />
|
||||
<MenuText>Send Contact Request</MenuText>
|
||||
</MenuItem>
|
||||
)}
|
||||
{userIsFriend && (
|
||||
{contact.isFriend && (
|
||||
<MenuItem>
|
||||
<ChatSvg width={16} height={16} />
|
||||
<MenuText>Send Message</MenuText>
|
||||
|
@ -98,7 +95,7 @@ export function ContactMenu({ id, setShowMenu }: ContactMenuProps) {
|
|||
</MenuText>
|
||||
</MenuItem>
|
||||
|
||||
{!userIsFriend && !isUser && (
|
||||
{!contact.isFriend && !isUser && (
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
setBlocked(!contact.blocked);
|
||||
|
|
|
@ -55,15 +55,7 @@ export const EditModal = () => {
|
|||
</NameSection>
|
||||
<LogoSection>
|
||||
<Label>Group image</Label>
|
||||
<GroupLogo
|
||||
style={{
|
||||
backgroundImage: image
|
||||
? `url(${image}`
|
||||
: activeChannel.icon
|
||||
? `url(${activeChannel.icon}`
|
||||
: "",
|
||||
}}
|
||||
>
|
||||
<GroupLogo icon={image || activeChannel.icon}>
|
||||
{!activeChannel.icon &&
|
||||
!image &&
|
||||
activeChannel.name.slice(0, 1).toUpperCase()}
|
||||
|
|
|
@ -2,7 +2,6 @@ import React, { useEffect, useMemo, useState } from "react";
|
|||
import { bufToHex } from "status-communities/dist/cjs/utils";
|
||||
import styled from "styled-components";
|
||||
|
||||
import { useFriends } from "../../contexts/friendsProvider";
|
||||
import { useIdentity } from "../../contexts/identityProvider";
|
||||
import { useModal } from "../../contexts/modalProvider";
|
||||
import { useManageContact } from "../../hooks/useManageContact";
|
||||
|
@ -40,17 +39,18 @@ export const ProfileModal = () => {
|
|||
[id, identity]
|
||||
);
|
||||
|
||||
const { friends, setFriends } = useFriends();
|
||||
|
||||
const userIsFriend = useMemo(() => friends.includes(id), [friends, id]);
|
||||
|
||||
const [renaming, setRenaming] = useState(renamingState ?? false);
|
||||
useEffect(() => {
|
||||
setRenaming(renamingState ?? false);
|
||||
}, [renamingState]);
|
||||
|
||||
const { contact, setBlocked, setCustomName, setIsUntrustworthy } =
|
||||
useManageContact(id);
|
||||
const {
|
||||
contact,
|
||||
setBlocked,
|
||||
setCustomName,
|
||||
setIsUntrustworthy,
|
||||
setIsUserFriend,
|
||||
} = useManageContact(id);
|
||||
const [customNameInput, setCustomNameInput] = useState("");
|
||||
|
||||
if (!contact) return null;
|
||||
|
@ -134,7 +134,7 @@ export const ProfileModal = () => {
|
|||
</>
|
||||
) : (
|
||||
<>
|
||||
{!userIsFriend && !isUser && (
|
||||
{!contact.isFriend && !isUser && (
|
||||
<ProfileBtn
|
||||
className={contact.blocked ? "" : "red"}
|
||||
onClick={() => {
|
||||
|
@ -144,12 +144,10 @@ export const ProfileModal = () => {
|
|||
{contact.blocked ? "Unblock" : "Block"}
|
||||
</ProfileBtn>
|
||||
)}
|
||||
{userIsFriend && (
|
||||
{contact.isFriend && (
|
||||
<ProfileBtn
|
||||
className="red"
|
||||
onClick={() =>
|
||||
setFriends((prev) => prev.filter((e) => e != id))
|
||||
}
|
||||
onClick={() => setIsUserFriend(false)}
|
||||
>
|
||||
Remove Contact
|
||||
</ProfileBtn>
|
||||
|
@ -162,8 +160,8 @@ export const ProfileModal = () => {
|
|||
? "Remove Untrustworthy Mark"
|
||||
: "Mark as Untrustworthy"}
|
||||
</ProfileBtn>
|
||||
{!userIsFriend && (
|
||||
<Btn onClick={() => setFriends((prev) => [...prev, id])}>
|
||||
{!contact.isFriend && (
|
||||
<Btn onClick={() => setIsUserFriend(true)}>
|
||||
Send Contact Request
|
||||
</Btn>
|
||||
)}
|
||||
|
|
|
@ -7,20 +7,13 @@ import { NarrowTopbar } from "./NarrowTopbar";
|
|||
|
||||
interface NarrowChannelsProps {
|
||||
setShowChannels: (val: boolean) => void;
|
||||
setCreateChat: (val: boolean) => void;
|
||||
}
|
||||
|
||||
export function NarrowChannels({
|
||||
setShowChannels,
|
||||
setCreateChat,
|
||||
}: NarrowChannelsProps) {
|
||||
export function NarrowChannels({ setShowChannels }: NarrowChannelsProps) {
|
||||
return (
|
||||
<ListWrapper>
|
||||
<NarrowTopbar list="Channels" />
|
||||
<Channels
|
||||
onCommunityClick={() => setShowChannels(false)}
|
||||
setCreateChat={setCreateChat}
|
||||
/>
|
||||
<Channels onCommunityClick={() => setShowChannels(false)} />
|
||||
</ListWrapper>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ import { ThemeProvider } from "styled-components";
|
|||
import styled from "styled-components";
|
||||
|
||||
import { FetchMetadataProvider } from "../contexts/fetchMetadataProvider";
|
||||
import { FriendsProvider } from "../contexts/friendsProvider";
|
||||
import { ModalProvider } from "../contexts/modalProvider";
|
||||
import { NarrowProvider } from "../contexts/narrowProvider";
|
||||
import { Metadata } from "../models/Metadata";
|
||||
|
@ -28,7 +27,6 @@ export function ReactChat({
|
|||
<ThemeProvider theme={theme}>
|
||||
<NarrowProvider myRef={ref}>
|
||||
<FetchMetadataProvider fetchMetadata={fetchMetadata}>
|
||||
<FriendsProvider>
|
||||
<ModalProvider>
|
||||
<Wrapper ref={ref}>
|
||||
<GlobalStyle />
|
||||
|
@ -36,7 +34,6 @@ export function ReactChat({
|
|||
<div id="modal-root" />
|
||||
</Wrapper>
|
||||
</ModalProvider>
|
||||
</FriendsProvider>
|
||||
</FetchMetadataProvider>
|
||||
</NarrowProvider>
|
||||
</ThemeProvider>
|
||||
|
|
|
@ -3,8 +3,8 @@ import styled from "styled-components";
|
|||
|
||||
import { useMessengerContext } from "../contexts/messengerProvider";
|
||||
|
||||
import { Channel } from "./Channels/Channel";
|
||||
import { ContactsList } from "./Chat/ChatCreation";
|
||||
import { Member } from "./Members/Member";
|
||||
|
||||
interface SearchBlockProps {
|
||||
query: string;
|
||||
|
@ -39,15 +39,9 @@ export const SearchBlock = ({
|
|||
.filter((member) => member.id.includes(query))
|
||||
.filter((member) => !dsicludeList.includes(member.id))
|
||||
.map((member) => (
|
||||
<Channel
|
||||
<Member
|
||||
key={member.id}
|
||||
channel={{
|
||||
id: member.id,
|
||||
name: member.id.slice(0, 10),
|
||||
type: "dm",
|
||||
}}
|
||||
isActive={false}
|
||||
isMuted={false}
|
||||
contact={member}
|
||||
onClick={() => onClick(member.id)}
|
||||
/>
|
||||
))}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
import React, { createContext, useContext, useState } from "react";
|
||||
|
||||
export enum ChatState {
|
||||
ChatCreation,
|
||||
ChatBody,
|
||||
}
|
||||
|
||||
type ChatStateContextType = [
|
||||
ChatState,
|
||||
React.Dispatch<React.SetStateAction<ChatState>>
|
||||
];
|
||||
|
||||
const ChatStateContext = createContext<ChatStateContextType>([
|
||||
ChatState.ChatBody,
|
||||
() => undefined,
|
||||
]);
|
||||
|
||||
export function useChatState() {
|
||||
return useContext(ChatStateContext);
|
||||
}
|
||||
|
||||
export function ChatStateProvider({ children }: { children: React.ReactNode }) {
|
||||
const state = useState(ChatState.ChatBody);
|
||||
return <ChatStateContext.Provider value={state} children={children} />;
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
import React, { createContext, useContext, useState } from "react";
|
||||
|
||||
const FriendsContext = createContext<{
|
||||
friends: string[];
|
||||
setFriends: React.Dispatch<React.SetStateAction<string[]>>;
|
||||
}>({
|
||||
friends: [],
|
||||
setFriends: () => undefined,
|
||||
});
|
||||
|
||||
export function useFriends() {
|
||||
return useContext(FriendsContext);
|
||||
}
|
||||
|
||||
interface FriendsProviderProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export function FriendsProvider({ children }: FriendsProviderProps) {
|
||||
const [friends, setFriends] = useState<string[]>([]);
|
||||
return (
|
||||
<FriendsContext.Provider
|
||||
value={{ friends, setFriends }}
|
||||
children={children}
|
||||
/>
|
||||
);
|
||||
}
|
|
@ -19,6 +19,7 @@ const MessengerContext = createContext<MessengerType>({
|
|||
activeChannel: {
|
||||
id: "",
|
||||
name: "",
|
||||
type: "channel",
|
||||
},
|
||||
channels: {},
|
||||
setChannel: () => undefined,
|
||||
|
|
|
@ -49,6 +49,7 @@ export function useMessenger(
|
|||
id: "",
|
||||
name: "",
|
||||
description: "",
|
||||
type: "channel",
|
||||
});
|
||||
|
||||
const chatId = useMemo(() => activeChannel.id, [activeChannel]);
|
||||
|
|
|
@ -38,5 +38,23 @@ export function useManageContact(id: string) {
|
|||
},
|
||||
[id]
|
||||
);
|
||||
return { contact, setCustomName, setBlocked, setIsUntrustworthy };
|
||||
|
||||
const setIsUserFriend = useCallback(
|
||||
(isFriend: boolean) => {
|
||||
setContacts((prev) => {
|
||||
const prevUser = prev[id];
|
||||
if (!prevUser) return prev;
|
||||
return { ...prev, [id]: { ...prevUser, isFriend } };
|
||||
});
|
||||
},
|
||||
[id]
|
||||
);
|
||||
|
||||
return {
|
||||
contact,
|
||||
setCustomName,
|
||||
setBlocked,
|
||||
setIsUntrustworthy,
|
||||
setIsUserFriend,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ import { Contact } from "./Contact";
|
|||
export type ChannelData = {
|
||||
id: string;
|
||||
name: string;
|
||||
type?: "channel" | "dm" | "group";
|
||||
type: "channel" | "dm" | "group";
|
||||
description?: string;
|
||||
icon?: string;
|
||||
isMuted?: boolean;
|
||||
|
|
|
@ -5,6 +5,7 @@ export type Contact = {
|
|||
customName?: string;
|
||||
isUntrustworthy: boolean;
|
||||
blocked: boolean;
|
||||
isFriend?: boolean;
|
||||
};
|
||||
|
||||
export type Contacts = {
|
||||
|
|
|
@ -14,7 +14,6 @@ export const GlobalStyle = createGlobalStyle`
|
|||
html {
|
||||
margin: 0;
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-weight: normal;
|
||||
font-size: 15px;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue