Skip to content

Commit

Permalink
Feat: add announcement , display room avatar , make room name clickab…
Browse files Browse the repository at this point in the history
…le. (RocketChat#734)

* Added room announcement feature , display avatar and make room name clickable

* remove showChannelAvatar from ECOptions

* Add padding

* Add padding to modal

* Remove text underline in announcement in normal view

* add showAnnouncement dependency to useEffect

* Run prettier

* replace channelInfo.description
  • Loading branch information
abirc8010 authored and SinghaAnirban005 committed Jan 1, 2025
1 parent d78e1b8 commit 60567a0
Show file tree
Hide file tree
Showing 7 changed files with 193 additions and 43 deletions.
75 changes: 70 additions & 5 deletions packages/react/src/views/ChatBody/ChatBody.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
/* eslint-disable no-shadow */
import React, { useCallback, useContext, useEffect, useState } from 'react';
import React, {
useCallback,
useContext,
useEffect,
useState,
useRef,
} from 'react';
import PropTypes from 'prop-types';
import { css } from '@emotion/react';
import {
Box,
Throbber,
useComponentOverrides,
Modal,
useTheme,
} from '@embeddedchat/ui-elements';
import RCContext from '../../context/RCInstance';
import {
Expand Down Expand Up @@ -33,21 +41,23 @@ const ChatBody = ({
scrollToBottom,
}) => {
const { classNames, styleOverrides } = useComponentOverrides('ChatBody');

const styles = getChatbodyStyles();
const { theme, mode } = useTheme();
const styles = getChatbodyStyles(theme, mode);
const [scrollPosition, setScrollPosition] = useState(0);
const [popupVisible, setPopupVisible] = useState(false);
const [, setIsUserScrolledUp] = useState(false);
const [otherUserMessage, setOtherUserMessage] = useState(false);

const [isOverflowing, setIsOverflowing] = useState(false);
const { RCInstance, ECOptions } = useContext(RCContext);
const showAnnouncement = ECOptions?.showAnnouncement;
const messages = useMessageStore((state) => state.messages);
const threadMessages = useMessageStore((state) => state.threadMessages);

const [isModalOpen, setModalOpen] = useState(false);
const setThreadMessages = useMessageStore((state) => state.setThreadMessages);
const upsertMessage = useMessageStore((state) => state.upsertMessage);
const removeMessage = useMessageStore((state) => state.removeMessage);
const isChannelPrivate = useChannelStore((state) => state.isChannelPrivate);
const channelInfo = useChannelStore((state) => state.channelInfo);
const isLoginIn = useLoginStore((state) => state.isLoginIn);

const [isThreadOpen, threadMainMessage] = useMessageStore((state) => [
Expand Down Expand Up @@ -182,7 +192,24 @@ const ChatBody = ({
const showNewMessagesPopup = () => {
setPopupVisible(true);
};
const announcementRef = useRef(null);

const toggleModal = () => {
setModalOpen(!isModalOpen);
};

const checkOverflow = () => {
if (announcementRef.current) {
setIsOverflowing(
announcementRef.current.scrollWidth >
announcementRef.current.clientWidth
);
}
};

useEffect(() => {
checkOverflow();
}, [channelInfo.announcement, showAnnouncement]);
useEffect(() => {
const currentRef = messageListRef.current;
currentRef.addEventListener('scroll', handleScroll);
Expand All @@ -204,6 +231,44 @@ const ChatBody = ({

return (
<>
{channelInfo.announcement && showAnnouncement && (
<Box css={styles.announcementStyles}>
<Box
ref={announcementRef}
css={[
styles.announcementTextBox,
css`
&:hover {
text-decoration: ${isOverflowing ? 'underline' : 'none'};
cursor: ${isOverflowing ? 'pointer' : 'default'};
}
`,
]}
onClick={isOverflowing ? toggleModal : undefined}
>
{channelInfo.announcement}
</Box>
</Box>
)}
{isModalOpen && (
<Modal>
<Modal.Header>
<Modal.Title>Announcement</Modal.Title>
<Modal.Close onClick={toggleModal} />
</Modal.Header>
<Modal.Content
css={css`
height: 300px;
word-wrap: break-word;
overflow-wrap: anywhere;
white-space: normal;
padding: 20px;
`}
>
{channelInfo.announcement}
</Modal.Content>
</Modal>
)}
<Box
ref={messageListRef}
css={styles.chatbodyContainer}
Expand Down
20 changes: 19 additions & 1 deletion packages/react/src/views/ChatBody/ChatBody.styles.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { css } from '@emotion/react';
import { darken, lighten } from '@embeddedchat/ui-elements';

export const getChatbodyStyles = () => {
export const getChatbodyStyles = (theme, mode) => {
const styles = {
chatbodyContainer: css`
flex: 1;
Expand All @@ -14,6 +15,23 @@ export const getChatbodyStyles = () => {
padding-top: 70px;
margin-top: 0.25rem;
`,
announcementStyles: css`
display: flex;
justify-content: center;
padding: 7px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
background-color: ${mode === 'light'
? lighten(theme.colors.info, 0.78)
: darken(theme.colors.primary, 0.7)};
`,
announcementTextBox: css`
max-width: 80%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
`,
};

return styles;
Expand Down
49 changes: 38 additions & 11 deletions packages/react/src/views/ChatHeader/ChatHeader.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { useCallback, useEffect, useMemo } from 'react';
import { css } from '@emotion/react';
import PropTypes from 'prop-types';
import {
Box,
Expand All @@ -8,6 +9,7 @@ import {
useToastBarDispatch,
useComponentOverrides,
useTheme,
Avatar,
} from '@embeddedchat/ui-elements';
import { useRCContext } from '../../context/RCInstance';
import {
Expand Down Expand Up @@ -115,7 +117,10 @@ const ChatHeader = ({
);
const setShowAllFiles = useFileStore((state) => state.setShowAllFiles);
const setShowMentions = useMentionsStore((state) => state.setShowMentions);

const getChannelAvatarURL = (channelname) => {
const host = RCInstance.getHost();
return `${host}/avatar/${channelname}`;
};
const handleGoBack = async () => {
if (isUserAuthenticated) {
getMessagesAndRoles();
Expand Down Expand Up @@ -347,25 +352,47 @@ const ChatHeader = ({
>
<Box css={styles.chatHeaderChild}>
<Box css={styles.channelDescription}>
<Icon name="hash" size={fullScreen ? '1.25rem' : '1rem'} />
<Box>
{isUserAuthenticated ? (
<>
<Heading
level={3}
className="ec-chat-header--channelName"
css={styles.clearSpacing}
style={{
display: 'flex',
alignItems: 'center',
gap: '0.2rem',
}}
>
{channelInfo.name || channelName || 'channelName'}
<Avatar
size="36px"
style={{ marginRight: '6px' }}
url={getChannelAvatarURL(channelInfo.name)}
/>
<Box>
<Box
css={styles.channelName}
onClick={() => setExclusiveState(setShowChannelinfo)}
>
<Icon
name="hash"
size={fullScreen ? '1.25rem' : '1rem'}
/>
<div>
{channelInfo.name || channelName || 'channelName'}
</div>
</Box>
{fullScreen && (
<Box
className="ec-chat-header--channelDescription"
css={styles.channelTopic}
>
{channelInfo.topic || ''}
</Box>
)}
</Box>
</Heading>
{fullScreen && (
<p
className="ec-chat-header--channelDescription"
css={styles.clearSpacing}
>
{channelInfo.description || ''}
</p>
)}
</>
) : (
<Heading
Expand Down
11 changes: 10 additions & 1 deletion packages/react/src/views/ChatHeader/ChatHeader.styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ const getChatHeaderStyles = ({ theme, mode }) => {
margin: 0;
padding: 0;
`,

chatHeaderChild: css`
${rowCentreAlign}
padding: 0 0.75rem;
Expand Down Expand Up @@ -43,6 +42,16 @@ const getChatHeaderStyles = ({ theme, mode }) => {
position:relative;
gap: 0.5rem;
`,
channelName: css`
display: flex;
align-items: center;
gap: 0.1rem;
cursor: pointer;
`,
channelTopic: css`
opacity: 0.8rem;
font-size: 1rem;
`,
};
return styles;
};
Expand Down
4 changes: 4 additions & 0 deletions packages/react/src/views/EmbeddedChat.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const EmbeddedChat = (props) => {
toastBarPosition = 'bottom right',
showRoles = false,
showAvatar = true,
showAnnouncement = true,
showUsername = false,
showName = true,
enableThreads = false,
Expand Down Expand Up @@ -204,6 +205,7 @@ const EmbeddedChat = (props) => {
showName,
showRoles,
showAvatar,
showAnnouncement,
showUsername,
hideHeader,
anonymousMode,
Expand All @@ -219,6 +221,7 @@ const EmbeddedChat = (props) => {
showName,
showRoles,
showAvatar,
showAnnouncement,
showUsername,
hideHeader,
anonymousMode,
Expand Down Expand Up @@ -281,6 +284,7 @@ EmbeddedChat.propTypes = {
toastBarPosition: PropTypes.string,
showRoles: PropTypes.bool,
showAvatar: PropTypes.bool,
showAnnouncement: PropTypes.bool,
enableThreads: PropTypes.bool,
theme: PropTypes.object,
auth: PropTypes.oneOfType([
Expand Down
52 changes: 27 additions & 25 deletions packages/react/src/views/RoomInformation/RoomInformation.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ import {
} from '@embeddedchat/ui-elements';
import RCContext from '../../context/RCInstance';
import { useChannelStore } from '../../store';
import getRoomInformationStyles from './RoomInformation.styles';
import useSetExclusiveState from '../../hooks/useSetExclusiveState';

const Roominfo = () => {
const { RCInstance } = useContext(RCContext);

const styles = getRoomInformationStyles();
const channelInfo = useChannelStore((state) => state.channelInfo);
const { variantOverrides } = useComponentOverrides('RoomMember');
const viewType = variantOverrides.viewType || 'Sidebar';
Expand Down Expand Up @@ -44,34 +45,35 @@ const Roominfo = () => {
overflow: auto;
`}
>
<Avatar size="100%" url={getChannelAvatarURL(channelInfo.name)} />
<Box
css={css`
margin: 16px;
width: 100%;
display: flex;
justify-content: center;
`}
>
<Box
css={css`
margin-block: 16px;
font-size: 1.25rem;
`}
>
# {channelInfo.name}
</Box>
<Box
css={css`
margin-block: 5px;
`}
>
Description
</Box>
<Box
css={css`
opacity: 0.5rem;
`}
>
{channelInfo.description}
</Box>
<Avatar size="100%" url={getChannelAvatarURL(channelInfo.name)} />
</Box>
<Box css={styles.infoContainer}>
<Box css={styles.infoHeader}># {channelInfo.name}</Box>
{channelInfo.description && (
<>
<Box css={styles.infoHeader}>Description</Box>
<Box css={styles.info}>{channelInfo.description}</Box>
</>
)}
{channelInfo.topic && (
<>
<Box css={styles.infoHeader}>Topic</Box>
<Box css={styles.info}>{channelInfo.topic}</Box>
</>
)}
{channelInfo.announcement && (
<>
<Box css={styles.infoHeader}>Announcement</Box>
<Box css={styles.info}>{channelInfo.announcement}</Box>
</>
)}
</Box>
</Box>
</ViewComponent>
Expand Down
25 changes: 25 additions & 0 deletions packages/react/src/views/RoomInformation/RoomInformation.styles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { css } from '@emotion/react';

const getRoomInformationStyles = () => {
const styles = {
infoContainer: css`
margin: 16px;
display: flex;
flex-direction: column;
gap: 0.1rem;
`,
infoHeader: css`
margin-block: 5px;
font-weight: 900;
`,
info: css`
word-wrap: break-word;
overflow-wrap: anywhere;
white-space: normal;
`,
};

return styles;
};

export default getRoomInformationStyles;

0 comments on commit 60567a0

Please sign in to comment.