1- import React , { useCallback , useContext } from 'react' ;
1+ import React , { useCallback , useEffect , useState , useContext } from 'react' ;
22import PropTypes from 'prop-types' ;
33import {
44 Card ,
@@ -15,8 +15,12 @@ import {
1515 selectCsrfToken ,
1616 selectActiveOrInactiveProfile
1717} from '../../context/selectors' ;
18+ import {
19+ UPDATE_TOAST
20+ } from '../../context/actions' ;
1821import { AppContext } from '../../context/AppContext' ;
1922import { getAvatarURL } from '../../api/api' ;
23+ import { getCustomEmoji } from '../../api/emoji.js' ;
2024import TeamIcon from '@mui/icons-material/Groups' ;
2125import { Emoji , EmojiStyle } from 'emoji-picker-react' ;
2226
@@ -35,35 +39,73 @@ const propTypes = {
3539 } ) . isRequired
3640} ;
3741
38- // TODO: Include support for custom Slack emojis and maybe move into it's own component and state
39- const parseEmojiData = ( ) => {
40- let shortcodeMap = { } ;
41- for ( const category in emojis ) {
42- if ( Object . hasOwn ( emojis , category ) ) {
43- let emojiList = emojis [ category ] ;
44- shortcodeMap = emojiList . reduce ( ( acc , current ) => {
45- current ?. n ?. forEach (
46- name => ( acc [ name . replace ( / \s / g, '_' ) ] = { unified : current . u } )
47- ) ;
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-
6142const KudosCard = ( { kudos } ) => {
6243 const { state, dispatch } = useContext ( AppContext ) ;
6344 const csrf = selectCsrfToken ( state ) ;
45+ const [ emojiShortcodeMap , setEmojiShortcodeMap ] = useState ( { } ) ;
46+ const [ customLoaded , setCustomLoaded ] = useState ( false ) ;
6447
6548 const sender = selectActiveOrInactiveProfile ( state , kudos . senderId ) ;
6649
50+ useEffect ( ( ) => {
51+ let shortcodeMap = { } ;
52+ for ( const category in emojis ) {
53+ if ( Object . hasOwn ( emojis , category ) ) {
54+ let emojiList = emojis [ category ] ;
55+ emojiList . reduce ( ( acc , current ) => {
56+ current ?. n ?. forEach (
57+ name => ( acc [ name . replace ( / \s / g, '_' ) ] = { unified : current . u } )
58+ ) ;
59+ return acc ;
60+ } , shortcodeMap ) ;
61+ }
62+ }
63+ setEmojiShortcodeMap ( shortcodeMap ) ;
64+ } , [ ] ) ;
65+
66+ useEffect ( ( ) => {
67+ const loadCustomEmoji = async ( ) => {
68+ let res = await getCustomEmoji ( csrf ) ;
69+ if ( res && res . payload && res . payload . data && ! res . error ) {
70+ const shortcodeMap = { ...emojiShortcodeMap } ;
71+ let aliases = { } ;
72+ let customEmoji = res . payload . data ;
73+ for ( const emoji in customEmoji ) {
74+ if ( Object . hasOwn ( customEmoji , emoji ) ) {
75+ if ( customEmoji [ emoji ] . startsWith ( "alias:" ) ) {
76+ aliases [ emoji ] = { alias : customEmoji [ emoji ] . substring ( "alias:" . length ) } ;
77+ } else {
78+ shortcodeMap [ emoji ] = { customUrl : customEmoji [ emoji ] } ;
79+ }
80+ }
81+ }
82+ for ( const emoji in aliases ) {
83+ if ( Object . hasOwn ( aliases , emoji ) ) {
84+ shortcodeMap [ emoji ] = shortcodeMap [ aliases [ emoji ] ] ;
85+ }
86+ }
87+ setEmojiShortcodeMap ( shortcodeMap ) ;
88+ setCustomLoaded ( true ) ;
89+ } else {
90+ window . snackDispatch ( {
91+ type : UPDATE_TOAST ,
92+ payload : {
93+ severity : 'warning' ,
94+ toast : `Custom emoji could not be loaded: ${ res . error } `
95+ }
96+ } ) ;
97+ }
98+ }
99+
100+ if ( csrf && ! customLoaded ) {
101+ loadCustomEmoji ( ) ;
102+ }
103+ } , [ csrf , customLoaded , emojiShortcodeMap ] ) ;
104+
105+ const getEmojiDataByShortcode = useCallback ( shortcode => {
106+ return emojiShortcodeMap [ shortcode . toLowerCase ( ) ] || null ;
107+ } , [ emojiShortcodeMap ] ) ;
108+
67109 const regexIndexOf = useCallback ( ( text , regex , start ) => {
68110 const indexInSuffix = text . slice ( start ) . search ( regex ) ;
69111 return indexInSuffix < 0 ? indexInSuffix : indexInSuffix + start ;
@@ -218,7 +260,7 @@ const KudosCard = ({ kudos }) => {
218260
219261 // If the original text had no shortcodes, return it in an array
220262 return components . length === 0 ? [ text ] : components ;
221- } , [ ] ) ;
263+ } , [ getEmojiDataByShortcode ] ) ;
222264
223265 // Creates the final array of React components for the message body,
224266 // processing Slack links, member names, and emojis.
0 commit comments