diff --git a/app/containers/markdown/components/Preview.tsx b/app/containers/markdown/components/Preview.tsx index fa61742dc0..c91a1503ea 100644 --- a/app/containers/markdown/components/Preview.tsx +++ b/app/containers/markdown/components/Preview.tsx @@ -5,6 +5,9 @@ import { themes } from '../../../lib/constants/colors'; import { useTheme } from '../../../theme'; import usePreviewFormatText from '../../../lib/hooks/usePreviewFormatText'; import styles from '../styles'; +import { useSelector } from 'react-redux'; +import { IApplicationState } from '../../../definitions'; +import CustomEmoji from '../../EmojiPicker/CustomEmoji'; interface IMarkdownPreview { msg?: string; @@ -16,18 +19,57 @@ interface IMarkdownPreview { const MarkdownPreview = ({ msg, numberOfLines = 1, style = [], testID }: IMarkdownPreview) => { const { theme } = useTheme(); const formattedText = usePreviewFormatText(msg ?? ''); + const customEmojis = useSelector((state: IApplicationState) => state.customEmojis); if (!msg) { return null; } - const m = formattedText; + + function getCustomEmoji(name: string) { + const emoji = customEmojis[name]; + return emoji ?? null; + } + + function parseText(input: string) { + const emojiPattern = /(:[a-zA-Z0-9_+-]+:)/g; + const emojiRegex = /:[a-zA-Z0-9_+-]+:/; + + const parts = input.split(emojiPattern).filter(Boolean); + + const tokens = parts.map(p => { + const isEmoji = emojiRegex.test(p); + + return { + type: isEmoji ? 'emoji' : 'text', + value: isEmoji ? getCustomEmoji(p.replace(/:/g, '')) : p + }; + }); + + return tokens.reduce((acc: any[], curr: any) => { + const last = acc[acc.length - 1]; + if (last && last.type === 'text' && curr.type === 'text') { + last.value += curr.value; + } else { + acc.push(curr); + } + return acc; + }, []); + } + + const m = parseText(formattedText); + return ( - {m} + testID={testID || `markdown-preview-${formattedText}`}> + {m.map((token, i) => { + if (token.type === 'emoji' && token.value) { + return ; + } + return {token.value}; + })} ); };