Skip to content

Commit

Permalink
Fix custom emojis for statuses not loaded on page refresh (mattermost…
Browse files Browse the repository at this point in the history
  • Loading branch information
chetanyakan committed May 26, 2021
1 parent 9b2be75 commit 9052b08
Show file tree
Hide file tree
Showing 17 changed files with 230 additions and 105 deletions.
164 changes: 164 additions & 0 deletions actions/emoji_actions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.

import * as EmojiActions from 'mattermost-redux/actions/emojis';
import {getCustomEmojisByName} from 'mattermost-redux/selectors/entities/emojis';
import {getConfig} from 'mattermost-redux/selectors/entities/general';

import {setRecentEmojis} from 'actions/local_storage';
import {getEmojiMap, getRecentEmojis, isCustomEmojiEnabled} from 'selectors/emojis';
import {isCustomStatusEnabled, makeGetCustomStatus} from 'selectors/views/custom_status';

import {ActionTypes} from 'utils/constants';
import {EmojiIndicesByAlias} from 'utils/emoji';

export function loadRecentlyUsedCustomEmojis() {
return async (dispatch, getState) => {
const state = getState();
const config = getConfig(state);

if (config.EnableCustomEmoji !== 'true') {
return {data: true};
}

const recentEmojis = getRecentEmojis(state);
const emojiMap = getEmojiMap(state);
const missingEmojis = recentEmojis.filter((name) => !emojiMap.has(name));

missingEmojis.forEach((name) => {
dispatch(EmojiActions.getCustomEmojiByName(name));
});

return {data: true};
};
}

export function incrementEmojiPickerPage() {
return async (dispatch) => {
dispatch({
type: ActionTypes.INCREMENT_EMOJI_PICKER_PAGE,
});

return {data: true};
};
}

const MAXIMUM_RECENT_EMOJI = 27;

export function addRecentEmoji(alias) {
return (dispatch, getState) => {
const state = getState();
const recentEmojis = getRecentEmojis(state);
const emojiMap = getEmojiMap(state);

let name;
const emoji = emojiMap.get(alias);
if (!emoji) {
return;
} else if (emoji.name) {
name = emoji.name;
} else {
name = emoji.aliases[0];
}

const index = recentEmojis.indexOf(name);
if (index !== -1) {
recentEmojis.splice(index, 1);
}

recentEmojis.push(name);

if (recentEmojis.length > MAXIMUM_RECENT_EMOJI) {
recentEmojis.splice(0, recentEmojis.length - MAXIMUM_RECENT_EMOJI);
}

dispatch(setRecentEmojis(recentEmojis));
};
}

export function loadCustomEmojisForCustomStatusesByUserIds(userIds) {
return (dispatch, getState) => {
const state = getState();
const customEmojiEnabled = isCustomEmojiEnabled(state);
const customStatusEnabled = isCustomStatusEnabled(state);
if (!customEmojiEnabled || !customStatusEnabled) {
return {data: false};
}

const getCustomStatus = makeGetCustomStatus();
const emojisToLoad = new Set();

userIds.forEach((userId) => {
const customStatus = getCustomStatus(state, userId);
if (!customStatus || !customStatus.emoji) {
return;
}

emojisToLoad.add(customStatus.emoji);
});

return dispatch(loadCustomEmojisIfNeeded(Array.from(emojisToLoad)));
};
}

export function loadCustomEmojisIfNeeded(emojis) {
return (dispatch, getState) => {
if (!emojis || emojis.length === 0) {
return {data: false};
}

const state = getState();
const customEmojiEnabled = isCustomEmojiEnabled(state);
if (!customEmojiEnabled) {
return {data: false};
}

const systemEmojis = EmojiIndicesByAlias;
const customEmojisByName = getCustomEmojisByName(state);
const nonExistentCustomEmoji = state.entities.emojis.nonExistentEmoji;
const emojisToLoad = [];

emojis.forEach((emoji) => {
if (!emoji) {
return;
}

if (systemEmojis.has(emoji)) {
// It's a system emoji, no need to fetch
return;
}

if (nonExistentCustomEmoji.has(emoji)) {
// We've previously confirmed this is not a custom emoji
return;
}

if (customEmojisByName.has(emoji)) {
// We have the emoji, no need to fetch
return;
}

emojisToLoad.push(emoji);
});

return dispatch(EmojiActions.getCustomEmojisByName(emojisToLoad));
};
}

export function loadCustomStatusEmojisForPostList(posts) {
return (dispatch) => {
if (!posts || posts.length === 0) {
return {data: false};
}

const userIds = new Set();
Object.keys(posts).forEach((postId) => {
const post = posts[postId];
if (post.user_id) {
userIds.add(post.user_id);
}
});
return dispatch(loadCustomEmojisForCustomStatusesByUserIds(userIds));
};
}

74 changes: 0 additions & 74 deletions actions/emoji_actions.jsx

This file was deleted.

2 changes: 1 addition & 1 deletion actions/emoji_actions.mock.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import thunk from 'redux-thunk';
import configureStore from 'redux-mock-store';

import * as Actions from 'actions/emoji_actions.jsx';
import * as Actions from 'actions/emoji_actions';
import {getEmojiMap, getRecentEmojis} from 'selectors/emojis';

const mockStore = configureStore([thunk]);
Expand Down
2 changes: 1 addition & 1 deletion actions/emoji_actions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import assert from 'assert';

import {getRecentEmojis} from 'selectors/emojis';
import * as Actions from 'actions/emoji_actions.jsx';
import * as Actions from 'actions/emoji_actions';
import configureStore from 'store';

describe('Actions.Emojis', () => {
Expand Down
5 changes: 4 additions & 1 deletion actions/status_actions.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {getPostsInCurrentChannel} from 'mattermost-redux/selectors/entities/post
import {getDirectShowPreferences} from 'mattermost-redux/selectors/entities/preferences';
import {getCurrentUserId} from 'mattermost-redux/selectors/entities/users';

import {loadCustomEmojisForCustomStatusesByUserIds} from 'actions/emoji_actions';
import store from 'stores/redux_store.jsx';
import {Constants} from 'utils/constants';

Expand Down Expand Up @@ -79,10 +80,12 @@ export function loadStatusesForProfilesMap(users) {
export function loadStatusesByIds(userIds) {
return (dispatch) => {
if (userIds.length === 0) {
return;
return {data: false};
}

dispatch(getStatusesByIds(userIds));
dispatch(loadCustomEmojisForCustomStatusesByUserIds(userIds));
return {data: true};
};
}

Expand Down
6 changes: 6 additions & 0 deletions actions/status_actions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ describe('actions/status_actions', () => {
myMembers: {channel_id1: {channel_id: 'channel_id1', user_id: 'current_user_id'}},
channelsInTeam: {team_id1: ['channel_id1']},
},
general: {
config: {
EnableCustomEmoji: 'true',
EnableCustomUserStatuses: 'true',
},
},
teams: {
currentTeamId: 'team_id1',
teams: {
Expand Down
10 changes: 10 additions & 0 deletions actions/user_actions.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import * as Selectors from 'mattermost-redux/selectors/entities/users';
import {legacyMakeFilterAutoclosedDMs, makeFilterManuallyClosedDMs} from 'mattermost-redux/selectors/entities/channel_categories';
import {CategoryTypes} from 'mattermost-redux/constants/channel_categories';

import {loadCustomEmojisForCustomStatusesByUserIds} from 'actions/emoji_actions';
import {loadStatusesForProfilesList, loadStatusesForProfilesMap} from 'actions/status_actions.jsx';
import {trackEvent} from 'actions/telemetry_actions.jsx';

Expand Down Expand Up @@ -328,8 +329,12 @@ export async function loadProfilesForGM() {
const userIdsInChannels = Selectors.getUserIdsInChannels(state);
const currentUserId = Selectors.getCurrentUserId(state);

const userIdsForLoadingCustomEmojis = new Set();
for (const channel of getGMsForLoading(state)) {
const userIds = userIdsInChannels[channel.id] || new Set();

userIds.forEach((userId) => userIdsForLoadingCustomEmojis.add(userId));

if (userIds.size >= Constants.MIN_USERS_IN_GM) {
continue;
}
Expand All @@ -355,6 +360,10 @@ export async function loadProfilesForGM() {
}

await queue.onEmpty();

if (userIdsForLoadingCustomEmojis.size > 0) {
dispatch(loadCustomEmojisForCustomStatusesByUserIds(userIdsForLoadingCustomEmojis));
}
if (newPreferences.length > 0) {
dispatch(savePreferences(currentUserId, newPreferences));
}
Expand Down Expand Up @@ -404,6 +413,7 @@ export async function loadProfilesForDM() {
if (profilesToLoad.length > 0) {
await UserActions.getProfilesByIds(profilesToLoad)(dispatch, getState);
}
await loadCustomEmojisForCustomStatusesByUserIds(profileIds)(dispatch, getState);
}

export function autocompleteUsersInTeam(username) {
Expand Down
6 changes: 5 additions & 1 deletion actions/views/channel.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {getChannelByName} from 'mattermost-redux/utils/channel_utils';
import EventEmitter from 'mattermost-redux/utils/event_emitter';

import {openDirectChannelToUserId} from 'actions/channel_actions.jsx';
import {loadCustomStatusEmojisForPostList} from 'actions/emoji_actions';
import {getLastViewedChannelName} from 'selectors/local_storage';
import {getLastPostsApiTimeForChannel} from 'selectors/views/channel';
import {getSocketStatus} from 'selectors/views/websocket';
Expand Down Expand Up @@ -230,8 +231,9 @@ export function loadUnreads(channelId, prefetch = false) {
atOldestmessage: false,
};
}
const actions = [];
dispatch(loadCustomStatusEmojisForPostList(data.posts));

const actions = [];
actions.push({
type: ActionTypes.INCREASE_POST_VISIBILITY,
data: channelId,
Expand Down Expand Up @@ -345,6 +347,8 @@ export function loadPosts({channelId, postId, type}) {
moreToLoad: true,
};
}

dispatch(loadCustomStatusEmojisForPostList(data.posts));
actions.push({
type: ActionTypes.INCREASE_POST_VISIBILITY,
data: channelId,
Expand Down
5 changes: 5 additions & 0 deletions actions/websocket_actions.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ import {syncPostsInChannel} from 'actions/views/channel';

import {browserHistory} from 'utils/browser_history';
import {loadChannelsForCurrentUser} from 'actions/channel_actions.jsx';
import {loadCustomEmojisIfNeeded} from 'actions/emoji_actions';
import {redirectUserToDefaultTeam} from 'actions/global_actions';
import {handleNewPost} from 'actions/post_actions.jsx';
import * as StatusActions from 'actions/status_actions.jsx';
Expand Down Expand Up @@ -975,6 +976,10 @@ export async function handleUserUpdatedEvent(msg) {
const state = getState();
const currentUser = getCurrentUser(state);
const user = msg.data.user;
if (user && user.props) {
const customStatus = user.props.customStatus ? JSON.parse(user.props.customStatus) : undefined;
dispatch(loadCustomEmojisIfNeeded([customStatus?.emoji]));
}

const config = getConfig(state);
const license = getLicense(state);
Expand Down
Loading

0 comments on commit 9052b08

Please sign in to comment.