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

Regression: Fix size of custom emoji and render emoji on thread message preview #25314

Merged
merged 20 commits into from
May 3, 2022
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import { BigEmoji as ASTBigEmoji } from '@rocket.chat/message-parser';
import React, { FC } from 'react';
import React, { ReactElement } from 'react';

import Emoji from '../../Emoji';
import MessageEmoji from '../MessageEmoji';

type BigEmojiProps = {
value: ASTBigEmoji['value'];
isThreadPreview?: boolean;
};

const BigEmoji: FC<BigEmojiProps> = ({ value }) => (
const BigEmoji = ({ value, isThreadPreview }: BigEmojiProps): ReactElement => (
<>
{value.map((block, index) => (
<Emoji className='big' key={index} emojiHandle={`:${block.value.value}:`} />
<MessageEmoji isThreadPreview={isThreadPreview} big emojiHandle={`:${block.value.value}:`} key={index} />
))}
</>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Paragraph as ASTParagraph } from '@rocket.chat/message-parser';
import React, { FC } from 'react';

import Emoji from '../../Emoji';
import MessageEmoji from '../MessageEmoji';
import Bold from './Bold';
import Image from './Image';
import InlineCode from './InlineCode';
Expand All @@ -11,36 +11,40 @@ import Mention from './Mention';
import MentionChannel from './MentionChannel';
import PlainText from './PlainText';
import Strike from './Strike';
import { useMessageBodyIsThreadPreview } from './contexts/MessageBodyContext';

const Inline: FC<{ value: ASTParagraph['value'] }> = ({ value = [] }) => (
<>
{value.map((block, index) => {
switch (block.type) {
case 'IMAGE':
return <Image key={index} value={block.value} />;
case 'PLAIN_TEXT':
return <PlainText key={index} value={block.value} />;
case 'BOLD':
return <Bold key={index} value={block.value} />;
case 'STRIKE':
return <Strike key={index} value={block.value} />;
case 'ITALIC':
return <Italic key={index} value={block.value} />;
case 'LINK':
return <Link key={index} value={block.value} />;
case 'MENTION_USER':
return <Mention key={index} value={block.value} />;
case 'MENTION_CHANNEL':
return <MentionChannel key={index} value={block.value} />;
case 'EMOJI':
return <Emoji key={index} emojiHandle={`:${block.value.value}:`} />;
case 'INLINE_CODE':
return <InlineCode key={index} value={block.value} />;
default:
return null;
}
})}
</>
);
const Inline: FC<{ value: ASTParagraph['value'] }> = ({ value = [] }) => {
const isThreadPreview = useMessageBodyIsThreadPreview();
return (
<>
{value.map((block, index) => {
switch (block.type) {
case 'IMAGE':
return <Image key={index} value={block.value} />;
case 'PLAIN_TEXT':
return <PlainText key={index} value={block.value} />;
case 'BOLD':
return <Bold key={index} value={block.value} />;
case 'STRIKE':
return <Strike key={index} value={block.value} />;
case 'ITALIC':
return <Italic key={index} value={block.value} />;
case 'LINK':
return <Link key={index} value={block.value} />;
case 'MENTION_USER':
return <Mention key={index} value={block.value} />;
case 'MENTION_CHANNEL':
return <MentionChannel key={index} value={block.value} />;
case 'EMOJI':
return <MessageEmoji isThreadPreview={isThreadPreview} key={index} emojiHandle={`:${block.value.value}:`} />;
case 'INLINE_CODE':
return <InlineCode key={index} value={block.value} />;
default:
return null;
}
})}
</>
);
};

export default Inline;
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { UserMention } from '../definitions/UserMention';
type MessageBodyContextType = {
mentions?: UserMention[];
channels?: ChannelMention[];
isThreadPreview?: boolean;
onUserMentionClick?: (username: string) => (e: MouseEvent<HTMLDivElement>) => void;
onChannelMentionClick?: (id: string) => (e: MouseEvent<HTMLDivElement>) => void;
};
Expand All @@ -17,6 +18,9 @@ export const MessageBodyContext = createContext<MessageBodyContextType>({

export const useMessageBodyContext = (): MessageBodyContextType => useContext(MessageBodyContext);

export const useMessageBodyIsThreadPreview = (): MessageBodyContextType['isThreadPreview'] =>
useContext(MessageBodyContext).isThreadPreview;

export const useMessageBodyUserMentions = (): UserMention[] => {
const { mentions = [] } = useMessageBodyContext();
return mentions;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,25 @@ type BodyProps = {
channels: ChannelMention[];
onUserMentionClick?: (username: string) => (e: MouseEvent<HTMLDivElement>) => void;
onChannelMentionClick?: (id: string) => (e: MouseEvent<HTMLDivElement>) => void;
isThreadPreview?: boolean;
};

const isBigEmoji = (tokens: MarkdownAST): tokens is [ASTBigEmoji] => tokens.length === 1 && tokens[0].type === 'BIG_EMOJI';

const MessageBodyRender: FC<BodyProps> = ({ tokens, mentions = [], channels = [], onUserMentionClick, onChannelMentionClick }) => {
const MessageBodyRender: FC<BodyProps> = ({
tokens,
mentions = [],
channels = [],
onUserMentionClick,
onChannelMentionClick,
isThreadPreview,
}) => {
if (isBigEmoji(tokens)) {
return <BigEmoji value={tokens[0].value} />;
return <BigEmoji value={tokens[0].value} isThreadPreview={isThreadPreview} />;
}

return (
<MessageBodyContext.Provider value={{ mentions, channels, onUserMentionClick, onChannelMentionClick }}>
<MessageBodyContext.Provider value={{ mentions, channels, onUserMentionClick, onChannelMentionClick, isThreadPreview }}>
{tokens.map((block, index) => {
if (block.type === 'UNORDERED_LIST') {
return <UnorderedList value={block.value} key={index} />;
Expand Down
30 changes: 30 additions & 0 deletions apps/meteor/client/components/Message/MessageEmoji.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { MessageEmoji as MessageEmojiBase, ThreadMessageEmoji } from '@rocket.chat/fuselage';
import React, { ReactElement } from 'react';

import { getEmojiClassNameAndDataTitle } from '../../lib/utils/renderEmoji';

type MessageEmojiProps = {
emojiHandle: string; // :emoji:
big?: boolean;
isThreadPreview?: boolean;
};

function MessageEmoji({ emojiHandle, big, isThreadPreview }: MessageEmojiProps): ReactElement {
const emojiProps = getEmojiClassNameAndDataTitle(emojiHandle);

if (!emojiProps.className && !emojiProps.name) {
return <>{emojiHandle}</>;
}

if (isThreadPreview) {
return <ThreadMessageEmoji {...emojiProps}>{emojiHandle}</ThreadMessageEmoji>;
}

return (
<MessageEmojiBase big={big} {...emojiProps}>
{emojiHandle}
</MessageEmojiBase>
);
}

export default MessageEmoji;
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ import { IMessage, isDiscussionMessage, isThreadMainMessage, ISubscription } fro
import { MessageBody } from '@rocket.chat/fuselage';
import React, { FC, memo } from 'react';

import { isE2EEMessage } from '../../../../../lib/isE2EEMessage';
import Attachments from '../../../../components/Message/Attachments';
import MessageActions from '../../../../components/Message/MessageActions';
import MessageBodyRender from '../../../../components/Message/MessageBodyRender';
import BroadcastMetric from '../../../../components/Message/Metrics/Broadcast';
import DiscussionMetric from '../../../../components/Message/Metrics/Discussion';
import ThreadMetric from '../../../../components/Message/Metrics/Thread';
Expand All @@ -19,9 +17,9 @@ import MessageLocation from '../../../location/MessageLocation';
import { useMessageActions, useMessageOembedIsEnabled, useMessageRunActionLink } from '../../contexts/MessageContext';
import { useMessageListShowReadReceipt } from '../contexts/MessageListContext';
import { isOwnUserMessage } from '../lib/isOwnUserMessage';
import EncryptedMessageRender from './EncryptedMessageRender';
import ReactionsList from './MessageReactionsList';
import ReadReceipt from './MessageReadReceipt';
import MessageRender from './MessageRender';
import PreviewList from './UrlPreview';

const MessageContent: FC<{ message: IMessage; sequential: boolean; subscription?: ISubscription; id: IMessage['_id'] }> = ({
Expand All @@ -30,15 +28,14 @@ const MessageContent: FC<{ message: IMessage; sequential: boolean; subscription?
}) => {
const {
broadcast,
actions: { openRoom, openThread, openUserCard, replyBroadcast },
actions: { openRoom, openThread, replyBroadcast },
} = useMessageActions();

const runActionLink = useMessageRunActionLink();

const oembedIsEnabled = useMessageOembedIsEnabled();
const shouldShowReadReceipt = useMessageListShowReadReceipt();
const user: UserPresence = { ...message.u, roles: [], ...useUserData(message.u._id) };
const isEncryptedMessage = isE2EEMessage(message);

const shouldShowReactionList = message.reactions && Object.keys(message.reactions).length;

Expand All @@ -47,19 +44,7 @@ const MessageContent: FC<{ message: IMessage; sequential: boolean; subscription?
return (
<>
<MessageBody data-qa-type='message-body'>
{!isEncryptedMessage && !message.blocks && message.md && (
<MessageBodyRender
onUserMentionClick={openUserCard}
onChannelMentionClick={openRoom}
mentions={message?.mentions || []}
channels={message?.channels || []}
tokens={message.md}
/>
)}

{!isEncryptedMessage && !message.blocks && !message.md && message.msg}

{isEncryptedMessage && <EncryptedMessageRender message={message} />}
<MessageRender message={message} />
</MessageBody>
{message.blocks && <MessageBlock mid={message._id} blocks={message.blocks} appId rid={message.rid} />}
{message.attachments && <Attachments attachments={message.attachments} file={message.file} />}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/* eslint-disable complexity */
import { IMessage } from '@rocket.chat/core-typings';
import React, { FC, memo } from 'react';

import { isE2EEMessage } from '../../../../../lib/isE2EEMessage';
import MessageBodyRender from '../../../../components/Message/MessageBodyRender';
import { useMessageActions } from '../../contexts/MessageContext';
import EncryptedMessageRender from './EncryptedMessageRender';

const MessageRender: FC<{ message: IMessage; isThreadPreview?: boolean }> = ({ message, isThreadPreview }) => {
const {
actions: { openRoom, openUserCard },
} = useMessageActions();

const isEncryptedMessage = isE2EEMessage(message);

return (
<>
{!isEncryptedMessage && !message.blocks && message.md && (
<MessageBodyRender
onUserMentionClick={openUserCard}
onChannelMentionClick={openRoom}
mentions={message?.mentions || []}
channels={message?.channels || []}
tokens={message.md}
isThreadPreview={isThreadPreview}
/>
)}

{!isEncryptedMessage && !message.blocks && !message.md && message.msg}

{isEncryptedMessage && <EncryptedMessageRender message={message} />}
</>
);
};

export default memo(MessageRender);
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { useMessageActions } from '../../contexts/MessageContext';
import { useIsSelecting, useToggleSelect, useIsSelectedMessage, useCountSelected } from '../contexts/SelectedMessagesContext';
import { useMessageBody } from '../hooks/useMessageBody';
import { useParentMessage } from '../hooks/useParentMessage';
import MessageRender from './MessageRender';

export const ThreadMessagePreview: FC<{ message: IThreadMessage; sequential: boolean }> = ({ message, sequential, ...props }) => {
const {
Expand Down Expand Up @@ -58,7 +59,9 @@ export const ThreadMessagePreview: FC<{ message: IThreadMessage; sequential: boo
{isSelecting && <CheckBox checked={isSelected} onChange={toggleSelected} />}
</ThreadMessageLeftContainer>
<ThreadMessageContainer>
<ThreadMessageBody>{message.ignored ? t('Message_Ignored') : message.msg}</ThreadMessageBody>
<ThreadMessageBody>
{message.ignored ? t('Message_Ignored') : <MessageRender isThreadPreview message={message} />}
</ThreadMessageBody>
</ThreadMessageContainer>
</ThreadMessageRow>
</ThreadMessageTemplate>
Expand Down