diff --git a/app/components/autocomplete/at_mention_item/at_mention_item.js b/app/components/autocomplete/at_mention_item/at_mention_item.js index a91cc399c..11f0b481c 100644 --- a/app/components/autocomplete/at_mention_item/at_mention_item.js +++ b/app/components/autocomplete/at_mention_item/at_mention_item.js @@ -13,6 +13,7 @@ import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone import {BotTag, GuestTag} from 'app/components/tag'; import TouchableWithFeedback from 'app/components/touchable_with_feedback'; import {makeStyleSheetFromTheme} from 'app/utils/theme'; +import FormattedText from 'app/components/formatted_text'; export default class AtMentionItem extends PureComponent { static propTypes = { @@ -25,6 +26,7 @@ export default class AtMentionItem extends PureComponent { isBot: PropTypes.bool, theme: PropTypes.object.isRequired, isLandscape: PropTypes.bool.isRequired, + isCurrentUser: PropTypes.bool.isRequired, }; static defaultProps = { @@ -47,6 +49,7 @@ export default class AtMentionItem extends PureComponent { isBot, isLandscape, isGuest, + isCurrentUser, } = this.props; const style = getStyleFromTheme(theme); @@ -78,6 +81,12 @@ export default class AtMentionItem extends PureComponent { /> {hasFullName && {' - '}} {hasFullName && {`${firstName} ${lastName}`}} + {isCurrentUser && + } ); } diff --git a/app/components/autocomplete/at_mention_item/index.js b/app/components/autocomplete/at_mention_item/index.js index ba634b989..73a584a66 100644 --- a/app/components/autocomplete/at_mention_item/index.js +++ b/app/components/autocomplete/at_mention_item/index.js @@ -3,7 +3,7 @@ import {connect} from 'react-redux'; -import {getUser} from 'mattermost-redux/selectors/entities/users'; +import {getCurrentUserId, getUser} from 'mattermost-redux/selectors/entities/users'; import {getTheme} from 'mattermost-redux/selectors/entities/preferences'; @@ -23,6 +23,7 @@ function mapStateToProps(state, ownProps) { isGuest: isGuest(user), theme: getTheme(state), isLandscape: isLandscape(state), + isCurrentUser: getCurrentUserId(state) === user.id, }; } diff --git a/app/selectors/autocomplete.js b/app/selectors/autocomplete.js index 926a44a48..3fe877f50 100644 --- a/app/selectors/autocomplete.js +++ b/app/selectors/autocomplete.js @@ -7,7 +7,7 @@ import {General} from 'mattermost-redux/constants'; import {getConfig} from 'mattermost-redux/selectors/entities/general'; import {getMyChannels, getOtherChannels} from 'mattermost-redux/selectors/entities/channels'; import { - getCurrentUser, getCurrentUserId, getProfilesInCurrentChannel, + getCurrentUser, getProfilesInCurrentChannel, getProfilesNotInCurrentChannel, getProfilesInCurrentTeam, } from 'mattermost-redux/selectors/entities/users'; import {sortChannelsByDisplayName} from 'mattermost-redux/utils/channel_utils'; @@ -64,9 +64,8 @@ export const getMatchTermForChannelMention = (() => { export const filterMembersInChannel = createSelector( getProfilesInCurrentChannel, - getCurrentUserId, (state, matchTerm) => matchTerm, - (profilesInChannel, currentUserId, matchTerm) => { + (profilesInChannel, matchTerm) => { if (matchTerm === null) { return null; } @@ -74,12 +73,12 @@ export const filterMembersInChannel = createSelector( let profiles; if (matchTerm) { profiles = profilesInChannel.filter((p) => { - return ((p.id !== currentUserId && p.delete_at === 0) && ( + return (p.delete_at === 0 && ( p.username.toLowerCase().includes(matchTerm) || p.email.toLowerCase().includes(matchTerm) || p.first_name.toLowerCase().includes(matchTerm) || p.last_name.toLowerCase().includes(matchTerm))); }); } else { - profiles = profilesInChannel.filter((p) => p.id !== currentUserId && p.delete_at === 0); + profiles = profilesInChannel.filter((p) => p.delete_at === 0); } // already sorted @@ -89,9 +88,8 @@ export const filterMembersInChannel = createSelector( export const filterMembersNotInChannel = createSelector( getProfilesNotInCurrentChannel, - getCurrentUserId, (state, matchTerm) => matchTerm, - (profilesNotInChannel, currentUserId, matchTerm) => { + (profilesNotInChannel, matchTerm) => { if (matchTerm === null) { return null; } @@ -104,7 +102,7 @@ export const filterMembersNotInChannel = createSelector( p.email.toLowerCase().includes(matchTerm) || p.first_name.toLowerCase().includes(matchTerm) || p.last_name.toLowerCase().includes(matchTerm) - ) && (p.delete_at === 0 && p.id !== currentUserId); + ) && p.delete_at === 0; }); } else { profiles = profilesNotInChannel.filter((p) => p.delete_at === 0); diff --git a/app/selectors/autocomplete.test.js b/app/selectors/autocomplete.test.js index 8ba21af98..fb823ed22 100644 --- a/app/selectors/autocomplete.test.js +++ b/app/selectors/autocomplete.test.js @@ -6,6 +6,7 @@ import assert from 'assert'; import { getMatchTermForAtMention, filterMembersNotInChannel, + filterMembersInChannel, } from 'app/selectors/autocomplete'; /* eslint-disable max-nested-callbacks */ @@ -67,24 +68,24 @@ describe('Selectors.Autocomplete', () => { users: { currentUserId: 'current-user-id', profiles: { - 'current-user-id': {id: 'current-user-id', username: 'current', delete_at: 0}, + 'current-user-id': {id: 'current-user-id', username: 'current', first_name: 'Current', last_name: 'User', email: 'current@user.com', delete_at: 0}, 'test-user-id': {id: 'test-user-id', username: 'test', first_name: 'Test', last_name: 'User', email: 'test@example.com', delete_at: 0}, 'another-user-id': {id: 'another-user-id', username: 'another', first_name: 'Another', last_name: 'One', email: 'another@example.com', delete_at: 0}, 'deleted-user-id': {id: 'deleted-user-id', username: 'deleted', first_name: 'Remvoed', last_name: 'Friend', email: 'deleted@example.com', delete_at: 123}, }, profilesNotInChannel: { - 'current-channel-id': new Set(['test-user-id', 'another-user-id', 'deleted-user-id']), + 'current-channel-id': new Set(['current-user-id', 'test-user-id', 'another-user-id', 'deleted-user-id']), }, }, }, }; let profiles = filterMembersNotInChannel(state, ''); - expect(profiles.length).toBe(2); + expect(profiles.length).toBe(3); - // filter to get the current user, should return zero results + // filter to get the current user, should return single result profiles = filterMembersNotInChannel(state, 'current'); - expect(profiles.length).toBe(0); + expect(profiles.length).toBe(1); profiles = filterMembersNotInChannel(state, 'tes'); expect(profiles.length).toBe(1); @@ -95,4 +96,42 @@ describe('Selectors.Autocomplete', () => { profiles = filterMembersNotInChannel(state, 'example'); expect(profiles.length).toBe(2); }); + + it('Should return profiles in channel', () => { + const state = { + entities: { + channels: { + currentChannelId: 'current-channel-id', + }, + users: { + currentUserId: 'current-user-id', + profiles: { + 'current-user-id': {id: 'current-user-id', username: 'current', first_name: 'Current', last_name: 'User', email: 'current@user.com', delete_at: 0}, + 'test-user-id': {id: 'test-user-id', username: 'test', first_name: 'Test', last_name: 'User', email: 'test@example.com', delete_at: 0}, + 'another-user-id': {id: 'another-user-id', username: 'another', first_name: 'Another', last_name: 'One', email: 'another@example.com', delete_at: 0}, + 'deleted-user-id': {id: 'deleted-user-id', username: 'deleted', first_name: 'Removed', last_name: 'Friend', email: 'deleted@example.com', delete_at: 123}, + 'another-channel-user-id': {id: 'another-channel-user-id', username: 'another_channel', first_name: 'Another', last_name: 'Channel', email: 'another_channel@example.com', delete_at: 0}, + }, + profilesInChannel: { + 'current-channel-id': new Set(['current-user-id', 'test-user-id', 'another-user-id', 'deleted-user-id']), + }, + }, + }, + }; + + let profiles = filterMembersInChannel(state, ''); + expect(profiles).toHaveLength(3); + + profiles = filterMembersInChannel(state, 'current'); + expect(profiles).toHaveLength(1); + + profiles = filterMembersInChannel(state, 'tes'); + expect(profiles.length).toBe(1); + + profiles = filterMembersInChannel(state, 'one'); + expect(profiles.length).toBe(1); + + profiles = filterMembersInChannel(state, 'example'); + expect(profiles.length).toBe(2); + }); }); diff --git a/assets/base/i18n/en.json b/assets/base/i18n/en.json index 65fd2ab22..6d785ed68 100644 --- a/assets/base/i18n/en.json +++ b/assets/base/i18n/en.json @@ -562,6 +562,7 @@ "suggestion.mention.morechannels": "Other Channels", "suggestion.mention.nonmembers": "Not in Channel", "suggestion.mention.special": "Special Mentions", + "suggestion.mention.you": "(you)", "suggestion.search.direct": "Direct Messages", "suggestion.search.private": "Private Channels", "suggestion.search.public": "Public Channels",