Skip to content

Commit a3f7835

Browse files
committed
Fixed custom emoji display in kudos administration
1 parent e08bddf commit a3f7835

File tree

1 file changed

+71
-30
lines changed

1 file changed

+71
-30
lines changed

web-ui/src/components/kudos_card/KudosCard.jsx

Lines changed: 71 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useCallback, useContext, useState } from 'react';
1+
import React, { useCallback, useEffect, useContext, useState } from 'react';
22
import PropTypes from 'prop-types';
33
import {
44
Paper,
@@ -28,6 +28,7 @@ import {
2828
import MemberSelector from '../member_selector/MemberSelector';
2929
import { AppContext } from '../../context/AppContext';
3030
import { getAvatarURL } from '../../api/api';
31+
import { getCustomEmoji } from '../../api/emoji.js';
3132
import DateFnsUtils from '@date-io/date-fns';
3233
import CheckIcon from '@mui/icons-material/Check';
3334
import 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-
8361
const 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

Comments
 (0)