fix: mentions and emojis inside bold, italic and strikethrough (#29391)
parent
d91e480ba9
commit
e01bbcca54
@ -0,0 +1,6 @@ |
||||
--- |
||||
'@rocket.chat/gazzodown': minor |
||||
--- |
||||
|
||||
Fixed mentions and emojis inside inside bold, italic or strikethrough texts |
||||
|
||||
@ -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,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; |
||||
|
||||
Loading…
Reference in new issue