@@ -5,6 +5,9 @@ import { themes } from '../../../lib/constants/colors';
55import { useTheme } from '../../../theme' ;
66import usePreviewFormatText from '../../../lib/hooks/usePreviewFormatText' ;
77import styles from '../styles' ;
8+ import { useSelector } from 'react-redux' ;
9+ import { IApplicationState } from '../../../definitions' ;
10+ import CustomEmoji from '../../EmojiPicker/CustomEmoji' ;
811
912interface IMarkdownPreview {
1013 msg ?: string ;
@@ -14,22 +17,64 @@ interface IMarkdownPreview {
1417}
1518
1619const MarkdownPreview = ( { msg, numberOfLines = 1 , style = [ ] , testID } : IMarkdownPreview ) => {
17- const { theme } = useTheme ( ) ;
18- const formattedText = usePreviewFormatText ( msg ?? '' ) ;
19-
20- if ( ! msg ) {
21- return null ;
22- }
23- const m = formattedText ;
24- return (
25- < Text
26- accessibilityLabel = { m }
27- style = { [ styles . text , { color : themes [ theme ] . fontDefault , lineHeight : undefined } , ...style ] }
28- numberOfLines = { numberOfLines }
29- testID = { testID || `markdown-preview-${ m } ` } >
30- { m }
31- </ Text >
32- ) ;
20+ const { theme } = useTheme ( ) ;
21+ const formattedText = usePreviewFormatText ( msg ?? '' ) ;
22+ const customEmojis = useSelector ( ( state : IApplicationState ) => state . customEmojis ) ;
23+
24+ if ( ! msg ) {
25+ return null ;
26+ }
27+
28+ function getCustomEmoji ( name : string ) {
29+ const emoji = customEmojis [ name ] ;
30+ return emoji ?? null ;
31+ }
32+
33+ function parseText ( input : string ) {
34+ const emojiPattern = / ( : [ a - z A - Z 0 - 9 _ + - ] + : ) / g;
35+ const emojiRegex = / : [ a - z A - Z 0 - 9 _ + - ] + : / ;
36+
37+ const parts = input . split ( emojiPattern ) . filter ( Boolean ) ;
38+
39+ const tokens = parts . map ( p => {
40+ const isEmoji = emojiRegex . test ( p ) ;
41+
42+ return {
43+ type : isEmoji ? "emoji" : "text" ,
44+ value : isEmoji ? getCustomEmoji ( p . replace ( / : / g, '' ) ) : p
45+ }
46+ } ) ;
47+
48+ return tokens . reduce ( ( acc : any [ ] , curr : any ) => {
49+ const last = acc [ acc . length - 1 ] ;
50+ if ( last && last . type === "text" && curr . type === "text" ) {
51+ last . value += curr . value ;
52+ } else {
53+ acc . push ( curr ) ;
54+ }
55+ return acc ;
56+ } , [ ] ) ;
57+ }
58+
59+ const m = parseText ( formattedText ) ;
60+
61+ return (
62+ < Text
63+ accessibilityLabel = { formattedText }
64+ style = { [ styles . text , { color : themes [ theme ] . fontDefault , lineHeight : undefined } , ...style ] }
65+ numberOfLines = { numberOfLines }
66+ testID = { testID || `markdown-preview-${ formattedText } ` }
67+ >
68+ { m . map ( ( token , i ) => {
69+ if ( token . type === 'emoji' && token . value ) {
70+ return < CustomEmoji key = { i } emoji = { token . value } style = { { width : 15 , height : 15 } } />
71+ }
72+ return (
73+ < Text key = { i } > { token . value } </ Text >
74+ ) ;
75+ } ) }
76+ </ Text >
77+ ) ;
3378} ;
3479
3580export default MarkdownPreview ;
0 commit comments