fix: mentions and emojis inside bold, italic and strikethrough (#29391)

pull/29744/head^2
Jayesh Jain 3 years ago committed by GitHub
parent d91e480ba9
commit e01bbcca54
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      .changeset/mentions-emoji-emphasis.md
  2. 56
      ee/packages/pdf-worker/src/templates/ChatTranscript/markup/elements/BoldSpan.tsx
  3. 56
      ee/packages/pdf-worker/src/templates/ChatTranscript/markup/elements/ItalicSpan.tsx
  4. 56
      ee/packages/pdf-worker/src/templates/ChatTranscript/markup/elements/StrikeSpan.tsx
  5. 60
      packages/gazzodown/src/elements/BoldSpan.tsx
  6. 4
      packages/gazzodown/src/elements/ImageElement.tsx
  7. 68
      packages/gazzodown/src/elements/ItalicSpan.tsx
  8. 68
      packages/gazzodown/src/elements/StrikeSpan.tsx
  9. 6
      yarn.lock

@ -0,0 +1,6 @@
---
'@rocket.chat/gazzodown': minor
---
Fixed mentions and emojis inside inside bold, italic or strikethrough texts

@ -4,6 +4,7 @@ import type * as MessageParser from '@rocket.chat/message-parser';
import ItalicSpan from './ItalicSpan';
import LinkSpan from './LinkSpan';
import StrikeSpan from './StrikeSpan';
import EmojiSpan from './EmojiSpan';
const styles = StyleSheet.create({
bold: {
@ -11,31 +12,52 @@ const styles = StyleSheet.create({
},
});
type MessageBlock =
| MessageParser.Emoji
| MessageParser.ChannelMention
| MessageParser.UserMention
| MessageParser.Link
| MessageParser.MarkupExcluding<MessageParser.Bold>;
type BoldSpanProps = {
children: (MessageParser.Link | MessageParser.MarkupExcluding<MessageParser.Bold>)[];
children: MessageBlock[];
};
const BoldSpan = ({ children }: BoldSpanProps) => (
<View style={styles.bold}>
<>
{children.map((child, index) => {
switch (child.type) {
case 'LINK':
return <LinkSpan key={index} label={Array.isArray(child.value.label) ? child.value.label : [child.value.label]} />;
if (child.type === 'LINK' || child.type === 'PLAIN_TEXT' || child.type === 'ITALIC' || child.type === 'STRIKE') {
return (
<View style={styles.bold} key={index}>
{renderBlockComponent(child, index)}
</View>
);
}
return renderBlockComponent(child, index);
})}
</>
);
case 'PLAIN_TEXT':
return <Text key={index}>{child.value}</Text>;
const renderBlockComponent = (child: MessageBlock, index: number) => {
switch (child.type) {
case 'LINK':
return <LinkSpan key={index} label={Array.isArray(child.value.label) ? child.value.label : [child.value.label]} />;
case 'STRIKE':
return <StrikeSpan key={index} children={child.value} />;
case 'PLAIN_TEXT':
return <Text key={index}>{child.value}</Text>;
case 'ITALIC':
return <ItalicSpan key={index} children={child.value} />;
case 'STRIKE':
return <StrikeSpan key={index} children={child.value} />;
default:
return null;
}
})}
</View>
);
case 'ITALIC':
return <ItalicSpan key={index} children={child.value} />;
case 'EMOJI':
return <EmojiSpan key={index} {...child} />;
default:
return null;
}
};
export default BoldSpan;

@ -4,6 +4,7 @@ import type * as MessageParser from '@rocket.chat/message-parser';
import BoldSpan from './BoldSpan';
import LinkSpan from './LinkSpan';
import StrikeSpan from './StrikeSpan';
import EmojiSpan from './EmojiSpan';
const styles = StyleSheet.create({
italic: {
@ -11,31 +12,52 @@ const styles = StyleSheet.create({
},
});
type MessageBlock =
| MessageParser.Emoji
| MessageParser.ChannelMention
| MessageParser.UserMention
| MessageParser.Link
| MessageParser.MarkupExcluding<MessageParser.Italic>;
type ItalicSpanProps = {
children: (MessageParser.Link | MessageParser.MarkupExcluding<MessageParser.Italic>)[];
children: MessageBlock[];
};
const ItalicSpan = ({ children }: ItalicSpanProps) => (
<View style={styles.italic}>
<>
{children.map((child, index) => {
switch (child.type) {
case 'LINK':
return <LinkSpan key={index} label={Array.isArray(child.value.label) ? child.value.label : [child.value.label]} />;
if (child.type === 'LINK' || child.type === 'PLAIN_TEXT' || child.type === 'STRIKE' || child.type === 'BOLD') {
return (
<View style={styles.italic} key={index}>
{renderBlockComponent(child, index)}
</View>
);
}
return renderBlockComponent(child, index);
})}
</>
);
case 'PLAIN_TEXT':
return <Text key={index}>{child.value}</Text>;
const renderBlockComponent = (child: MessageBlock, index: number) => {
switch (child.type) {
case 'LINK':
return <LinkSpan key={index} label={Array.isArray(child.value.label) ? child.value.label : [child.value.label]} />;
case 'STRIKE':
return <StrikeSpan key={index} children={child.value} />;
case 'PLAIN_TEXT':
return <Text key={index}>{child.value}</Text>;
case 'BOLD':
return <BoldSpan key={index} children={child.value} />;
case 'STRIKE':
return <StrikeSpan key={index} children={child.value} />;
default:
return null;
}
})}
</View>
);
case 'BOLD':
return <BoldSpan key={index} children={child.value} />;
case 'EMOJI':
return <EmojiSpan key={index} {...child} />;
default:
return null;
}
};
export default ItalicSpan;

@ -4,6 +4,7 @@ import type * as MessageParser from '@rocket.chat/message-parser';
import ItalicSpan from './ItalicSpan';
import LinkSpan from './LinkSpan';
import BoldSpan from './BoldSpan';
import EmojiSpan from './EmojiSpan';
const styles = StyleSheet.create({
strike: {
@ -11,31 +12,52 @@ const styles = StyleSheet.create({
},
});
type MessageBlock =
| MessageParser.Emoji
| MessageParser.ChannelMention
| MessageParser.UserMention
| MessageParser.Link
| MessageParser.MarkupExcluding<MessageParser.Strike>;
type StrikeSpanProps = {
children: (MessageParser.Link | MessageParser.MarkupExcluding<MessageParser.Strike>)[];
children: MessageBlock[];
};
const StrikeSpan = ({ children }: StrikeSpanProps) => (
<View style={styles.strike}>
<>
{children.map((child, index) => {
switch (child.type) {
case 'LINK':
return <LinkSpan key={index} label={Array.isArray(child.value.label) ? child.value.label : [child.value.label]} />;
if (child.type === 'LINK' || child.type === 'PLAIN_TEXT' || child.type === 'ITALIC' || child.type === 'BOLD') {
return (
<View style={styles.strike} key={index}>
{renderBlockComponent(child, index)}
</View>
);
}
return renderBlockComponent(child, index);
})}
</>
);
case 'PLAIN_TEXT':
return <Text key={index}>{child.value}</Text>;
const renderBlockComponent = (child: MessageBlock, index: number) => {
switch (child.type) {
case 'LINK':
return <LinkSpan key={index} label={Array.isArray(child.value.label) ? child.value.label : [child.value.label]} />;
case 'BOLD':
return <BoldSpan key={index} children={child.value} />;
case 'PLAIN_TEXT':
return <Text key={index}>{child.value}</Text>;
case 'ITALIC':
return <ItalicSpan key={index} children={child.value} />;
case 'ITALIC':
return <ItalicSpan key={index} children={child.value} />;
default:
return null;
}
})}
</View>
);
case 'BOLD':
return <BoldSpan key={index} children={child.value} />;
case 'EMOJI':
return <EmojiSpan key={index} {...child} />;
default:
return null;
}
};
export default StrikeSpan;

@ -1,36 +1,62 @@
import type * as MessageParser from '@rocket.chat/message-parser';
import type { ReactElement } from 'react';
import EmojiElement from '../emoji/EmojiElement';
import ChannelMentionElement from '../mentions/ChannelMentionElement';
import UserMentionElement from '../mentions/UserMentionElement';
import ItalicSpan from './ItalicSpan';
import LinkSpan from './LinkSpan';
import PlainSpan from './PlainSpan';
import StrikeSpan from './StrikeSpan';
type MessageBlock =
| MessageParser.Emoji
| MessageParser.ChannelMention
| MessageParser.UserMention
| MessageParser.Link
| MessageParser.MarkupExcluding<MessageParser.Bold>;
type BoldSpanProps = {
children: (MessageParser.Link | MessageParser.MarkupExcluding<MessageParser.Bold>)[];
children: MessageBlock[];
};
const BoldSpan = ({ children }: BoldSpanProps): ReactElement => (
<strong>
<>
{children.map((block, index) => {
switch (block.type) {
case 'LINK':
return <LinkSpan key={index} href={block.value.src.value} label={block.value.label} />;
if (block.type === 'LINK' || block.type === 'PLAIN_TEXT' || block.type === 'STRIKE' || block.type === 'ITALIC') {
return <strong key={index}>{renderBlockComponent(block, index)}</strong>;
}
return renderBlockComponent(block, index);
})}
</>
);
case 'PLAIN_TEXT':
return <PlainSpan key={index} text={block.value} />;
const renderBlockComponent = (block: MessageBlock, index: number): ReactElement | null => {
switch (block.type) {
case 'EMOJI':
return <EmojiElement key={index} {...block} />;
case 'STRIKE':
return <StrikeSpan key={index} children={block.value} />;
case 'MENTION_USER':
return <UserMentionElement key={index} mention={block.value.value} />;
case 'ITALIC':
return <ItalicSpan key={index} children={block.value} />;
case 'MENTION_CHANNEL':
return <ChannelMentionElement key={index} mention={block.value.value} />;
default:
return null;
}
})}
</strong>
);
case 'PLAIN_TEXT':
return <PlainSpan key={index} text={block.value} />;
case 'LINK':
return <LinkSpan key={index} href={block.value.src.value} label={block.value.label} />;
case 'STRIKE':
return <StrikeSpan key={index} children={block.value} />;
case 'ITALIC':
return <ItalicSpan key={index} children={block.value} />;
default:
return null;
}
};
export default BoldSpan;

@ -1,7 +1,9 @@
import type * as MessageParser from '@rocket.chat/message-parser';
import { ReactElement, useMemo } from 'react';
const flattenMarkup = (markup: MessageParser.Markup | MessageParser.Link): string => {
const flattenMarkup = (
markup: MessageParser.Markup | MessageParser.Link | MessageParser.Emoji | MessageParser.ChannelMention | MessageParser.UserMention,
): string => {
switch (markup.type) {
case 'PLAIN_TEXT':
return markup.value;

@ -1,42 +1,62 @@
import type * as MessageParser from '@rocket.chat/message-parser';
import type { ReactElement } from 'react';
import EmojiElement from '../emoji/EmojiElement';
import ChannelMentionElement from '../mentions/ChannelMentionElement';
import UserMentionElement from '../mentions/UserMentionElement';
import BoldSpan from './BoldSpan';
import LinkSpan from './LinkSpan';
import PlainSpan from './PlainSpan';
import StrikeSpan from './StrikeSpan';
type MessageBlock =
| MessageParser.Emoji
| MessageParser.ChannelMention
| MessageParser.UserMention
| MessageParser.Link
| MessageParser.MarkupExcluding<MessageParser.Italic>;
type ItalicSpanProps = {
children: (MessageParser.Link | MessageParser.MarkupExcluding<MessageParser.Italic>)[];
children: MessageBlock[];
};
const ItalicSpan = ({ children }: ItalicSpanProps): ReactElement => (
<em>
<>
{children.map((block, index) => {
switch (block.type) {
case 'LINK':
return (
<LinkSpan
key={index}
href={block.value.src.value}
label={Array.isArray(block.value.label) ? block.value.label : [block.value.label]}
/>
);
case 'PLAIN_TEXT':
return <PlainSpan key={index} text={block.value} />;
case 'STRIKE':
return <StrikeSpan key={index} children={block.value} />;
case 'BOLD':
return <BoldSpan key={index} children={block.value} />;
default:
return null;
if (block.type === 'LINK' || block.type === 'PLAIN_TEXT' || block.type === 'STRIKE' || block.type === 'BOLD') {
return <em key={index}>{renderBlockComponent(block, index)}</em>;
}
return renderBlockComponent(block, index);
})}
</em>
</>
);
const renderBlockComponent = (block: MessageBlock, index: number): ReactElement | null => {
switch (block.type) {
case 'EMOJI':
return <EmojiElement key={index} {...block} />;
case 'MENTION_USER':
return <UserMentionElement key={index} mention={block.value.value} />;
case 'MENTION_CHANNEL':
return <ChannelMentionElement key={index} mention={block.value.value} />;
case 'PLAIN_TEXT':
return <PlainSpan key={index} text={block.value} />;
case 'LINK':
return <LinkSpan key={index} href={block.value.src.value} label={block.value.label} />;
case 'STRIKE':
return <StrikeSpan key={index} children={block.value} />;
case 'BOLD':
return <BoldSpan key={index} children={block.value} />;
default:
return null;
}
};
export default ItalicSpan;

@ -1,42 +1,62 @@
import type * as MessageParser from '@rocket.chat/message-parser';
import type { ReactElement } from 'react';
import EmojiElement from '../emoji/EmojiElement';
import ChannelMentionElement from '../mentions/ChannelMentionElement';
import UserMentionElement from '../mentions/UserMentionElement';
import BoldSpan from './BoldSpan';
import ItalicSpan from './ItalicSpan';
import LinkSpan from './LinkSpan';
import PlainSpan from './PlainSpan';
type MessageBlock =
| MessageParser.Emoji
| MessageParser.ChannelMention
| MessageParser.UserMention
| MessageParser.Link
| MessageParser.MarkupExcluding<MessageParser.Strike>;
type StrikeSpanProps = {
children: (MessageParser.Link | MessageParser.MarkupExcluding<MessageParser.Strike>)[];
children: MessageBlock[];
};
const StrikeSpan = ({ children }: StrikeSpanProps): ReactElement => (
<del>
<>
{children.map((block, index) => {
switch (block.type) {
case 'LINK':
return (
<LinkSpan
key={index}
href={block.value.src.value}
label={Array.isArray(block.value.label) ? block.value.label : [block.value.label]}
/>
);
case 'PLAIN_TEXT':
return <PlainSpan key={index} text={block.value} />;
case 'BOLD':
return <BoldSpan key={index} children={block.value} />;
case 'ITALIC':
return <ItalicSpan key={index} children={block.value} />;
default:
return null;
if (block.type === 'LINK' || block.type === 'PLAIN_TEXT' || block.type === 'ITALIC' || block.type === 'BOLD') {
return <del key={index}>{renderBlockComponent(block, index)}</del>;
}
return renderBlockComponent(block, index);
})}
</del>
</>
);
const renderBlockComponent = (block: MessageBlock, index: number): ReactElement | null => {
switch (block.type) {
case 'EMOJI':
return <EmojiElement key={index} {...block} />;
case 'MENTION_USER':
return <UserMentionElement key={index} mention={block.value.value} />;
case 'MENTION_CHANNEL':
return <ChannelMentionElement key={index} mention={block.value.value} />;
case 'PLAIN_TEXT':
return <PlainSpan key={index} text={block.value} />;
case 'LINK':
return <LinkSpan key={index} href={block.value.src.value} label={block.value.label} />;
case 'ITALIC':
return <ItalicSpan key={index} children={block.value} />;
case 'BOLD':
return <BoldSpan key={index} children={block.value} />;
default:
return null;
}
};
export default StrikeSpan;

@ -9950,11 +9950,11 @@ __metadata:
linkType: hard
"@rocket.chat/message-parser@npm:next":
version: 0.32.0-dev.277
resolution: "@rocket.chat/message-parser@npm:0.32.0-dev.277"
version: 0.32.0-dev.296
resolution: "@rocket.chat/message-parser@npm:0.32.0-dev.296"
dependencies:
tldts: ~5.7.112
checksum: c1e34dbe2dd23142c565088a86f4243501364a95de456e0b8add3cec78cd44545747b4ed7add7a1403667c14193a1bac52d2a98add85f0cf3cd9844fc9c03095
checksum: 2a40090b0b5b94e531da3bd1433c6f60b98f19b85eb9ca81db8706fcf360d8245c97fde2257a6c39e9be7fa4a630eede5abf679847ef3c923594c7156f8eb334
languageName: node
linkType: hard

Loading…
Cancel
Save