1- import React , { useCallback , useContext , useState } from 'react' ;
1+ import React , { useCallback , useContext } from 'react' ;
22import PropTypes from 'prop-types' ;
33import {
44 Card ,
55 CardHeader ,
66 CardContent ,
7- Divider ,
87 Typography ,
98 Avatar ,
109 Chip ,
11- Button ,
1210 AvatarGroup ,
1311 Tooltip ,
14- Dialog ,
15- DialogTitle ,
16- DialogContent ,
17- DialogContentText ,
18- DialogActions ,
19- TextField ,
2012 Link
2113} from '@mui/material' ;
2214import {
@@ -26,14 +18,11 @@ import {
2618import { AppContext } from '../../context/AppContext' ;
2719import { getAvatarURL } from '../../api/api' ;
2820import DateFnsUtils from '@date-io/date-fns' ;
29- import CheckIcon from '@mui/icons-material/Check' ;
30- import CloseIcon from '@mui/icons-material/Close' ;
3121import TeamIcon from '@mui/icons-material/Groups' ;
32-
33- import { approveKudos , deleteKudos } from '../../api/kudos' ;
34- import { UPDATE_TOAST } from '../../context/actions' ;
22+ import { Emoji , EmojiStyle } from 'emoji-picker-react' ;
3523
3624import './PublicKudosCard.css' ;
25+ import emojis from 'emoji-picker-react/src/data/emojis.json' ;
3726
3827const dateUtils = new DateFnsUtils ( ) ;
3928
@@ -49,6 +38,26 @@ const propTypes = {
4938 } ) . isRequired
5039} ;
5140
41+ const parseEmojiData = ( ) => {
42+ let shortcodeMap = { } ;
43+ for ( const category in emojis ) {
44+ if ( Object . hasOwn ( emojis , category ) ) {
45+ let emojiList = emojis [ category ] ;
46+ shortcodeMap = emojiList . reduce ( ( acc , current ) => {
47+ current ?. n ?. forEach ( name => acc [ name . replace ( / \s / g, "_" ) ] = { unified : current . u } )
48+ return acc ;
49+ } , shortcodeMap ) ;
50+ }
51+ }
52+ return shortcodeMap
53+ } ;
54+
55+ const emojiShortcodeMap = parseEmojiData ( ) ;
56+
57+ const getEmojiDataByShortcode = ( shortcode ) => {
58+ return emojiShortcodeMap [ shortcode . toLowerCase ( ) ] || null ;
59+ } ;
60+
5261const KudosCard = ( { kudos } ) => {
5362 const { state, dispatch } = useContext ( AppContext ) ;
5463 const csrf = selectCsrfToken ( state ) ;
@@ -174,6 +183,62 @@ const KudosCard = ({ kudos }) => {
174183 return components ;
175184 } ;
176185
186+ const renderTextWithEmojis = useCallback ( ( text ) => {
187+ const emojiShortcodeRegex = / : ( [ a - z A - Z 0 - 9 _ + - ] + ) : / g; // Regex to find :shortcodes:
188+ const components = [ ] ;
189+ let lastIndex = 0 ;
190+ let match ;
191+
192+ while ( ( match = emojiShortcodeRegex . exec ( text ) ) !== null ) {
193+ const shortcode = match [ 1 ] ;
194+ const emojiData = getEmojiDataByShortcode ( shortcode ) ;
195+ const precedingText = text . slice ( lastIndex , match . index ) ;
196+
197+ // Add text before the emoji shortcode
198+ if ( precedingText ) {
199+ components . push ( precedingText ) ;
200+ }
201+
202+ // Add the Emoji component or the original shortcode text
203+ if ( emojiData ) {
204+ if ( emojiData . unified ) {
205+ components . push (
206+ < Emoji
207+ key = { `${ match . index } -${ shortcode } ` } // Unique key
208+ unified = { emojiData . unified }
209+ size = { 20 } // Adjust size as needed
210+ />
211+ ) ;
212+ } else if ( emojiData . customUrl ) {
213+ // Render custom emoji using emojiUrl (or as an img tag)
214+ components . push (
215+ < Emoji
216+ key = { `${ match . index } -${ shortcode } ` }
217+ emojiUrl = { emojiData . customUrl }
218+ size = { 20 }
219+ />
220+ // Alternative: Render as an img tag directly if preferred
221+ // <img key={`${match.index}-${shortcode}`} src={emojiData.customUrl} alt={`:${shortcode}:`} style={{ width: 20, height: 20, verticalAlign: 'middle' }} />
222+ ) ;
223+ }
224+ } else {
225+ // If shortcode not found in map, render the original text
226+ components . push ( match [ 0 ] ) ;
227+ }
228+
229+ lastIndex = emojiShortcodeRegex . lastIndex ;
230+ }
231+
232+ // Add any remaining text after the last shortcode
233+ const remainingText = text . slice ( lastIndex ) ;
234+ if ( remainingText ) {
235+ components . push ( remainingText ) ;
236+ }
237+
238+ // If the original text had no shortcodes, return it in an array
239+ return components . length === 0 ? [ text ] : components ;
240+ } , [ ] ) ;
241+
177242 const createLinks = kudos => {
178243 const lines = [ ] ;
179244 let index = 0 ;
@@ -193,9 +258,19 @@ const KudosCard = ({ kudos }) => {
193258 }
194259 }
195260 }
261+
262+ let finalComponents = [ ] ;
263+ for ( const comp of components ) {
264+ if ( typeof comp === 'string' ) {
265+ finalComponents . push ( ...renderTextWithEmojis ( comp ) ) ; // Spread the result
266+ } else {
267+ finalComponents . push ( comp ) ; // Keep existing non-string components
268+ }
269+ }
270+
196271 lines . push (
197- < Typography key = { kudos . id + '-' + index } variant = "body1" >
198- { components }
272+ < Typography key = { kudos . id + '-' + index } variant = "body1" sx = { { lineHeight : '1.6' } } >
273+ { finalComponents }
199274 </ Typography >
200275 ) ;
201276 index ++ ;
0 commit comments