1- import React , { useCallback , useContext , useState } from 'react' ;
1+ import React , { useCallback , useEffect , useContext , useState } from 'react' ;
22import PropTypes from 'prop-types' ;
33import {
44 Paper ,
@@ -28,6 +28,7 @@ import {
2828import MemberSelector from '../member_selector/MemberSelector' ;
2929import { AppContext } from '../../context/AppContext' ;
3030import { getAvatarURL } from '../../api/api' ;
31+ import { getCustomEmoji } from '../../api/emoji.js' ;
3132import DateFnsUtils from '@date-io/date-fns' ;
3233import CheckIcon from '@mui/icons-material/Check' ;
3334import CloseIcon from '@mui/icons-material/Close' ;
@@ -57,32 +58,11 @@ const propTypes = {
5758 onKudosAction : PropTypes . func
5859} ;
5960
60- // TODO: Include support for custom Slack emojis and maybe move into it's own component and state
61- const parseEmojiData = ( ) => {
62- let shortcodeMap = { } ;
63- for ( const category in emojis ) {
64- if ( Object . hasOwn ( emojis , category ) ) {
65- let emojiList = emojis [ category ] ;
66- shortcodeMap = emojiList . reduce ( ( acc , current ) => {
67- current ?. n ?. forEach (
68- name => ( acc [ name . replace ( / \s / g, '_' ) ] = { unified : current . u } )
69- ) ;
70- return acc ;
71- } , shortcodeMap ) ;
72- }
73- }
74- return shortcodeMap ;
75- } ;
76-
77- const emojiShortcodeMap = parseEmojiData ( ) ;
78-
79- const getEmojiDataByShortcode = shortcode => {
80- return emojiShortcodeMap [ shortcode . toLowerCase ( ) ] || null ;
81- } ;
82-
8361const KudosCard = ( { kudos, includeActions, includeEdit, onKudosAction } ) => {
8462 const { state, dispatch } = useContext ( AppContext ) ;
8563 const csrf = selectCsrfToken ( state ) ;
64+ const [ emojiShortcodeMap , setEmojiShortcodeMap ] = useState ( { } ) ;
65+ const [ customLoaded , setCustomLoaded ] = useState ( false ) ;
8666
8767 const [ expanded , setExpanded ] = useState ( true ) ;
8868 const [ deleteDialogOpen , setDeleteDialogOpen ] = useState ( false ) ;
@@ -96,6 +76,65 @@ const KudosCard = ({ kudos, includeActions, includeEdit, onKudosAction }) => {
9676
9777 const sender = selectActiveOrInactiveProfile ( state , kudos . senderId ) ;
9878
79+ useEffect ( ( ) => {
80+ let shortcodeMap = { } ;
81+ for ( const category in emojis ) {
82+ if ( Object . hasOwn ( emojis , category ) ) {
83+ let emojiList = emojis [ category ] ;
84+ emojiList . reduce ( ( acc , current ) => {
85+ current ?. n ?. forEach (
86+ name => ( acc [ name . replace ( / \s / g, '_' ) ] = { unified : current . u } )
87+ ) ;
88+ return acc ;
89+ } , shortcodeMap ) ;
90+ }
91+ }
92+ setEmojiShortcodeMap ( shortcodeMap ) ;
93+ } , [ ] ) ;
94+
95+ useEffect ( ( ) => {
96+ const loadCustomEmoji = async ( ) => {
97+ let res = await getCustomEmoji ( csrf ) ;
98+ if ( res && res . payload && res . payload . data && ! res . error ) {
99+ const shortcodeMap = { ...emojiShortcodeMap } ;
100+ let aliases = { } ;
101+ let customEmoji = res . payload . data ;
102+ for ( const emoji in customEmoji ) {
103+ if ( Object . hasOwn ( customEmoji , emoji ) ) {
104+ if ( customEmoji [ emoji ] . startsWith ( "alias:" ) ) {
105+ aliases [ emoji ] = { alias : customEmoji [ emoji ] . substring ( "alias:" . length ) } ;
106+ } else {
107+ shortcodeMap [ emoji ] = { customUrl : customEmoji [ emoji ] } ;
108+ }
109+ }
110+ }
111+ for ( const emoji in aliases ) {
112+ if ( Object . hasOwn ( aliases , emoji ) ) {
113+ shortcodeMap [ emoji ] = shortcodeMap [ aliases [ emoji ] . alias ] ;
114+ }
115+ }
116+ setEmojiShortcodeMap ( shortcodeMap ) ;
117+ setCustomLoaded ( true ) ;
118+ } else {
119+ window . snackDispatch ( {
120+ type : UPDATE_TOAST ,
121+ payload : {
122+ severity : 'warning' ,
123+ toast : `Custom emoji could not be loaded: ${ res . error } `
124+ }
125+ } ) ;
126+ }
127+ }
128+
129+ if ( csrf && ! customLoaded ) {
130+ loadCustomEmoji ( ) ;
131+ }
132+ } , [ csrf , customLoaded , emojiShortcodeMap ] ) ;
133+
134+ const getEmojiDataByShortcode = useCallback ( shortcode => {
135+ return emojiShortcodeMap [ shortcode . toLowerCase ( ) ] || null ;
136+ } , [ emojiShortcodeMap ] ) ;
137+
99138 const regexIndexOf = useCallback ( ( text , regex , start ) => {
100139 const indexInSuffix = text . slice ( start ) . search ( regex ) ;
101140 return indexInSuffix < 0 ? indexInSuffix : indexInSuffix + start ;
@@ -227,11 +266,13 @@ const KudosCard = ({ kudos, includeActions, includeEdit, onKudosAction }) => {
227266 } else if ( emojiData . customUrl ) {
228267 // Render custom emoji using emojiUrl
229268 components . push (
230- < Emoji
231- key = { `${ match . index } -${ shortcode } ` }
232- emojiUrl = { emojiData . customUrl }
233- size = { 20 }
234- />
269+ < img src = { emojiData . customUrl } alt = { shortcode } style = { { height : '20px' , width : '20px' , fontSize : '20px' } } />
270+ // Not sure why the below doesn't work. It seems like it should according to the docs. :shrug:s
271+ // <Emoji
272+ // key={`${match.index}-${shortcode}`}
273+ // emojiUrl={emojiData.customUrl}
274+ // size={20}
275+ // />
235276 ) ;
236277 }
237278 } else {
@@ -250,7 +291,7 @@ const KudosCard = ({ kudos, includeActions, includeEdit, onKudosAction }) => {
250291
251292 // If the original text had no shortcodes, return it in an array
252293 return components . length === 0 ? [ text ] : components ;
253- } , [ ] ) ;
294+ } , [ getEmojiDataByShortcode ] ) ;
254295
255296 // Creates the final array of React components for the message body,
256297 // processing Slack links, member names, and emojis.
0 commit comments