Unverified Commit 2eef4b34 authored by Saturnino Abril's avatar Saturnino Abril Committed by GitHub
Browse files

[MM-10727] Fix missing username on combined system messages (#1277)

* Fix missing username on combined system messages by supporting backward compatibility on addedUsername props when user was added to the channel or team

* updated mattermost-redux and explicitly get profiles by IDs or usernames
parent 87040dc2
......@@ -346,11 +346,12 @@ export function renderSystemMessage(post) {
} else if (post.type === Posts.POST_TYPES.EPHEMERAL_ADD_TO_CHANNEL) {
return renderAddToChannelMessage(post);
} else if (post.type === Posts.POST_TYPES.COMBINED_USER_ACTIVITY) {
const {allUserIds, messageData} = post.props.user_activity;
const {allUserIds, allUsernames, messageData} = post.props.user_activity;
return (
<CombinedSystemMessage
allUserIds={allUserIds}
allUsernames={allUsernames}
messageData={messageData}
/>
);
......
......@@ -3,15 +3,11 @@
import PropTypes from 'prop-types';
import React from 'react';
import {FormattedHTMLMessage} from 'react-intl';
import {FormattedHTMLMessage, intlShape} from 'react-intl';
import {displayUsername} from 'mattermost-redux/utils/user_utils';
import {Posts} from 'mattermost-redux/constants';
import {
getDisplayNameByUserId,
localizeMessage,
} from 'utils/utils.jsx';
import LastUsers from './last_users';
const {
......@@ -152,58 +148,119 @@ const postTypeMessage = {
export default class CombinedSystemMessage extends React.PureComponent {
static propTypes = {
allUserIds: PropTypes.array.isRequired,
allUsernames: PropTypes.array.isRequired,
currentUserId: PropTypes.string.isRequired,
currentUsername: PropTypes.string.isRequired,
messageData: PropTypes.array.isRequired,
allUserIds: PropTypes.array.isRequired,
teammateNameDisplay: PropTypes.string.isRequired,
actions: PropTypes.shape({
getMissingProfilesByIds: PropTypes.func.isRequired,
getProfilesByIds: PropTypes.func.isRequired,
getProfilesByUsernames: PropTypes.func.isRequired,
}).isRequired,
};
static defaultProps = {
allUserIds: [],
allUsernames: [],
};
static contextTypes = {
intl: intlShape,
};
constructor(props) {
super(props);
this.state = {
missingProfiles: [],
userProfiles: [],
};
}
componentDidMount() {
this.loadMissingProfiles();
this.loadUserProfiles(this.props.allUserIds, this.props.allUsernames);
}
UNSAFE_componentWillReceiveProps(nextProps) { // eslint-disable-line camelcase
if (this.props.allUserIds !== nextProps.allUserIds || this.props.allUsernames !== nextProps.allUsernames) {
this.loadUserProfiles(nextProps.allUserIds, nextProps.allUsernames);
}
}
loadUserProfiles = async (allUserIds, allUsernames) => {
const {actions} = this.props;
const userProfiles = [];
if (allUserIds.length > 0) {
const {data} = await actions.getProfilesByIds(allUserIds);
if (data.length > 0) {
userProfiles.push(...data);
}
}
if (allUsernames.length > 0) {
const {data} = await actions.getProfilesByUsernames(allUsernames);
if (data.length > 0) {
userProfiles.push(...data);
}
}
this.setState({userProfiles});
}
loadMissingProfiles = async () => {
getAllUsersDisplayName = () => {
const {userProfiles} = this.state;
const {
actions,
allUserIds,
allUsernames,
currentUserId,
currentUsername,
teammateNameDisplay,
} = this.props;
const missingProfiles = await actions.getMissingProfilesByIds(allUserIds);
this.setState({missingProfiles});
const {formatMessage} = this.context.intl;
const usersDisplayName = userProfiles.reduce((acc, user) => {
const displayName = displayUsername(user, teammateNameDisplay, true);
acc[user.id] = displayName;
acc[user.username] = displayName;
return acc;
}, {});
const currentUserDisplayName = formatMessage({id: 'combined_system_message.you', defaultMessage: 'You'});
if (allUserIds.includes(currentUserId)) {
usersDisplayName[currentUserId] = currentUserDisplayName;
} else if (allUsernames.includes(currentUsername)) {
usersDisplayName[currentUsername] = currentUserDisplayName;
}
return usersDisplayName;
}
getDisplayNameByIds = (userIds = []) => {
const {currentUserId} = this.props;
const {currentUserId, currentUsername} = this.props;
const usersDisplayName = this.getAllUsersDisplayName();
const displayNames = userIds.
filter((userId) => {
return userId !== currentUserId;
return userId !== currentUserId && userId !== currentUsername;
}).
map((userId) => {
return getDisplayNameByUserId(userId, true);
return usersDisplayName[userId];
}).filter((displayName) => {
return displayName && displayName !== '';
});
const userInProp = userIds.includes(currentUserId);
if (userInProp) {
displayNames.unshift(localizeMessage('combined_system_message.you', 'You'));
if (userIds.includes(currentUserId)) {
displayNames.unshift(usersDisplayName[currentUserId]);
} else if (userIds.includes(currentUsername)) {
displayNames.unshift(usersDisplayName[currentUsername]);
}
return displayNames;
}
renderFormattedMessage(postType, userIds, actorId) {
const {currentUserId, currentUsername} = this.props;
const userDisplayNames = this.getDisplayNameByIds(userIds);
let actor = actorId ? this.getDisplayNameByIds([actorId])[0] : '';
if (actorId === this.props.currentUserId) {
if (actor && (actorId === currentUserId || actorId === currentUsername)) {
actor = actor.toLowerCase();
}
......@@ -224,7 +281,7 @@ export default class CombinedSystemMessage extends React.PureComponent {
);
if (
userIds[0] === this.props.currentUserId &&
(userIds[0] === this.props.currentUserId || userIds[0] === this.props.currentUsername) &&
postTypeMessage[postType].one_you
) {
formattedMessage = (
......@@ -249,7 +306,7 @@ export default class CombinedSystemMessage extends React.PureComponent {
}}
/>
);
} else {
} else if (numOthers > 1) {
formattedMessage = (
<LastUsers
actor={actor}
......
......@@ -4,21 +4,27 @@
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import {getMissingProfilesByIds} from 'mattermost-redux/actions/users';
import {getCurrentUserId} from 'mattermost-redux/selectors/entities/users';
import {getProfilesByIds, getProfilesByUsernames} from 'mattermost-redux/actions/users';
import {getTeammateNameDisplaySetting} from 'mattermost-redux/selectors/entities/preferences';
import {getCurrentUser} from 'mattermost-redux/selectors/entities/users';
import CombinedSystemMessage from './combined_system_message.jsx';
function mapStateToProps(state) {
const currentUser = getCurrentUser(state);
return {
currentUserId: getCurrentUserId(state),
currentUserId: currentUser.id,
currentUsername: currentUser.username,
teammateNameDisplay: getTeammateNameDisplaySetting(state),
};
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators({
getMissingProfilesByIds,
getProfilesByIds,
getProfilesByUsernames,
}, dispatch),
};
}
......
......@@ -10869,8 +10869,8 @@
"dev": true
},
"mattermost-redux": {
"version": "github:mattermost/mattermost-redux#4e32d267a0a9ae72b04e55d3ce5f2bec7a1878d9",
"from": "github:mattermost/mattermost-redux#4e32d267a0a9ae72b04e55d3ce5f2bec7a1878d9",
"version": "github:mattermost/mattermost-redux#fe27e2bfa465aea739e82afe18fa7a6f512f74a0",
"from": "github:mattermost/mattermost-redux#fe27e2bfa465aea739e82afe18fa7a6f512f74a0",
"requires": {
"deep-equal": "1.0.1",
"eslint-plugin-header": "1.2.0",
......
......@@ -5,18 +5,7 @@ exports[`components/post_view/CombinedSystemMessage should match snapshot 1`] =
<React.Fragment
key="system_add_to_channeluser_id_1"
>
<span>
<FormattedHTMLMessage
defaultMessage="{firstUser} <b>added to the channel</b> by {actor}."
id="combined_system_message.added_to_channel.one"
values={
Object {
"actor": "",
"firstUser": "",
}
}
/>
</span>
<span />
<br />
</React.Fragment>
</React.Fragment>
......
......@@ -2,24 +2,30 @@
// See LICENSE.txt for license information.
import React from 'react';
import {shallow} from 'enzyme';
import {Posts} from 'mattermost-redux/constants';
import {General, Posts} from 'mattermost-redux/constants';
import {shallowWithIntl} from 'tests/helpers/intl-test-helper';
import CombinedSystemMessage from 'components/post_view/combined_system_message/combined_system_message.jsx';
describe('components/post_view/CombinedSystemMessage', () => {
function emptyFunc() {} // eslint-disable-line no-empty-function
const baseProps = {
teammateNameDisplay: General.TEAMMATE_NAME_DISPLAY.SHOW_USERNAME,
currentUserId: 'current_user_id',
currentUsername: 'current_username',
allUserIds: ['added_user_id_1', 'user_id_1'],
allUsernames: [],
messageData: [{actorId: 'user_id_1', postType: Posts.POST_TYPES.ADD_TO_CHANNEL, userIds: ['added_user_id_1']}],
actions: {
getMissingProfilesByIds: () => {}, // eslint-disable-line
getProfilesByIds: emptyFunc,
getProfilesByUsernames: emptyFunc,
},
};
test('should match snapshot', () => {
const wrapper = shallow(
const wrapper = shallowWithIntl(
<CombinedSystemMessage {...baseProps}/>
);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment