MM-53164 Batch adding multiple custom emojis when making a post (#23822)

This commit is contained in:
Harrison Healey 2023-06-22 15:41:43 -04:00 committed by GitHub
parent a7bf602478
commit 5a540ea23e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 88 additions and 41 deletions

View File

@ -60,43 +60,49 @@ export function setUserSkinTone(skin) {
}; };
} }
export function addRecentEmoji(alias) {
return addRecentEmojis([alias]);
}
export const MAXIMUM_RECENT_EMOJI = 27; export const MAXIMUM_RECENT_EMOJI = 27;
export function addRecentEmoji(alias) { export function addRecentEmojis(aliases) {
return (dispatch, getState) => { return (dispatch, getState) => {
const state = getState(); const state = getState();
const currentUserId = getCurrentUserId(state); const currentUserId = getCurrentUserId(state);
const recentEmojis = getRecentEmojisData(state); const recentEmojis = getRecentEmojisData(state);
const emojiMap = getEmojiMap(state); const emojiMap = getEmojiMap(state);
let updatedRecentEmojis = [...recentEmojis];
for (const alias of aliases) {
let name; let name;
const emoji = emojiMap.get(alias); const emoji = emojiMap.get(alias);
if (!emoji) { if (!emoji) {
return {data: false}; continue;
} else if (emoji.short_name) { } else if (emoji.short_name) {
name = emoji.short_name; name = emoji.short_name;
} else { } else {
name = emoji.name; name = emoji.name;
} }
let updatedRecentEmojis; const currentEmojiIndexInRecentList = updatedRecentEmojis.findIndex((recentEmoji) => recentEmoji.name === name);
const currentEmojiIndexInRecentList = recentEmojis.findIndex((recentEmoji) => recentEmoji.name === name);
if (currentEmojiIndexInRecentList > -1) { if (currentEmojiIndexInRecentList > -1) {
const currentEmojiInRecentList = recentEmojis[currentEmojiIndexInRecentList]; const currentEmojiInRecentList = updatedRecentEmojis[currentEmojiIndexInRecentList];
// If the emoji is already in the recent list, remove it and add it to the front with updated usage count // If the emoji is already in the recent list, remove it and add it to the front with updated usage count
const updatedCurrentEmojiData = { const updatedCurrentEmojiData = {
name, name,
usageCount: currentEmojiInRecentList.usageCount + 1, usageCount: currentEmojiInRecentList.usageCount + 1,
}; };
recentEmojis.splice(currentEmojiIndexInRecentList, 1); updatedRecentEmojis.splice(currentEmojiIndexInRecentList, 1);
updatedRecentEmojis = [...recentEmojis, updatedCurrentEmojiData].slice(-MAXIMUM_RECENT_EMOJI); updatedRecentEmojis = [...updatedRecentEmojis, updatedCurrentEmojiData].slice(-MAXIMUM_RECENT_EMOJI);
} else { } else {
const currentEmojiData = { const currentEmojiData = {
name, name,
usageCount: 1, usageCount: 1,
}; };
updatedRecentEmojis = [...recentEmojis, currentEmojiData].slice(-MAXIMUM_RECENT_EMOJI); updatedRecentEmojis = [...updatedRecentEmojis, currentEmojiData].slice(-MAXIMUM_RECENT_EMOJI);
}
} }
// sort emojis by count in the ascending order // sort emojis by count in the ascending order

View File

@ -236,4 +236,49 @@ describe('Actions.Emojis', () => {
await store.dispatch(EmojiActions.addRecentEmoji('accept')); await store.dispatch(EmojiActions.addRecentEmoji('accept'));
expect(store.getActions()).toEqual(expectedActions); expect(store.getActions()).toEqual(expectedActions);
}); });
test('Should add multiple emojis to recent emojis at once', async () => {
const recentEmojisList = [
{name: 'trumpet', usageCount: 1},
{name: 'balloon', usageCount: 3},
{name: 'taco', usageCount: 4},
];
getRecentEmojisData.mockImplementation(() => {
return recentEmojisList;
});
getEmojiMap.mockImplementation(() => {
return new Map([
['accept', {short_name: 'accept'}],
['balloon', {short_name: 'balloon'}],
['grinning', {short_name: 'grinning'}],
['taco', {short_name: 'taco'}],
['trumpet', {short_name: 'trumpet'}],
]);
});
const expectedActions = [{
type: 'RECEIVED_PREFERENCES',
args: [
'current_user_id',
[
{
category: 'recent_emojis',
name: 'current_user_id',
user_id: 'current_user_id',
value: JSON.stringify([
{name: 'trumpet', usageCount: 1},
{name: 'grinning', usageCount: 1},
{name: 'accept', usageCount: 2},
{name: 'taco', usageCount: 4},
{name: 'balloon', usageCount: 5},
]),
},
],
],
}];
await store.dispatch(EmojiActions.addRecentEmojis(['balloon', 'grinning', 'accept', 'balloon', 'accept']));
expect(store.getActions()).toEqual(expectedActions);
});
}); });

View File

@ -27,6 +27,7 @@ jest.mock('mattermost-redux/actions/posts', () => ({
jest.mock('actions/emoji_actions', () => ({ jest.mock('actions/emoji_actions', () => ({
addRecentEmoji: (...args: any[]) => ({type: 'MOCK_ADD_RECENT_EMOJI', args}), addRecentEmoji: (...args: any[]) => ({type: 'MOCK_ADD_RECENT_EMOJI', args}),
addRecentEmojis: (...args: any[]) => ({type: 'MOCK_ADD_RECENT_EMOJIS', args}),
})); }));
jest.mock('actions/notification_actions', () => ({ jest.mock('actions/notification_actions', () => ({
@ -376,8 +377,8 @@ describe('Actions.Posts', () => {
const files: FileInfo[] = []; const files: FileInfo[] = [];
const immediateExpectedState = [{ const immediateExpectedState = [{
args: ['+1'], args: [['+1']],
type: 'MOCK_ADD_RECENT_EMOJI', type: 'MOCK_ADD_RECENT_EMOJIS',
}, { }, {
args: [newPost, files], args: [newPost, files],
type: 'MOCK_CREATE_POST', type: 'MOCK_CREATE_POST',
@ -396,8 +397,8 @@ describe('Actions.Posts', () => {
const files: FileInfo[] = []; const files: FileInfo[] = [];
const immediateExpectedState = [{ const immediateExpectedState = [{
args: ['cake'], args: [['cake']],
type: 'MOCK_ADD_RECENT_EMOJI', type: 'MOCK_ADD_RECENT_EMOJIS',
}, { }, {
args: [newPost, files], args: [newPost, files],
type: 'MOCK_CREATE_POST', type: 'MOCK_CREATE_POST',
@ -416,11 +417,8 @@ describe('Actions.Posts', () => {
const files: FileInfo[] = []; const files: FileInfo[] = [];
const immediateExpectedState = [{ const immediateExpectedState = [{
args: ['cake'], args: [['cake', '+1']],
type: 'MOCK_ADD_RECENT_EMOJI', type: 'MOCK_ADD_RECENT_EMOJIS',
}, {
args: ['+1'],
type: 'MOCK_ADD_RECENT_EMOJI',
}, { }, {
args: [newPost, files], args: [newPost, files],
type: 'MOCK_CREATE_POST', type: 'MOCK_CREATE_POST',

View File

@ -17,7 +17,7 @@ import {getCurrentTeamId} from 'mattermost-redux/selectors/entities/teams';
import {canEditPost, comparePosts} from 'mattermost-redux/utils/post_utils'; import {canEditPost, comparePosts} from 'mattermost-redux/utils/post_utils';
import {DispatchFunc, GetStateFunc} from 'mattermost-redux/types/actions'; import {DispatchFunc, GetStateFunc} from 'mattermost-redux/types/actions';
import {addRecentEmoji} from 'actions/emoji_actions'; import {addRecentEmoji, addRecentEmojis} from 'actions/emoji_actions';
import * as StorageActions from 'actions/storage'; import * as StorageActions from 'actions/storage';
import {loadNewDMIfNeeded, loadNewGMIfNeeded} from 'actions/user_actions'; import {loadNewDMIfNeeded, loadNewGMIfNeeded} from 'actions/user_actions';
import * as RhsActions from 'actions/views/rhs'; import * as RhsActions from 'actions/views/rhs';
@ -102,10 +102,8 @@ export function createPost(post: Post, files: FileInfo[]) {
// parse message and emit emoji event // parse message and emit emoji event
const emojis = matchEmoticons(post.message); const emojis = matchEmoticons(post.message);
if (emojis) { if (emojis) {
for (const emoji of emojis) { const trimmedEmojis = emojis.map((emoji) => emoji.substring(1, emoji.length - 1));
const trimmed = emoji.substring(1, emoji.length - 1); dispatch(addRecentEmojis(trimmedEmojis));
dispatch(addRecentEmoji(trimmed));
}
} }
let result; let result;