diff options
Diffstat (limited to 'webapp/components/suggestion/at_mention_provider.jsx')
-rw-r--r-- | webapp/components/suggestion/at_mention_provider.jsx | 134 |
1 files changed, 54 insertions, 80 deletions
diff --git a/webapp/components/suggestion/at_mention_provider.jsx b/webapp/components/suggestion/at_mention_provider.jsx index 9998e6357..d4f441f98 100644 --- a/webapp/components/suggestion/at_mention_provider.jsx +++ b/webapp/components/suggestion/at_mention_provider.jsx @@ -1,19 +1,19 @@ // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -import React from 'react'; +import Suggestion from './suggestion.jsx'; -import SuggestionStore from 'stores/suggestion_store.jsx'; import ChannelStore from 'stores/channel_store.jsx'; -import UserStore from 'stores/user_store.jsx'; + +import {autocompleteUsersInChannel} from 'actions/user_actions.jsx'; + +import AppDispatcher from 'dispatcher/app_dispatcher.jsx'; import * as Utils from 'utils/utils.jsx'; import Client from 'client/web_client.jsx'; -import Constants from 'utils/constants.jsx'; +import {Constants, ActionTypes} from 'utils/constants.jsx'; +import React from 'react'; import {FormattedMessage} from 'react-intl'; -import Suggestion from './suggestion.jsx'; - -const MaxUserSuggestions = 40; class AtMentionSuggestion extends Suggestion { render() { @@ -99,92 +99,66 @@ class AtMentionSuggestion extends Suggestion { } } -function filterUsersByPrefix(users, prefix, limit, type) { - const filtered = []; - - for (const id of Object.keys(users)) { - if (filtered.length >= limit) { - break; - } - - const user = users[id]; - - if (user.delete_at > 0) { - continue; - } - - if (user.username.startsWith(prefix) || - (user.first_name && user.first_name.toLowerCase().startsWith(prefix)) || - (user.last_name && user.last_name.toLowerCase().startsWith(prefix)) || - (user.nickname && user.nickname.toLowerCase().startsWith(prefix))) { - // create a new object here since we're mutating it by adding the type field - filtered.push(Object.assign({}, user, {type})); - } - } - - return filtered; -} - export default class AtMentionProvider { constructor(channelId) { this.channelId = channelId; + this.timeoutId = ''; + } + + componentWillUnmount() { + clearTimeout(this.timeoutId); } handlePretextChanged(suggestionId, pretext) { + clearTimeout(this.timeoutId); + const captured = (/@([a-z0-9\-\._]*)$/i).exec(pretext.toLowerCase()); if (captured) { const prefix = captured[1]; - // Group users into members and nonmembers of the channel. - const users = UserStore.getActiveOnlyProfiles(true); - const channelMembers = {}; - const channelNonmembers = users; - if (this.channelId != null) { - const extraInfo = ChannelStore.getExtraInfo(this.channelId); - for (let i = 0; i < extraInfo.members.length; i++) { - const id = extraInfo.members[i].id; - if (users[id]) { - channelMembers[id] = users[id]; - Reflect.deleteProperty(channelNonmembers, id); + function autocomplete() { + autocompleteUsersInChannel( + prefix, + this.channelId, + (data) => { + const members = data.in_channel; + for (const id of Object.keys(members)) { + members[id].type = Constants.MENTION_MEMBERS; + } + + const nonmembers = data.out_of_channel; + for (const id of Object.keys(nonmembers)) { + nonmembers[id].type = Constants.MENTION_NONMEMBERS; + } + + let specialMentions = []; + if (!pretext.startsWith('/msg')) { + specialMentions = ['here', 'channel', 'all'].filter((item) => { + return item.startsWith(prefix); + }).map((name) => { + return {username: name, type: Constants.MENTION_SPECIAL}; + }); + } + + const users = members.concat(specialMentions).concat(nonmembers); + const mentions = users.map((user) => '@' + user.username); + + AppDispatcher.handleServerAction({ + type: ActionTypes.SUGGESTION_RECEIVED_SUGGESTIONS, + id: suggestionId, + matchedPretext: captured[0], + terms: mentions, + items: users, + component: AtMentionSuggestion + }); } - } - } - - // Filter users by prefix. - const filteredMembers = filterUsersByPrefix( - channelMembers, prefix, MaxUserSuggestions, Constants.MENTION_MEMBERS); - const filteredNonmembers = filterUsersByPrefix( - channelNonmembers, prefix, MaxUserSuggestions - filteredMembers.length, Constants.MENTION_NONMEMBERS); - let filteredSpecialMentions = []; - if (!pretext.startsWith('/msg')) { - filteredSpecialMentions = ['here', 'channel', 'all'].filter((item) => { - return item.startsWith(prefix); - }).map((name) => { - return {username: name, type: Constants.MENTION_SPECIAL}; - }); + ); } - // Sort users by username. - [filteredMembers, filteredNonmembers].forEach((items) => { - items.sort((a, b) => { - const aPrefix = a.username.startsWith(prefix); - const bPrefix = b.username.startsWith(prefix); - - if (aPrefix === bPrefix) { - return a.username.localeCompare(b.username); - } else if (aPrefix) { - return -1; - } - - return 1; - }); - }); - - const filtered = filteredMembers.concat(filteredSpecialMentions).concat(filteredNonmembers); - - const mentions = filtered.map((user) => '@' + user.username); - - SuggestionStore.addSuggestions(suggestionId, mentions, filtered, AtMentionSuggestion, captured[0]); + this.timeoutId = setTimeout( + autocomplete.bind(this), + Constants.AUTOCOMPLETE_TIMEOUT + ); } } } |