Skip to content

Commit 01e0f4e

Browse files
authored
Merge pull request #2950 from objectcomputing/feature-2946/support-custom-slack-emoji
Feature 2946/support custom slack emoji
2 parents 9123f9a + ce361aa commit 01e0f4e

File tree

6 files changed

+94
-79
lines changed

6 files changed

+94
-79
lines changed

server/src/main/resources/META-INF/native-image/com.objectcomputing/checkins/reflect-config.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
11
[
2+
{
3+
"name": "java.lang.reflect.RecordComponent",
4+
"allPublicMethods": true
5+
},
6+
{
7+
"name": "com.slack.api.methods.response.auth.AuthTestResponse",
8+
"allDeclaredConstructors" : true,
9+
"allPublicConstructors" : true
10+
},
211
{
312
"name": "com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer",
413
"allDeclaredConstructors" : true,

web-ui/src/api/emoji.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { resolve } from './api.js';
22

33
const emojiUrl = '/services/slack/emoji';
44

5-
export const getCustomEmoji = async (cookie) => {
5+
export const getCustomEmoji = async cookie => {
66
return resolve({
77
url: emojiUrl,
88
responseType: 'json',

web-ui/src/components/kudos/EnhancedKudos.jsx

Lines changed: 78 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
1-
import React, {useCallback, useContext, useEffect, useState} from 'react';
1+
import React, { useCallback, useContext, useEffect, useState } from 'react';
22
import PropTypes from 'prop-types';
3-
import {
4-
Typography,
5-
Link
6-
} from '@mui/material';
3+
import { Typography, Link } from '@mui/material';
74
import { AppContext } from '../../context/AppContext';
8-
import {
9-
selectCsrfToken,
10-
selectActiveOrInactiveProfile
11-
} from '../../context/selectors';
5+
import { selectCsrfToken } from '../../context/selectors';
126
import { UPDATE_TOAST } from '../../context/actions';
137
import { getCustomEmoji } from '../../api/emoji.js';
148
import { Emoji } from 'emoji-picker-react';
@@ -24,14 +18,14 @@ const propTypes = {
2418
dateCreated: PropTypes.array.isRequired,
2519
dateApproved: PropTypes.array,
2620
recipientMembers: PropTypes.array
27-
}).isRequired,
21+
}).isRequired
2822
};
2923

30-
const EnhancedKudos = ({kudos}) => {
24+
const EnhancedKudos = ({ kudos }) => {
3125
const { state, dispatch } = useContext(AppContext);
3226
const csrf = selectCsrfToken(state);
33-
const [ emojiShortcodeMap, setEmojiShortcodeMap ] = useState({});
34-
const [ customLoaded, setCustomLoaded ] = useState(false);
27+
const [emojiShortcodeMap, setEmojiShortcodeMap] = useState({});
28+
const [customLoaded, setCustomLoaded] = useState(false);
3529

3630
useEffect(() => {
3731
let shortcodeMap = {};
@@ -56,16 +50,18 @@ const EnhancedKudos = ({kudos}) => {
5650
const shortcodeMap = { ...emojiShortcodeMap };
5751
let aliases = {};
5852
let customEmoji = res.payload.data;
59-
for(const emoji in customEmoji) {
60-
if(Object.hasOwn(customEmoji, emoji)) {
61-
if(customEmoji[emoji].startsWith("alias:")) {
62-
aliases[emoji] = { alias: customEmoji[emoji].substring("alias:".length) };
53+
for (const emoji in customEmoji) {
54+
if (Object.hasOwn(customEmoji, emoji)) {
55+
if (customEmoji[emoji].startsWith('alias:')) {
56+
aliases[emoji] = {
57+
alias: customEmoji[emoji].substring('alias:'.length)
58+
};
6359
} else {
6460
shortcodeMap[emoji] = { customUrl: customEmoji[emoji] };
6561
}
6662
}
6763
}
68-
for(const emoji in aliases) {
64+
for (const emoji in aliases) {
6965
if (Object.hasOwn(aliases, emoji)) {
7066
shortcodeMap[emoji] = shortcodeMap[aliases[emoji].alias];
7167
}
@@ -81,16 +77,19 @@ const EnhancedKudos = ({kudos}) => {
8177
}
8278
});
8379
}
84-
}
80+
};
8581

86-
if(csrf && !customLoaded) {
82+
if (csrf && !customLoaded) {
8783
loadCustomEmoji();
8884
}
8985
}, [csrf, customLoaded, emojiShortcodeMap]);
9086

91-
const getEmojiDataByShortcode = useCallback(shortcode => {
92-
return emojiShortcodeMap[shortcode.toLowerCase()] || null;
93-
}, [emojiShortcodeMap]);
87+
const getEmojiDataByShortcode = useCallback(
88+
shortcode => {
89+
return emojiShortcodeMap[shortcode.toLowerCase()] || null;
90+
},
91+
[emojiShortcodeMap]
92+
);
9493

9594
const regexIndexOf = useCallback((text, regex, start) => {
9695
const indexInSuffix = text.slice(start).search(regex);
@@ -194,61 +193,68 @@ const EnhancedKudos = ({kudos}) => {
194193
return components.length === 0 ? [textLine] : components;
195194
}, []);
196195

197-
const renderTextWithEmojis = useCallback(text => {
198-
const emojiShortcodeRegex = /:([a-zA-Z0-9_+-]+):/g; // Regex to find :shortcodes:
199-
const components = [];
200-
let lastIndex = 0;
201-
let match;
196+
const renderTextWithEmojis = useCallback(
197+
text => {
198+
const emojiShortcodeRegex = /:([a-zA-Z0-9_+-]+):/g; // Regex to find :shortcodes:
199+
const components = [];
200+
let lastIndex = 0;
201+
let match;
202202

203-
while ((match = emojiShortcodeRegex.exec(text)) !== null) {
204-
const shortcode = match[1];
205-
const emojiData = getEmojiDataByShortcode(shortcode);
206-
const precedingText = text.slice(lastIndex, match.index);
203+
while ((match = emojiShortcodeRegex.exec(text)) !== null) {
204+
const shortcode = match[1];
205+
const emojiData = getEmojiDataByShortcode(shortcode);
206+
const precedingText = text.slice(lastIndex, match.index);
207207

208-
// Add text before the emoji shortcode
209-
if (precedingText) {
210-
components.push(precedingText);
211-
}
208+
// Add text before the emoji shortcode
209+
if (precedingText) {
210+
components.push(precedingText);
211+
}
212212

213-
// Add the Emoji component or the original shortcode text
214-
if (emojiData) {
215-
if (emojiData.unified) {
216-
components.push(
217-
<Emoji
218-
key={`${match.index}-${shortcode}`} // Unique key
219-
unified={emojiData.unified}
220-
size={20} // Adjust size as needed
221-
/>
222-
);
223-
} else if (emojiData.customUrl) {
224-
// Render custom emoji using emojiUrl
225-
components.push(
226-
<img src={emojiData.customUrl} alt={shortcode} style={{ height: '20px', width: '20px', fontSize: '20px' }} />
227-
// Not sure why the below doesn't work. It seems like it should according to the docs. :shrug:s
228-
// <Emoji
229-
// key={`${match.index}-${shortcode}`}
230-
// emojiUrl={emojiData.customUrl}
231-
// size={20}
232-
// />
233-
);
213+
// Add the Emoji component or the original shortcode text
214+
if (emojiData) {
215+
if (emojiData.unified) {
216+
components.push(
217+
<Emoji
218+
key={`${match.index}-${shortcode}`} // Unique key
219+
unified={emojiData.unified}
220+
size={20} // Adjust size as needed
221+
/>
222+
);
223+
} else if (emojiData.customUrl) {
224+
// Render custom emoji using emojiUrl
225+
components.push(
226+
<img
227+
src={emojiData.customUrl}
228+
alt={shortcode}
229+
style={{ height: '20px', width: '20px', fontSize: '20px' }}
230+
/>
231+
// Not sure why the below doesn't work. It seems like it should according to the docs. :shrug:s
232+
// <Emoji
233+
// key={`${match.index}-${shortcode}`}
234+
// emojiUrl={emojiData.customUrl}
235+
// size={20}
236+
// />
237+
);
238+
}
239+
} else {
240+
// If shortcode not found in map, render the original text
241+
components.push(match[0]);
234242
}
235-
} else {
236-
// If shortcode not found in map, render the original text
237-
components.push(match[0]);
238-
}
239243

240-
lastIndex = emojiShortcodeRegex.lastIndex;
241-
}
244+
lastIndex = emojiShortcodeRegex.lastIndex;
245+
}
242246

243-
// Add any remaining text after the last shortcode
244-
const remainingText = text.slice(lastIndex);
245-
if (remainingText) {
246-
components.push(remainingText);
247-
}
247+
// Add any remaining text after the last shortcode
248+
const remainingText = text.slice(lastIndex);
249+
if (remainingText) {
250+
components.push(remainingText);
251+
}
248252

249-
// If the original text had no shortcodes, return it in an array
250-
return components.length === 0 ? [text] : components;
251-
}, [getEmojiDataByShortcode]);
253+
// If the original text had no shortcodes, return it in an array
254+
return components.length === 0 ? [text] : components;
255+
},
256+
[getEmojiDataByShortcode]
257+
);
252258

253259
// Creates the final array of React components for the message body,
254260
// processing Slack links, member names, and emojis.
@@ -338,4 +344,4 @@ const EnhancedKudos = ({kudos}) => {
338344

339345
EnhancedKudos.propTypes = propTypes;
340346

341-
export default EnhancedKudos;
347+
export default EnhancedKudos;

web-ui/src/components/kudos/PublicKudosCard.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ const KudosCard = ({ kudos }) => {
5050
<Typography>{`+${num}`}</Typography>
5151
</Tooltip>
5252
);
53-
},[]);
53+
}, []);
5454

5555
const getRecipientComponent = useCallback(() => {
5656
if (kudos.recipientTeam) {

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ const KudosCard = ({ kudos, includeActions, includeEdit, onKudosAction }) => {
8383
<Typography>{`+${num}`}</Typography>
8484
</Tooltip>
8585
);
86-
},[]);
86+
}, []);
8787

8888
const getRecipientComponent = useCallback(() => {
8989
if (kudos.recipientTeam) {
@@ -93,9 +93,9 @@ const KudosCard = ({ kudos, includeActions, includeEdit, onKudosAction }) => {
9393
key={kudos.recipientTeam.id}
9494
title={kudos.recipientTeam.name}
9595
>
96-
<Avatar>
97-
<TeamIcon />
98-
</Avatar>
96+
<Avatar>
97+
<TeamIcon />
98+
</Avatar>
9999
</Tooltip>
100100
);
101101
}

web-ui/src/setupTests.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,4 @@ global.window.requestAnimationFrame = global.requestAnimationFrame =
4747
requestAnimationFrame;
4848
//global.window.addEventListener = global.addEventListener;
4949

50-
global.window.snackDispatch = vi.fn();
50+
global.window.snackDispatch = vi.fn();

0 commit comments

Comments
 (0)