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: Formatted text rendered by UI Kit #28060

Merged
merged 6 commits into from
Feb 16, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
25 changes: 3 additions & 22 deletions apps/meteor/app/ui-utils/client/lib/RoomHistoryManager.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { Meteor } from 'meteor/meteor';
import { Tracker } from 'meteor/tracker';
import { ReactiveVar } from 'meteor/reactive-var';
import { v4 as uuidv4 } from 'uuid';
import differenceInMilliseconds from 'date-fns/differenceInMilliseconds';
import { Emitter } from '@rocket.chat/emitter';
import type { IMessage, IRoom, ISubscription, IUser } from '@rocket.chat/core-typings';
import type { IMessage, IRoom, ISubscription } from '@rocket.chat/core-typings';
import type { MutableRefObject } from 'react';

import { waitForElement } from '../../../../client/lib/utils/waitForElement';
Expand All @@ -17,18 +16,15 @@ import {
setHighlightMessage,
clearHighlightMessage,
} from '../../../../client/views/room/MessageList/providers/messageHighlightSubscription';
import { normalizeThreadMessage } from '../../../../client/lib/normalizeThreadMessage';
import type { MinimongoCollection } from '../../../../client/definitions/MinimongoCollection';

export async function upsertMessage(
{
msg,
subscription,
uid = Tracker.nonreactive(() => Meteor.userId()) ?? undefined,
}: {
msg: IMessage & { ignored?: boolean };
subscription?: ISubscription;
uid?: IUser['_id'];
},
{ direct }: MinimongoCollection<IMessage> = ChatMessage,
) {
Expand All @@ -43,21 +39,7 @@ export async function upsertMessage(
}
msg = (await onClientMessageReceived(msg)) || msg;

const { _id, ...messageToUpsert } = msg;

if (msg.tcount) {
direct.update(
{ tmid: _id },
{
$set: {
following: uid && (msg.replies?.includes(uid) ?? false),
threadMsg: normalizeThreadMessage(messageToUpsert),
repliesCount: msg.tcount,
},
},
{ multi: true },
);
}
const { _id } = msg;

return direct.upsert({ _id }, msg);
}
Expand All @@ -66,14 +48,13 @@ export function upsertMessageBulk(
{ msgs, subscription }: { msgs: IMessage[]; subscription?: ISubscription },
collection: MinimongoCollection<IMessage> = ChatMessage,
) {
const uid = Tracker.nonreactive(() => Meteor.userId()) ?? undefined;
const { queries } = collection;
collection.queries = [];
msgs.forEach((msg, index) => {
if (index === msgs.length - 1) {
collection.queries = queries;
}
upsertMessage({ msg, subscription, uid }, collection);
upsertMessage({ msg, subscription }, collection);
});
}

Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/app/ui/client/lib/ChatMessages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export class ChatMessages implements ChatAPI {
await this.currentEditing.cancel();
},
editMessage: async (message: IMessage, { cursorAtStart = false }: { cursorAtStart?: boolean } = {}) => {
const text = (await this.data.getDraft(message._id)) || message.attachments?.[0].description || message.msg;
const text = (await this.data.getDraft(message._id)) || message.attachments?.[0]?.description || message.msg;

await this.currentEditing?.stop();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import {
useVideoConfManager,
useVideoConfSetPreferences,
} from '../../../contexts/VideoConfContext';
import { renderMessageBody } from '../../../lib/utils/renderMessageBody';
import { useVideoConfWarning } from '../../../views/room/contextualBar/VideoConference/useVideoConfWarning';
import ParsedText from './uikit/ParsedText';

let patched = false;
const patchMessageParser = () => {
Expand All @@ -33,11 +33,11 @@ const patchMessageParser = () => {
return <>{text}</>;
}

return <span dangerouslySetInnerHTML={{ __html: renderMessageBody({ msg: text }) }} />;
return <ParsedText text={text} />;
};

// TODO: move this to fuselage-ui-kit itself
messageParser.mrkdwn = ({ text }) => (text ? <span dangerouslySetInnerHTML={{ __html: renderMessageBody({ msg: text }) }} /> : null);
messageParser.mrkdwn = ({ text }) => <ParsedText text={text} />;
};

type UiKitSurfaceProps = {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { parse } from '@rocket.chat/message-parser';
import type { ReactElement } from 'react';
import React, { memo, useMemo } from 'react';

import MessageContentBody from '../../MessageContentBody';

const ParsedText = ({ text }: { text: string }): ReactElement | null => {
const md = useMemo(() => parse(text, { emoticons: true }), [text]);

return <MessageContentBody md={md} />;
};

export default memo(ParsedText);
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
import type { IMessage } from '@rocket.chat/core-typings';
import { escapeHTML } from '@rocket.chat/string-helpers';
import type { ReactElement } from 'react';
import React from 'react';

import { filterMarkdown } from '../../app/markdown/lib/markdown';
import { renderMessageBody } from './utils/renderMessageBody';
import ParsedText from '../components/message/content/uikit/ParsedText';

export function normalizeThreadMessage({ ...message }: Readonly<Pick<IMessage, 'msg' | 'mentions' | 'attachments'>>): string | undefined {
export function normalizeThreadMessage({ ...message }: Readonly<Pick<IMessage, 'msg' | 'mentions' | 'attachments'>>): ReactElement | null {
if (message.msg) {
message.msg = filterMarkdown(message.msg);
delete message.mentions;
return renderMessageBody(message).replace(/<br\s?\\?>/g, ' ');
return <ParsedText text={message.msg} />;
}

if (message.attachments) {
const attachment = message.attachments.find((attachment) => attachment.title || attachment.description);

if (attachment?.description) {
return escapeHTML(attachment.description);
return <>{attachment.description}</>;
}

if (attachment?.title) {
return escapeHTML(attachment.title);
return <>{attachment.title}</>;
}
}

return null;
}
16 changes: 0 additions & 16 deletions apps/meteor/client/lib/utils/renderMessageBody.ts

This file was deleted.

2 changes: 1 addition & 1 deletion apps/meteor/client/methods/updateMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ Meteor.methods({
msg: message.msg,
};

if (originalMessage.attachments) {
if (originalMessage.attachments?.length) {
if (originalMessage.attachments[0].description !== undefined) {
delete messageObject.msg;
originalMessage.attachments[0].description = message.msg;
Expand Down
6 changes: 2 additions & 4 deletions apps/meteor/client/views/blocks/textParsers.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
/* eslint-disable react/no-multi-comp */
/* eslint-disable react/display-name */
import { modalParser } from '@rocket.chat/fuselage-ui-kit';
import React from 'react';

import { renderMessageBody } from '../../lib/utils/renderMessageBody';
import ParsedText from '../../components/message/content/uikit/ParsedText';

// TODO: move this to fuselage-ui-kit itself
modalParser.plainText = ({ text } = {}) => text;

// TODO: move this to fuselage-ui-kit itself
modalParser.mrkdwn = ({ text }) => <span dangerouslySetInnerHTML={{ __html: renderMessageBody({ msg: text }) }} />;
modalParser.mrkdwn = ({ text }) => <ParsedText text={text} />;
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import React, { memo } from 'react';
import { useTimeAgo } from '../../../../hooks/useTimeAgo';
import { clickableItem } from '../../../../lib/clickableItem';
import { normalizeThreadMessage } from '../../../../lib/normalizeThreadMessage';
import DiscussionListMessage from './components/Message';
import DiscussionListMessage from './components/DiscussionMessage';
import { mapProps } from './mapProps';

const Discussion = memo(mapProps(clickableItem(DiscussionListMessage)));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { Box, Message } from '@rocket.chat/fuselage';
import React, { memo } from 'react';

import UserAvatar from '../../../../../components/avatar/UserAvatar';

const DiscussionMessage = ({
_id,
msg,
following,
username,
name = username,
ts,
dcount,
t = (text) => text,
participants,
handleFollowButton,
unread,
mention,
all,
formatDate = (e) => e,
dlm,
className = [],
...props
}) => (
<Box is={Message} {...props} className={className} pbs='x16' pbe='x8'>
<Message.LeftContainer>
<UserAvatar username={username} className='rcx-message__avatar' size='x36' />
</Message.LeftContainer>
<Message.Container>
<Message.Header>
<Message.Name title={username}>{name}</Message.Name>
<Message.Timestamp>{formatDate(ts)}</Message.Timestamp>
</Message.Header>
<Message.Body clamp={2}>{msg}</Message.Body>
<Message.Block>
<Message.Metrics>
{!dcount && (
<Message.Metrics.Item>
<Message.Metrics.Item.Label>{t('No_messages_yet')}</Message.Metrics.Item.Label>
</Message.Metrics.Item>
)}
{!!dcount && (
<Message.Metrics.Item>
<Message.Metrics.Item.Icon name='discussion' />
<Message.Metrics.Item.Label>{dcount}</Message.Metrics.Item.Label>
</Message.Metrics.Item>
)}
{!!dcount && (
<Message.Metrics.Item>
<Message.Metrics.Item.Icon name='clock' />
<Message.Metrics.Item.Label>{formatDate(dlm)}</Message.Metrics.Item.Label>
</Message.Metrics.Item>
)}
</Message.Metrics>
</Message.Block>
</Message.Container>
</Box>
);

export default memo(DiscussionMessage);

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';

import Message from './Message';
import DiscussionMessage from './DiscussionMessage';

const message = {
msg: 'hello world',
Expand All @@ -22,11 +22,11 @@ const noReplies = {

export default {
title: 'Room/Contextual Bar/Discussion/Message',
component: Message,
component: DiscussionMessage,
};

export const Basic = () => <Message {...message} />;
export const Basic = () => <DiscussionMessage {...(message as any)} />;

export const LargeText = () => <Message {...largeText} />;
export const LargeText = () => <DiscussionMessage {...(largeText as any)} />;

export const NoReplies = () => <Message {...noReplies} />;
export const NoReplies = () => <DiscussionMessage {...(noReplies as any)} />;
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { useTranslation } from '@rocket.chat/ui-contexts';
import type { ComponentProps, MouseEventHandler, ReactElement, ReactNode } from 'react';
import React, { memo } from 'react';

import RawText from '../../../../../components/RawText';
import UserAvatar from '../../../../../components/avatar/UserAvatar';
import { followStyle, anchor } from '../../../../../components/message/helpers/followSyle';
import AllMentionNotification from '../../../../../components/message/notification/AllMentionNotification';
Expand All @@ -14,7 +13,7 @@ import { useTimeAgo } from '../../../../../hooks/useTimeAgo';

type ThreadListMessageProps = {
_id: IMessage['_id'];
msg: IMessage['msg'];
msg: ReactNode;
following: boolean;
username: IMessage['u']['username'];
name?: IMessage['u']['name'];
Expand Down Expand Up @@ -61,9 +60,7 @@ const ThreadListMessage = ({
<Message.Name title={username}>{name}</Message.Name>
<Message.Timestamp>{formatDate(ts)}</Message.Timestamp>
</Message.Header>
<Message.Body clamp={2}>
<RawText>{msg}</RawText>
</Message.Body>
<Message.Body clamp={2}>{msg}</Message.Body>
<Message.Block>
<Message.Metrics>
<Message.Metrics.Item>
Expand Down