From 931e712af165a64e0ab4f9813cca8f6213b89d7c Mon Sep 17 00:00:00 2001 From: Harrison Healey Date: Wed, 25 Jan 2017 21:16:18 -0500 Subject: Fixed ChannelMentionProvider matching completed mentions (#5188) --- .../suggestion/channel_mention_provider.jsx | 122 +++++++++++---------- webapp/components/suggestion/suggestion_box.jsx | 6 + 2 files changed, 72 insertions(+), 56 deletions(-) diff --git a/webapp/components/suggestion/channel_mention_provider.jsx b/webapp/components/suggestion/channel_mention_provider.jsx index 611f3de10..f1d6d9e76 100644 --- a/webapp/components/suggestion/channel_mention_provider.jsx +++ b/webapp/components/suggestion/channel_mention_provider.jsx @@ -51,73 +51,83 @@ class ChannelMentionSuggestion extends Suggestion { } export default class ChannelMentionProvider extends Provider { + constructor() { + super(); + + this.lastCompletedWord = ''; + } + handlePretextChanged(suggestionId, pretext) { - const captured = (/(^|\s)(~([^~]*))$/i).exec(pretext.toLowerCase()); - if (captured) { - const prefix = captured[3]; + const captured = (/(^|\s)(~([^~\r\n]*))$/i).exec(pretext.toLowerCase()); - if ((/\s/).test(prefix)) { - // If there's a space, there's a chance that we've already completed this mention - const firstWordOfPrefix = prefix.split(' ')[0]; + if (!captured) { + // Not a channel mention + return; + } - for (const channel of ChannelStore.getChannels()) { - if (firstWordOfPrefix === channel.name) { - // We've already mentioned this channel so there's nothing else to look for - return; - } - } - } + if (this.lastCompletedWord && captured[0].startsWith(this.lastCompletedWord)) { + // It appears we're still matching a channel handle that we already completed + return; + } - this.startNewRequest(prefix); + // Clear the last completed word since we've started to match new text + this.lastCompletedWord = ''; - autocompleteChannels( - prefix, - (data) => { - if (this.shouldCancelDispatch(prefix)) { - return; - } + const prefix = captured[3]; + + this.startNewRequest(prefix); - 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) => { + if (this.shouldCancelDispatch(prefix)) { + return; + } + + 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); + wrappedMoreChannels.push({ + type: Constants.MENTION_MORE_CHANNELS, + channel: item }); - const wrapped = wrappedChannels.concat(wrappedMoreChannels); - const mentions = wrapped.map((item) => '~' + item.channel.name); - - AppDispatcher.handleServerAction({ - type: ActionTypes.RECEIVED_MORE_CHANNELS, - channels: moreChannels - }); + 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 + }); + } + ); + } - AppDispatcher.handleServerAction({ - type: ActionTypes.SUGGESTION_RECEIVED_SUGGESTIONS, - id: suggestionId, - matchedPretext: captured[2], - terms: mentions, - items: wrapped, - component: ChannelMentionSuggestion - }); - } - ); - } + handleCompleteWord(term) { + this.lastCompletedWord = term; } } diff --git a/webapp/components/suggestion/suggestion_box.jsx b/webapp/components/suggestion/suggestion_box.jsx index e9f7c3699..29b9b2d8b 100644 --- a/webapp/components/suggestion/suggestion_box.jsx +++ b/webapp/components/suggestion/suggestion_box.jsx @@ -153,6 +153,12 @@ export default class SuggestionBox extends React.Component { window.requestAnimationFrame(() => { Utils.setCaretPosition(textbox, prefix.length + term.length + 1); }); + + for (const provider of this.props.providers) { + if (provider.handleCompleteWord) { + provider.handleCompleteWord(term, matchedPretext); + } + } } handleKeyDown(e) { -- cgit v1.2.3-1-g7c22