Skip to content

Commit

Permalink
[NEW] New Message Parser (#21962)
Browse files Browse the repository at this point in the history
  • Loading branch information
ggazzo authored May 9, 2021
1 parent 645b119 commit 6e9d541
Show file tree
Hide file tree
Showing 40 changed files with 562 additions and 93 deletions.
4 changes: 4 additions & 0 deletions app/emoji-emojione/client/emojione-sprites.css
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,7 @@
width: 44px;
height: 44px;
}
.big > .emojione {
width: 44px;
height: 44px;
}
6 changes: 6 additions & 0 deletions app/lib/server/functions/sendMessage.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Match, check } from 'meteor/check';
import { parser } from '@rocket.chat/message-parser';

import { settings } from '../../../settings';
import { callbacks } from '../../../callbacks';
Expand Down Expand Up @@ -215,6 +216,11 @@ export const sendMessage = function(user, message, room, upsert = false) {
parseUrlsInMessage(message);

message = callbacks.run('beforeSaveMessage', message, room);
try {
message.md = parser(message.msg);
} catch (e) {
console.log(e); // errors logged while the parser is at experimental stage
}
if (message) {
if (message._id && upsert) {
const { _id } = message;
Expand Down
7 changes: 7 additions & 0 deletions app/lib/server/functions/updateMessage.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Meteor } from 'meteor/meteor';
import { parser } from '@rocket.chat/message-parser';

import { Messages, Rooms } from '../../../models';
import { settings } from '../../../settings';
Expand Down Expand Up @@ -44,6 +45,12 @@ export const updateMessage = function(message, user, originalMessage) {

message = callbacks.run('beforeSaveMessage', message);

try {
message.md = parser(message.msg);
} catch (e) {
console.log(e); // errors logged while the parser is at experimental stage
}

const tempid = message._id;
delete message._id;

Expand Down
9 changes: 9 additions & 0 deletions app/lib/server/startup/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -507,16 +507,25 @@ settings.addGroup('Accounts', function() {
public: true,
i18nLabel: 'New_Message_Notification',
});

this.add('Accounts_Default_User_Preferences_muteFocusedConversations', true, {
type: 'boolean',
public: true,
i18nLabel: 'Mute_Focused_Conversations',
});

this.add('Accounts_Default_User_Preferences_notificationsSoundVolume', 100, {
type: 'int',
public: true,
i18nLabel: 'Notifications_Sound_Volume',
});

this.add('Accounts_Default_User_Preferences_enableMessageParserEarlyAdoption', false, {
type: 'boolean',
public: true,
i18nLabel: 'Enable_message_parser_early_adoption',
alert: 'Enable_message_parser_early_adoption_alert',
});
});

this.section('Avatar', function() {
Expand Down
1 change: 1 addition & 0 deletions app/models/server/models/Messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,7 @@ export class Messages extends Base {
},
},
$unset: {
md: 1,
blocks: 1,
tshow: 1,
},
Expand Down
2 changes: 1 addition & 1 deletion app/settings/client/lib/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class Settings extends SettingsBase {

collection = PublicSettingsCachedCollection.get().collection;

dict = new ReactiveDict<any>('settings');
dict = new ReactiveDict('settings');

get(_id: string): any {
return this.dict.get(_id);
Expand Down
10 changes: 7 additions & 3 deletions app/ui-message/client/message.html
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,11 @@
{{> Blocks blocks=msg.blocks rid=msg.rid mid=msg._id}}
</div>
{{else}}
{{{body}}}
{{# if enableMessageParserEarlyAdoption }}
{{> MessageBody tokens=msg.md mentions=msg.mentions }}
{{else}}
{{{body}}}
{{/if}}
{{/if}}
{{#if msg.location}}
{{> messageLocation location=msg.location}}
Expand All @@ -123,7 +127,7 @@
{{#if hasAttachments}}
{{> reactAttachments attachments=msg.attachments file=msg.file }}
{{/if}}


{{#with readReceipt}}
<div class="read-receipt {{readByEveryone}}">
Expand Down Expand Up @@ -170,7 +174,7 @@
{{#if msg.drid}}
{{> DiscussionMetric count=msg.dcount drid=msg.drid lm=msg.dlm openDiscussion=actions.openDiscussion }}
{{/if}}

{{#if $and settings.showReplyButton msg.tcount}}
{{> ThreadMetric counter=msg.tcount following=following lm=msg.tlm rid=msg.rid mid=msg._id unread=unread mention=mention all=all openThread=actions.openThread }}
{{/if}}
Expand Down
4 changes: 4 additions & 0 deletions app/ui-message/client/message.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ const renderBody = (msg, settings) => {
};

Template.message.helpers({
enableMessageParserEarlyAdoption() {
const { settings: { enableMessageParserEarlyAdoption }, msg } = this;
return enableMessageParserEarlyAdoption && msg.md;
},
unread() {
const { msg, subscription } = this;
return subscription?.tunread?.includes(msg._id);
Expand Down
4 changes: 2 additions & 2 deletions app/ui-utils/client/lib/messageContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ import { fireGlobalEvent } from './fireGlobalEvent';
import { actionLinks } from '../../../action-links/client';
import { goToRoomById } from '../../../../client/lib/goToRoomById';


const fields = { name: 1, username: 1, 'settings.preferences.showMessageInMainThread': 1, 'settings.preferences.autoImageLoad': 1, 'settings.preferences.saveMobileBandwidth': 1, 'settings.preferences.collapseMediaByDefault': 1, 'settings.preferences.hideRoles': 1 };
const fields = { name: 1, username: 1, 'settings.preferences.enableMessageParserEarlyAdoption': 1, 'settings.preferences.showMessageInMainThread': 1, 'settings.preferences.autoImageLoad': 1, 'settings.preferences.saveMobileBandwidth': 1, 'settings.preferences.collapseMediaByDefault': 1, 'settings.preferences.hideRoles': 1 };

export function messageContext({ rid } = Template.instance()) {
const uid = Meteor.userId();
Expand Down Expand Up @@ -99,6 +98,7 @@ export function messageContext({ rid } = Template.instance()) {
translateLanguage: AutoTranslate.getLanguage(rid),
showMessageInMainThread: getUserPreference(user, 'showMessageInMainThread'),
autoImageLoad: getUserPreference(user, 'autoImageLoad'),
enableMessageParserEarlyAdoption: getUserPreference(user, 'enableMessageParserEarlyAdoption'),
saveMobileBandwidth: Meteor.Device.isPhone() && getUserPreference(user, 'saveMobileBandwidth'),
collapseMediaByDefault: getUserPreference(user, 'collapseMediaByDefault'),
showreply: true,
Expand Down
4 changes: 2 additions & 2 deletions client/components/Emoji.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import React from 'react';

import { renderEmoji } from '../../app/emoji/client/index';

function Emoji({ emojiHandle }) {
function Emoji({ emojiHandle, className = undefined }) {
const markup = { __html: `${renderEmoji(emojiHandle)}` };
return <div dangerouslySetInnerHTML={markup}></div>;
return <span className={className} dangerouslySetInnerHTML={markup} />;
}

export default Emoji;
18 changes: 18 additions & 0 deletions client/components/Message/Body/BigEmoji.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { BigEmoji as ASTBigEmoji } from '@rocket.chat/message-parser';
import React, { FC } from 'react';

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

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

const BigEmoji: FC<BigEmojiProps> = ({ value }) => (
<>
{value.map((block, index) => (
<Emoji className='big' key={index} emojiHandle={`:${block.value.value}:`} />
))}
</>
);

export default BigEmoji;
63 changes: 63 additions & 0 deletions client/components/Message/Body/Body.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { BigEmoji as ASTBigEmoji, MarkdownAST as GazzodownAST } from '@rocket.chat/message-parser';
import React, { FC, memo } from 'react';

import BigEmoji from './BigEmoji';
import Code from './Code';
import Heading from './Heading';
import OrderedList from './OrderedList';
import Paragraph from './Paragraph';
import Quote from './Quote';
import TaskList from './TaskList';
import UnorderedList from './UnorderedList';
import { UserMention } from './definitions/UserMention';

type BodyProps = {
tokens: GazzodownAST;
mentions: UserMention[];
};

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

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

return (
<>
{tokens.map((block, index) => {
if (block.type === 'UNORDERED_LIST') {
return <UnorderedList value={block.value} key={index} />;
}

if (block.type === 'QUOTE') {
return <Quote value={block.value} key={index} />;
}
if (block.type === 'TASKS') {
return <TaskList value={block.value} key={index} />;
}

if (block.type === 'ORDERED_LIST') {
return <OrderedList value={block.value} key={index} />;
}

if (block.type === 'PARAGRAPH') {
return <Paragraph mentions={mentions} value={block.value} key={index} />;
}

if (block.type === 'CODE') {
return <Code value={block.value} key={index} />;
}

if (block.type === 'HEADING') {
return <Heading value={block.value} key={index} />;
}

return null;
})}
</>
);
};

export default memo(Body);
24 changes: 24 additions & 0 deletions client/components/Message/Body/Bold.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Bold as ASTBold } from '@rocket.chat/message-parser';
import React, { FC } from 'react';

import Italic from './Italic';
import Strike from './Strike';

const Bold: FC<{ value: ASTBold['value'] }> = ({ value = [] }) => (
<strong>
{value.map((block, index) => {
switch (block.type) {
case 'PLAIN_TEXT':
return block.value;
case 'STRIKE':
return <Strike key={index} value={block.value} />;
case 'ITALIC':
return <Italic key={index} value={block.value} />;
default:
return null;
}
})}
</strong>
);

export default Bold;
19 changes: 19 additions & 0 deletions client/components/Message/Body/Code.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Code as ASTCode } from '@rocket.chat/message-parser';
import React, { FC } from 'react';

import CodeLine from './CodeLine';

const Code: FC<{ value: ASTCode['value'] }> = ({ value = [] }) => (
<code className='code-colors hljs'>
{value.map((block, index) => {
switch (block.type) {
case 'CODE_LINE':
return <CodeLine key={index} value={block.value} />;
default:
return null;
}
})}
</code>
);

export default Code;
8 changes: 8 additions & 0 deletions client/components/Message/Body/CodeLine.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { CodeLine as ASTCodeLine } from '@rocket.chat/message-parser';
import React, { FC } from 'react';

const CodeLine: FC<{ value: ASTCodeLine['value'] }> = ({ value }) => (
<div>{value.type === 'PLAIN_TEXT' && value.value}</div>
);

export default CodeLine;
17 changes: 17 additions & 0 deletions client/components/Message/Body/Heading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Bold as ASTHeading } from '@rocket.chat/message-parser';
import React, { FC } from 'react';

const Heading: FC<{ value: ASTHeading['value'] }> = ({ value = [] }) => (
<h1>
{value.map((block) => {
switch (block.type) {
case 'PLAIN_TEXT':
return block.value;
default:
return null;
}
})}
</h1>
);

export default Heading;
47 changes: 47 additions & 0 deletions client/components/Message/Body/Inline.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Paragraph as ASTParagraph } from '@rocket.chat/message-parser';
import React, { FC } from 'react';

import Emoji from '../../Emoji';
import Bold from './Bold';
import InlineCode from './InlineCode';
import Italic from './Italic';
import Link from './Link';
import Mention from './Mention';
import Plain from './Plain';
import Strike from './Strike';
import { UserMention } from './definitions/UserMention';

const Inline: FC<{ value: ASTParagraph['value']; mentions?: UserMention[] }> = ({
value = [],
mentions = [],
}) => (
<>
{value.map((block) => {
switch (block.type) {
case 'PLAIN_TEXT':
return block.value;
case 'BOLD':
return <Bold value={block.value} />;
case 'STRIKE':
return <Strike value={block.value} />;
case 'ITALIC':
return <Italic value={block.value} />;
case 'LINK':
return <Link value={block.value} />;
case 'MENTION_USER':
return <Mention value={block.value} mentions={mentions} />;
case 'EMOJI':
return <Emoji emojiHandle={`:${block.value.value}:`} />;
case 'MENTION_CHANNEL':
// case 'COLOR':
return <Plain value={block.value} />;
case 'INLINE_CODE':
return <InlineCode value={block.value} />;
default:
return null;
}
})}
</>
);

export default Inline;
17 changes: 17 additions & 0 deletions client/components/Message/Body/InlineCode.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { InlineCode as ASTInlineCode } from '@rocket.chat/message-parser';
import React, { FC } from 'react';

const InlineCode: FC<{ value: ASTInlineCode['value'] }> = ({ value }) => (
<code className='code-colors inline'>
{((block): string | null => {
switch (block.type) {
case 'PLAIN_TEXT':
return block.value;
default:
return null;
}
})(value)}
</code>
);

export default InlineCode;
Loading

0 comments on commit 6e9d541

Please sign in to comment.