diff --git a/packages/react-chat/src/components/Chat/ChatBody.tsx b/packages/react-chat/src/components/Chat/ChatBody.tsx index fa63c49..470c3e7 100644 --- a/packages/react-chat/src/components/Chat/ChatBody.tsx +++ b/packages/react-chat/src/components/Chat/ChatBody.tsx @@ -9,7 +9,9 @@ import { CommunityData } from "../../models/CommunityData"; import { Channel } from "../Channels/Channel"; import { EmptyChannel } from "../Channels/EmptyChannel"; import { Community } from "../Community"; +import { ChannelMenu } from "../Form/ChannelMenu"; import { MembersIcon } from "../Icons/MembersIcon"; +import { MoreIcon } from "../Icons/MoreIcon"; import { NarrowChannels } from "../NarrowMode/NarrowChannels"; import { NarrowMembers } from "../NarrowMode/NarrowMembers"; import { CommunitySkeleton } from "../Skeleton/CommunitySkeleton"; @@ -54,6 +56,7 @@ export function ChatBody({ const narrow = useNarrow(); const [showChannelsList, setShowChannelsList] = useState(false); const [showMembersList, setShowMembersList] = useState(false); + const [showChannelMenu, setShowChannelMenu] = useState(false); const className = useMemo(() => (narrow ? "narrow" : ""), [narrow]); const switchChannelList = useCallback(() => { @@ -101,17 +104,28 @@ export function ChatBody({ )} - switchMemberList() : onClick} - className={ - (showMembers && !narrow) || (showMembersList && narrow) - ? "active" - : "" - } - > - - + + {!narrow && ( + + + + )} + setShowChannelMenu(!showChannelMenu)}> + + + {!community && } + {showChannelMenu && ( + + )} {messenger && community ? ( <> @@ -220,12 +234,33 @@ const CommunityWrap = styled.div` } `; +const MenuWrapper = styled.div` + display: flex; + align-items: center; +`; + const MemberBtn = styled.button` width: 32px; height: 32px; border-radius: 8px; padding: 0; - margin-top: 12px; + + &:hover { + background: ${({ theme }) => theme.border}; + } + + &:active, + &.active { + background: ${({ theme }) => theme.inputColor}; + } +`; + +const MoreBtn = styled.button` + width: 32px; + height: 32px; + border-radius: 8px; + padding: 0; + margin: 0 8px; &:hover { background: ${({ theme }) => theme.border}; diff --git a/packages/react-chat/src/components/Form/ChannelMenu.tsx b/packages/react-chat/src/components/Form/ChannelMenu.tsx new file mode 100644 index 0000000..a4fdf4d --- /dev/null +++ b/packages/react-chat/src/components/Form/ChannelMenu.tsx @@ -0,0 +1,153 @@ +import React from "react"; +import styled from "styled-components"; + +import { useMessengerContext } from "../../contexts/messengerProvider"; +import { useNarrow } from "../../contexts/narrowProvider"; +import { ChannelData } from "../../models/ChannelData"; +import { ChatMessage } from "../../models/ChatMessage"; +import { textSmallStyles } from "../Text"; + +interface ChannelMenuProps { + channel: ChannelData; + + messages: ChatMessage[]; + switchMemberList: () => void; + setShowChannelMenu: (val: boolean) => void; +} + +export const ChannelMenu = ({ + channel, + + messages, + switchMemberList, + setShowChannelMenu, +}: ChannelMenuProps) => { + const narrow = useNarrow(); + const { clearNotifications } = useMessengerContext(); + + return ( + + + {narrow && ( + { + switchMemberList(); + setShowChannelMenu(false); + }} + > + + + + + View members + + )} + channel.isMuted === true}> + + + + Mute Chat + + clearNotifications(channel.id)}> + + + + + Mark as Read + + messages.length === 0}> + + + + + Clear History + + + + ); +}; + +const MenuBlock = styled.div` + width: 207px; + background: ${({ theme }) => theme.bodyBackgroundColor}; + box-shadow: 0px 2px 4px rgba(0, 34, 51, 0.16), + 0px 4px 12px rgba(0, 34, 51, 0.08); + borderradius: 8px; + padding: 8px 0; + position: absolute; + right: 8px; + top: calc(100% - 8px); + z-index: 2; +`; + +const MenuList = styled.ul` + list-style: none; +`; + +const MenuItem = styled.li` + width: 100%; + display: flex; + align-items: center; + padding: 8px 14px; + cursor: pointer; + color: ${({ theme }) => theme.primary}; + + &:hover { + background: ${({ theme }) => theme.tertiary}; + color: ${({ theme }) => theme.bodyBackgroundColor}; + } + + & > svg { + fill: ${({ theme }) => theme.tertiary}; + } + + &:hover > svg { + fill: ${({ theme }) => theme.bodyBackgroundColor}; + } +`; + +const MenuText = styled.span` + margin-left: 6px; + + ${textSmallStyles} +`; diff --git a/packages/react-chat/src/components/Icons/CheckIcon.tsx b/packages/react-chat/src/components/Icons/CheckIcon.tsx new file mode 100644 index 0000000..7d9575a --- /dev/null +++ b/packages/react-chat/src/components/Icons/CheckIcon.tsx @@ -0,0 +1,31 @@ +import React from "react"; +import styled from "styled-components"; + +export const CheckIcon = () => { + return ( + + + + + ); +}; + +const Icon = styled.svg` + & > path { + fill: ${({ theme }) => theme.tertiary}; + } + + &:hover > path { + fill: ${({ theme }) => theme.bodyBackgroundColor}; + } +`; diff --git a/packages/react-chat/src/components/Icons/ClearIcon.tsx b/packages/react-chat/src/components/Icons/ClearIcon.tsx new file mode 100644 index 0000000..384ed00 --- /dev/null +++ b/packages/react-chat/src/components/Icons/ClearIcon.tsx @@ -0,0 +1,31 @@ +import React from "react"; +import styled from "styled-components"; + +export const ClearIcon = () => { + return ( + + + + + ); +}; + +const Icon = styled.svg` + & > path { + fill: ${({ theme }) => theme.tertiary}; + } + + &:hover > path { + fill: ${({ theme }) => theme.bodyBackgroundColor}; + } +`; diff --git a/packages/react-chat/src/components/Icons/MoreIcon.tsx b/packages/react-chat/src/components/Icons/MoreIcon.tsx new file mode 100644 index 0000000..39d257c --- /dev/null +++ b/packages/react-chat/src/components/Icons/MoreIcon.tsx @@ -0,0 +1,24 @@ +import React from "react"; +import styled from "styled-components"; + +export const MoreIcon = () => { + return ( + + + + + + ); +}; + +const Icon = styled.svg` + & > path { + fill: ${({ theme }) => theme.primary}; + } +`; diff --git a/packages/react-chat/src/components/Icons/MuteIcon.tsx b/packages/react-chat/src/components/Icons/MuteIcon.tsx new file mode 100644 index 0000000..f6c4c08 --- /dev/null +++ b/packages/react-chat/src/components/Icons/MuteIcon.tsx @@ -0,0 +1,30 @@ +import React from "react"; +import styled from "styled-components"; + +export const MuteIcon = () => { + return ( + + + + ); +}; + +const Icon = styled.svg` + & > path { + fill: ${({ theme }) => theme.tertiary}; + } + + &:hover > path { + fill: ${({ theme }) => theme.bodyBackgroundColor}; + } +`;