Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: add announcement , display room avatar , make room name clickable. #734

Merged
merged 8 commits into from
Jan 1, 2025
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 68 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 = () => {
Spiral-Memory marked this conversation as resolved.
Show resolved Hide resolved
if (announcementRef.current) {
setIsOverflowing(
announcementRef.current.scrollWidth >
announcementRef.current.clientWidth
);
}
};

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

return (
<>
{channelInfo.announcement && showAnnouncement && (
<Box css={styles.announcementStyles}>
<Box
ref={announcementRef}
css={[
styles.announcementTextBox,
css`
text-decoration: ${isOverflowing ? 'underline' : 'none'};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why adding a underline when overflowing ? Specific reason ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to give a hint to user that the announcement is clickable , but I just realized that in RC the underline appears only if the user hovers over the announcement , should I consider removing it in normal view?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yaa better remove it, keep it on hover only

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed the text underline in normal view

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.description && (
<>
<Box css={styles.infoHeader}>Topic</Box>
<Box css={styles.info}>{channelInfo.topic}</Box>
</>
)}
{channelInfo.description && (
<>
<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;
Loading