-
Notifications
You must be signed in to change notification settings - Fork 10.7k
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
[IMPROVE] Message rewrite code structure #24723
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import { IMessage } from '../../definition/IMessage'; | ||
|
||
export const isE2EEMessage = (message: IMessage): boolean => message.t === 'e2e'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,14 @@ | ||
/* eslint-disable complexity */ | ||
import { css } from '@rocket.chat/css-in-js'; | ||
import { | ||
Box, | ||
Message as MessageTemplate, | ||
MessageBody, | ||
MessageContainer, | ||
MessageHeader, | ||
MessageLeftContainer, | ||
MessageName, | ||
MessageRole, | ||
MessageRoles, | ||
MessageTimestamp, | ||
MessageUsername, | ||
MessageReactions, | ||
MessageStatusPrivateIndicator, | ||
MessageReactionAction, | ||
Icon, | ||
} from '@rocket.chat/fuselage'; | ||
import React, { FC, memo } from 'react'; | ||
|
||
|
@@ -28,32 +21,22 @@ import Broadcast from '../../../../components/Message/Metrics/Broadcast'; | |
import Discussion from '../../../../components/Message/Metrics/Discussion'; | ||
import Thread from '../../../../components/Message/Metrics/Thread'; | ||
import UserAvatar from '../../../../components/avatar/UserAvatar'; | ||
import { useSetting } from '../../../../contexts/SettingsContext'; | ||
import { TranslationKey, useTranslation } from '../../../../contexts/TranslationContext'; | ||
import { useUserId } from '../../../../contexts/UserContext'; | ||
import { useUserData } from '../../../../hooks/useUserData'; | ||
import { getUserDisplayName } from '../../../../lib/getUserDisplayName'; | ||
import { isE2EEMessage } from '../../../../lib/isE2EEMessage'; | ||
import { UserPresence } from '../../../../lib/presence'; | ||
import MessageBlock from '../../../blocks/MessageBlock'; | ||
import MessageLocation from '../../../location/MessageLocation'; | ||
import { | ||
useMessageActions, | ||
useMessageOembedIsEnabled, | ||
useMessageOembedMaxWidth, | ||
useMessageRunActionLink, | ||
} from '../../contexts/MessageContext'; | ||
import { | ||
useMessageListShowRoles, | ||
useMessageListShowUsername, | ||
useMessageListShowRealName, | ||
useOpenEmojiPicker, | ||
useReactionsFilter, | ||
useReactToMessage, | ||
useUserHasReacted, | ||
} from '../contexts/MessageListContext'; | ||
import { useMessageActions, useMessageRunActionLink } from '../../contexts/MessageContext'; | ||
import { useMessageListShowUsername, useMessageListShowRealName } from '../contexts/MessageListContext'; | ||
import { MessageIndicators } from './MessageIndicators'; | ||
import { MessageReaction } from './MessageReaction'; | ||
import ReactionsList from './MessageReactionsList'; | ||
import ReadReceipt from './MessageReadReceipt'; | ||
import RolesList from './MessageRolesList'; | ||
import Toolbox from './Toolbox'; | ||
import OEmbedList from './UrlPreview'; | ||
import PreviewList from './UrlPreview'; | ||
|
||
const Message: FC<{ message: IMessage; sequential: boolean; subscription?: ISubscription }> = ({ | ||
message, | ||
|
@@ -70,23 +53,15 @@ const Message: FC<{ message: IMessage; sequential: boolean; subscription?: ISubs | |
|
||
const runActionLink = useMessageRunActionLink(); | ||
|
||
const hasReacted = useUserHasReacted(message); | ||
const reactToMessage = useReactToMessage(message); | ||
const filterReactions = useReactionsFilter(message); | ||
|
||
const oembedIsEnabled = useMessageOembedIsEnabled(); | ||
const oembedWidth = useMessageOembedMaxWidth(); | ||
|
||
const openEmojiPicker = useOpenEmojiPicker(message); | ||
|
||
const isReadReceiptEnabled = useSetting('Message_Read_Receipt_Enabled'); | ||
|
||
const showRoles = useMessageListShowRoles(); | ||
const showRealName = useMessageListShowRealName(); | ||
const user: UserPresence = { ...message.u, roles: [], ...useUserData(message.u._id) }; | ||
const usernameAndRealNameAreSame = !user.name || user.username === user.name; | ||
const showUsername = useMessageListShowUsername() && showRealName && !usernameAndRealNameAreSame; | ||
|
||
const isEncryptedMessage = isE2EEMessage(message); | ||
const encryptedMessageIsPending = isEncryptedMessage && message.e2e === 'pending'; | ||
const messageIsReady = !isEncryptedMessage || !encryptedMessageIsPending; | ||
|
||
const mineUid = useUserId(); | ||
|
||
return ( | ||
|
@@ -103,7 +78,7 @@ const Message: FC<{ message: IMessage; sequential: boolean; subscription?: ISubs | |
data-username={user.username} | ||
onClick={user.username !== undefined ? openUserCard(user.username) : undefined} | ||
> | ||
{(showRealName && user.name) || user.username} | ||
{getUserDisplayName(user.name, user.username, showRealName)} | ||
</MessageName> | ||
{showUsername && ( | ||
<MessageUsername | ||
|
@@ -113,16 +88,9 @@ const Message: FC<{ message: IMessage; sequential: boolean; subscription?: ISubs | |
@{user.username} | ||
</MessageUsername> | ||
)} | ||
<MessageRoles> | ||
{showRoles && Array.isArray(user.roles) && user.roles.length > 0 && ( | ||
<> | ||
{user.roles.map((role, index) => ( | ||
<MessageRole key={index}>{role}</MessageRole> | ||
))} | ||
</> | ||
)} | ||
{message.bot && <MessageRole>{t('Bot')}</MessageRole>} | ||
</MessageRoles> | ||
|
||
<RolesList user={user} isBot={message.bot} /> | ||
|
||
<MessageTimestamp data-time={message.ts.toISOString()}>{formatters.messageHeader(message.ts)}</MessageTimestamp> | ||
{message.private && ( | ||
// The MessageStatusPrivateIndicator component should not have name prop, it should be fixed on fuselage | ||
|
@@ -131,14 +99,24 @@ const Message: FC<{ message: IMessage; sequential: boolean; subscription?: ISubs | |
<MessageIndicators message={message} /> | ||
</MessageHeader> | ||
)} | ||
<MessageBody> | ||
{/* <MessageBody> | ||
{message.e2e === 'pending' | ||
? t('E2E_message_encrypted_placeholder') | ||
: message.e2e !== 'done' && | ||
!message.blocks && | ||
message.md && <MessageBodyRender onMentionClick={openUserCard} mentions={message.mentions} tokens={message.md} />} | ||
{!message.blocks && !message.md && message.msg} | ||
{message.e2e === 'done' && message.msg} | ||
</MessageBody> */} | ||
|
||
<MessageBody> | ||
{encryptedMessageIsPending && t('E2E_message_encrypted_placeholder')} | ||
|
||
{messageIsReady && !message.blocks && message.md && ( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe some |
||
<MessageBodyRender onMentionClick={openUserCard} mentions={message.mentions} tokens={message.md} /> | ||
)} | ||
|
||
{messageIsReady && !message.blocks && !message.md && message.msg} | ||
</MessageBody> | ||
{message.blocks && <MessageBlock mid={message._id} blocks={message.blocks} appId rid={message.rid} />} | ||
{message.attachments && <Attachments attachments={message.attachments} file={message.file} />} | ||
|
@@ -158,21 +136,8 @@ const Message: FC<{ message: IMessage; sequential: boolean; subscription?: ISubs | |
runAction={runActionLink(message)} | ||
/> | ||
)} | ||
{message.reactions && Object.keys(message.reactions).length > 0 && ( | ||
<MessageReactions> | ||
{Object.entries(message.reactions).map(([name, reactions]) => ( | ||
<MessageReaction | ||
key={name} | ||
counter={reactions.usernames.length} | ||
hasReacted={hasReacted} | ||
reactToMessage={reactToMessage} | ||
name={name} | ||
names={filterReactions(name)} | ||
/> | ||
))} | ||
<MessageReactionAction onClick={openEmojiPicker} /> | ||
</MessageReactions> | ||
)} | ||
|
||
<ReactionsList message={message} /> | ||
|
||
{isThreadMainMessage(message) && ( | ||
<Thread | ||
|
@@ -202,23 +167,9 @@ const Message: FC<{ message: IMessage; sequential: boolean; subscription?: ISubs | |
{message.location && <MessageLocation location={message.location} />} | ||
{broadcast && user.username && <Broadcast replyBroadcast={replyBroadcast} mid={message._id} username={user.username} />} | ||
|
||
{oembedIsEnabled && message.urls && ( | ||
<Box width={oembedWidth}> | ||
<OEmbedList urls={message.urls} /> | ||
</Box> | ||
)} | ||
<PreviewList urls={message.urls} /> | ||
|
||
{isReadReceiptEnabled && ( | ||
<Box | ||
position='absolute' | ||
className={css` | ||
top: 2px; | ||
right: 0.5rem; | ||
`} | ||
> | ||
<Icon name='check' size='x11' color='primary' /> | ||
</Box> | ||
)} | ||
<ReadReceipt /> | ||
</MessageContainer> | ||
{!message.private && <Toolbox message={message} />} | ||
</MessageTemplate> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { MessageReactions, MessageReactionAction } from '@rocket.chat/fuselage'; | ||
import React, { ReactElement } from 'react'; | ||
|
||
import { IMessage } from '../../../../../definition/IMessage'; | ||
import { useOpenEmojiPicker, useReactionsFilter, useReactToMessage, useUserHasReacted } from '../contexts/MessageListContext'; | ||
import { MessageReaction } from './MessageReaction'; | ||
|
||
const MessageReactionsList = ({ message }: { message: IMessage }): ReactElement | null => { | ||
const hasReacted = useUserHasReacted(message); | ||
const reactToMessage = useReactToMessage(message); | ||
const filterReactions = useReactionsFilter(message); | ||
const openEmojiPicker = useOpenEmojiPicker(message); | ||
|
||
if (!message.reactions || !Object.keys(message.reactions).length) { | ||
return null; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This conditional should be on the parent component. example:
This way the component will not be loaded. |
||
|
||
return ( | ||
<MessageReactions> | ||
{Object.entries(message.reactions).map(([name, reactions]) => ( | ||
<MessageReaction | ||
key={name} | ||
counter={reactions.usernames.length} | ||
hasReacted={hasReacted} | ||
reactToMessage={reactToMessage} | ||
name={name} | ||
names={filterReactions(name)} | ||
/> | ||
))} | ||
<MessageReactionAction onClick={openEmojiPicker} /> | ||
</MessageReactions> | ||
); | ||
}; | ||
|
||
export default MessageReactionsList; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { css } from '@rocket.chat/css-in-js'; | ||
import { Box, Icon } from '@rocket.chat/fuselage'; | ||
import React, { ReactElement } from 'react'; | ||
|
||
import { useSetting } from '../../../../contexts/SettingsContext'; | ||
|
||
const MessageReadReceipt = (): ReactElement | null => { | ||
const isReadReceiptEnabled = useSetting('Message_Read_Receipt_Enabled'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe on MessageListProvider? can we centralize the Settings there. |
||
|
||
if (!isReadReceiptEnabled) { | ||
return null; | ||
} | ||
|
||
return ( | ||
<Box | ||
position='absolute' | ||
className={css` | ||
top: 2px; | ||
right: 0.5rem; | ||
`} | ||
> | ||
<Icon name='check' size='x11' color='primary' /> | ||
</Box> | ||
); | ||
}; | ||
|
||
export default MessageReadReceipt; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { MessageRole, MessageRoles } from '@rocket.chat/fuselage'; | ||
import React, { ReactElement } from 'react'; | ||
|
||
import { useTranslation } from '../../../../contexts/TranslationContext'; | ||
import { UserPresence } from '../../../../lib/presence'; | ||
import { useMessageListShowRoles } from '../contexts/MessageListContext'; | ||
|
||
type MessageRolesListProps = { | ||
user: UserPresence; | ||
isBot?: boolean; | ||
}; | ||
|
||
const MessageRolesList = ({ user, isBot }: MessageRolesListProps): ReactElement | null => { | ||
const t = useTranslation(); | ||
const showRoles = useMessageListShowRoles(); | ||
|
||
if (!showRoles || !user.roles || !Array.isArray(user.roles) || user.roles.length < 1) { | ||
return null; | ||
} | ||
|
||
return ( | ||
<MessageRoles> | ||
{user.roles.map((role, index) => ( | ||
<MessageRole key={index}>{role}</MessageRole> | ||
))} | ||
{isBot && <MessageRole>{t('Bot')}</MessageRole>} | ||
</MessageRoles> | ||
); | ||
}; | ||
|
||
export default MessageRolesList; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe when the variable is boolean it is good to put the prefix
is
.