From bf3fec604fc4ad0fd53d38490c18d872bccd629d Mon Sep 17 00:00:00 2001 From: Joram Wilander Date: Tue, 20 Dec 2016 09:08:58 -0500 Subject: Remove autocomplete delay (#4819) --- .../components/suggestion/at_mention_provider.jsx | 95 +++++---------- .../suggestion/channel_mention_provider.jsx | 91 ++++++-------- .../suggestion/search_channel_provider.jsx | 79 +++++------- .../components/suggestion/search_user_provider.jsx | 49 +++----- .../suggestion/switch_channel_provider.jsx | 133 +++++++++------------ 5 files changed, 177 insertions(+), 270 deletions(-) (limited to 'webapp/components/suggestion') diff --git a/webapp/components/suggestion/at_mention_provider.jsx b/webapp/components/suggestion/at_mention_provider.jsx index f1b36d697..9a5e103ad 100644 --- a/webapp/components/suggestion/at_mention_provider.jsx +++ b/webapp/components/suggestion/at_mention_provider.jsx @@ -4,7 +4,6 @@ import Suggestion from './suggestion.jsx'; import ChannelStore from 'stores/channel_store.jsx'; -import SuggestionStore from 'stores/suggestion_store.jsx'; import {autocompleteUsersInChannel} from 'actions/user_actions.jsx'; @@ -104,79 +103,49 @@ class AtMentionSuggestion extends Suggestion { export default class AtMentionProvider { constructor(channelId) { this.channelId = channelId; - this.timeoutId = ''; - } - - componentWillUnmount() { - this.clearTimeout(this.timeoutId); - } - - clearTimeout() { - if (this.timeoutId) { - clearTimeout(this.timeoutId); - this.timeoutId = ''; - - return true; - } - - return false; } handlePretextChanged(suggestionId, pretext) { - const hadSuggestions = this.clearTimeout(this.timeoutId); - const captured = XRegExp.cache('(?:^|\\W)@([\\pL\\d\\-_.]*)$', 'i').exec(pretext.toLowerCase()); if (captured) { const prefix = captured[1]; - 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[1]}`, - terms: mentions, - items: users, - component: AtMentionSuggestion + 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}; }); } - ); - } - this.timeoutId = setTimeout( - autocomplete.bind(this), - Constants.AUTOCOMPLETE_TIMEOUT + 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[1]}`, + terms: mentions, + items: users, + component: AtMentionSuggestion + }); + } ); } - - if (hadSuggestions) { - // Clear the suggestions since the user has now typed something invalid - SuggestionStore.clearSuggestions(suggestionId); - } } } diff --git a/webapp/components/suggestion/channel_mention_provider.jsx b/webapp/components/suggestion/channel_mention_provider.jsx index c644d1a9f..7c781a2f7 100644 --- a/webapp/components/suggestion/channel_mention_provider.jsx +++ b/webapp/components/suggestion/channel_mention_provider.jsx @@ -50,69 +50,54 @@ class ChannelMentionSuggestion extends Suggestion { } export default class ChannelMentionProvider { - constructor() { - this.timeoutId = ''; - } - - componentWillUnmount() { - clearTimeout(this.timeoutId); - } - handlePretextChanged(suggestionId, pretext) { const captured = (/(^|\s)(~([^~]*))$/i).exec(pretext.toLowerCase()); if (captured) { const prefix = captured[3]; - function autocomplete() { - autocompleteChannels( - prefix, - (data) => { - const channels = data; - - // Wrap channels in an outer object to avoid overwriting the 'type' property. - const wrappedChannels = []; - const wrappedMoreChannels = []; - const moreChannels = []; - channels.forEach((item) => { - if (ChannelStore.get(item.id)) { - wrappedChannels.push({ - type: Constants.MENTION_CHANNELS, - channel: item - }); - return; - } - - wrappedMoreChannels.push({ - type: Constants.MENTION_MORE_CHANNELS, + autocompleteChannels( + prefix, + (data) => { + const channels = data; + + // Wrap channels in an outer object to avoid overwriting the 'type' property. + const wrappedChannels = []; + const wrappedMoreChannels = []; + const moreChannels = []; + channels.forEach((item) => { + if (ChannelStore.get(item.id)) { + wrappedChannels.push({ + type: Constants.MENTION_CHANNELS, channel: item }); + return; + } - moreChannels.push(item); - }); - - const wrapped = wrappedChannels.concat(wrappedMoreChannels); - const mentions = wrapped.map((item) => '~' + item.channel.name); - - AppDispatcher.handleServerAction({ - type: ActionTypes.RECEIVED_MORE_CHANNELS, - channels: moreChannels - }); - - AppDispatcher.handleServerAction({ - type: ActionTypes.SUGGESTION_RECEIVED_SUGGESTIONS, - id: suggestionId, - matchedPretext: captured[2], - terms: mentions, - items: wrapped, - component: ChannelMentionSuggestion + wrappedMoreChannels.push({ + type: Constants.MENTION_MORE_CHANNELS, + channel: item }); - } - ); - } - this.timeoutId = setTimeout( - autocomplete.bind(this), - Constants.AUTOCOMPLETE_TIMEOUT + moreChannels.push(item); + }); + + const wrapped = wrappedChannels.concat(wrappedMoreChannels); + const mentions = wrapped.map((item) => '~' + item.channel.name); + + AppDispatcher.handleServerAction({ + type: ActionTypes.RECEIVED_MORE_CHANNELS, + channels: moreChannels + }); + + AppDispatcher.handleServerAction({ + type: ActionTypes.SUGGESTION_RECEIVED_SUGGESTIONS, + id: suggestionId, + matchedPretext: captured[2], + terms: mentions, + items: wrapped, + component: ChannelMentionSuggestion + }); + } ); } } diff --git a/webapp/components/suggestion/search_channel_provider.jsx b/webapp/components/suggestion/search_channel_provider.jsx index 66011af9f..283113fb9 100644 --- a/webapp/components/suggestion/search_channel_provider.jsx +++ b/webapp/components/suggestion/search_channel_provider.jsx @@ -33,63 +33,48 @@ class SearchChannelSuggestion extends Suggestion { } export default class SearchChannelProvider { - constructor() { - this.timeoutId = ''; - } - - componentWillUnmount() { - clearTimeout(this.timeoutId); - } - handlePretextChanged(suggestionId, pretext) { const captured = (/\b(?:in|channel):\s*(\S*)$/i).exec(pretext.toLowerCase()); if (captured) { const channelPrefix = captured[1]; - function autocomplete() { - autocompleteChannels( - channelPrefix, - (data) => { - const publicChannels = data; + autocompleteChannels( + channelPrefix, + (data) => { + const publicChannels = data; - const localChannels = ChannelStore.getAll(); - const privateChannels = []; + const localChannels = ChannelStore.getAll(); + const privateChannels = []; - for (const id of Object.keys(localChannels)) { - const channel = localChannels[id]; - if (channel.name.startsWith(channelPrefix) && channel.type === Constants.PRIVATE_CHANNEL) { - privateChannels.push(channel); - } + for (const id of Object.keys(localChannels)) { + const channel = localChannels[id]; + if (channel.name.startsWith(channelPrefix) && channel.type === Constants.PRIVATE_CHANNEL) { + privateChannels.push(channel); } - - const filteredPublicChannels = []; - publicChannels.forEach((item) => { - if (item.name.startsWith(channelPrefix)) { - filteredPublicChannels.push(item); - } - }); - - privateChannels.sort((a, b) => a.name.localeCompare(b.name)); - filteredPublicChannels.sort((a, b) => a.name.localeCompare(b.name)); - - const channels = filteredPublicChannels.concat(privateChannels); - const channelNames = channels.map((channel) => channel.name); - - AppDispatcher.handleServerAction({ - type: ActionTypes.SUGGESTION_RECEIVED_SUGGESTIONS, - id: suggestionId, - matchedPretext: channelPrefix, - terms: channelNames, - items: channels, - component: SearchChannelSuggestion - }); } - ); - } - this.timeoutId = setTimeout( - autocomplete.bind(this), - Constants.AUTOCOMPLETE_TIMEOUT + const filteredPublicChannels = []; + publicChannels.forEach((item) => { + if (item.name.startsWith(channelPrefix)) { + filteredPublicChannels.push(item); + } + }); + + privateChannels.sort((a, b) => a.name.localeCompare(b.name)); + filteredPublicChannels.sort((a, b) => a.name.localeCompare(b.name)); + + const channels = filteredPublicChannels.concat(privateChannels); + const channelNames = channels.map((channel) => channel.name); + + AppDispatcher.handleServerAction({ + type: ActionTypes.SUGGESTION_RECEIVED_SUGGESTIONS, + id: suggestionId, + matchedPretext: channelPrefix, + terms: channelNames, + items: channels, + component: SearchChannelSuggestion + }); + } ); } } diff --git a/webapp/components/suggestion/search_user_provider.jsx b/webapp/components/suggestion/search_user_provider.jsx index 2aa72aef5..6fce8edcf 100644 --- a/webapp/components/suggestion/search_user_provider.jsx +++ b/webapp/components/suggestion/search_user_provider.jsx @@ -8,7 +8,7 @@ import {autocompleteUsersInTeam} from 'actions/user_actions.jsx'; import AppDispatcher from 'dispatcher/app_dispatcher.jsx'; import Client from 'client/web_client.jsx'; import * as Utils from 'utils/utils.jsx'; -import {Constants, ActionTypes} from 'utils/constants.jsx'; +import {ActionTypes} from 'utils/constants.jsx'; import React from 'react'; @@ -57,43 +57,26 @@ class SearchUserSuggestion extends Suggestion { } export default class SearchUserProvider { - constructor() { - this.timeoutId = ''; - } - - componentWillUnmount() { - clearTimeout(this.timeoutId); - } - handlePretextChanged(suggestionId, pretext) { - clearTimeout(this.timeoutId); - const captured = (/\bfrom:\s*(\S*)$/i).exec(pretext.toLowerCase()); if (captured) { const usernamePrefix = captured[1]; - function autocomplete() { - autocompleteUsersInTeam( - usernamePrefix, - (data) => { - const users = data.in_team; - const mentions = users.map((user) => user.username); - - AppDispatcher.handleServerAction({ - type: ActionTypes.SUGGESTION_RECEIVED_SUGGESTIONS, - id: suggestionId, - matchedPretext: usernamePrefix, - terms: mentions, - items: users, - component: SearchUserSuggestion - }); - } - ); - } - - this.timeoutId = setTimeout( - autocomplete.bind(this), - Constants.AUTOCOMPLETE_TIMEOUT + autocompleteUsersInTeam( + usernamePrefix, + (data) => { + const users = data.in_team; + const mentions = users.map((user) => user.username); + + AppDispatcher.handleServerAction({ + type: ActionTypes.SUGGESTION_RECEIVED_SUGGESTIONS, + id: suggestionId, + matchedPretext: usernamePrefix, + terms: mentions, + items: users, + component: SearchUserSuggestion + }); + } ); } } diff --git a/webapp/components/suggestion/switch_channel_provider.jsx b/webapp/components/suggestion/switch_channel_provider.jsx index b41bc4f11..bf9e7c646 100644 --- a/webapp/components/suggestion/switch_channel_provider.jsx +++ b/webapp/components/suggestion/switch_channel_provider.jsx @@ -59,94 +59,79 @@ class SwitchChannelSuggestion extends Suggestion { } export default class SwitchChannelProvider { - constructor() { - this.timeoutId = ''; - } - - componentWillUnmount() { - clearTimeout(this.timeoutId); - } - handlePretextChanged(suggestionId, channelPrefix) { if (channelPrefix) { const allChannels = ChannelStore.getAll(); const channels = []; - function autocomplete() { - autocompleteUsers( - channelPrefix, - (users) => { - const currentId = UserStore.getCurrentId(); + autocompleteUsers( + channelPrefix, + (users) => { + const currentId = UserStore.getCurrentId(); - for (const id of Object.keys(allChannels)) { - const channel = allChannels[id]; - if (channel.display_name.toLowerCase().indexOf(channelPrefix.toLowerCase()) !== -1) { - channels.push(channel); - } + for (const id of Object.keys(allChannels)) { + const channel = allChannels[id]; + if (channel.display_name.toLowerCase().indexOf(channelPrefix.toLowerCase()) !== -1) { + channels.push(channel); } + } - const userMap = {}; - for (let i = 0; i < users.length; i++) { - const user = users[i]; - let displayName = `@${user.username} `; + const userMap = {}; + for (let i = 0; i < users.length; i++) { + const user = users[i]; + let displayName = `@${user.username} `; - if (user.id === currentId) { - continue; - } - - if ((user.first_name || user.last_name) && user.nickname) { - displayName += `- ${Utils.getFullName(user)} (${user.nickname})`; - } else if (user.nickname) { - displayName += `- (${user.nickname})`; - } else if (user.first_name || user.last_name) { - displayName += `- ${Utils.getFullName(user)}`; - } + if (user.id === currentId) { + continue; + } - const newChannel = { - display_name: displayName, - name: user.username, - id: user.id, - update_at: user.update_at, - type: Constants.DM_CHANNEL - }; - channels.push(newChannel); - userMap[user.id] = user; + if ((user.first_name || user.last_name) && user.nickname) { + displayName += `- ${Utils.getFullName(user)} (${user.nickname})`; + } else if (user.nickname) { + displayName += `- (${user.nickname})`; + } else if (user.first_name || user.last_name) { + displayName += `- ${Utils.getFullName(user)}`; } - channels.sort((a, b) => { - if (a.display_name === b.display_name) { - if (a.type !== Constants.DM_CHANNEL && b.type === Constants.DM_CHANNEL) { - return -1; - } else if (a.type === Constants.DM_CHANNEL && b.type !== Constants.DM_CHANNEL) { - return 1; - } - return a.name.localeCompare(b.name); - } - return a.display_name.localeCompare(b.display_name); - }); - - const channelNames = channels.map((channel) => channel.name); - - AppDispatcher.handleServerAction({ - type: ActionTypes.SUGGESTION_RECEIVED_SUGGESTIONS, - id: suggestionId, - matchedPretext: channelPrefix, - terms: channelNames, - items: channels, - component: SwitchChannelSuggestion - }); - - AppDispatcher.handleServerAction({ - type: ActionTypes.RECEIVED_PROFILES, - profiles: userMap - }); + const newChannel = { + display_name: displayName, + name: user.username, + id: user.id, + update_at: user.update_at, + type: Constants.DM_CHANNEL + }; + channels.push(newChannel); + userMap[user.id] = user; } - ); - } - this.timeoutId = setTimeout( - autocomplete.bind(this), - Constants.AUTOCOMPLETE_TIMEOUT + channels.sort((a, b) => { + if (a.display_name === b.display_name) { + if (a.type !== Constants.DM_CHANNEL && b.type === Constants.DM_CHANNEL) { + return -1; + } else if (a.type === Constants.DM_CHANNEL && b.type !== Constants.DM_CHANNEL) { + return 1; + } + return a.name.localeCompare(b.name); + } + return a.display_name.localeCompare(b.display_name); + }); + + const channelNames = channels.map((channel) => channel.name); + + AppDispatcher.handleServerAction({ + type: ActionTypes.SUGGESTION_RECEIVED_SUGGESTIONS, + id: suggestionId, + matchedPretext: channelPrefix, + terms: channelNames, + items: channels, + component: SwitchChannelSuggestion + }); + + AppDispatcher.handleServerAction({ + type: ActionTypes.RECEIVED_PROFILES, + profiles: userMap + }); + } ); } } -- cgit v1.2.3-1-g7c22