From 7a8f524f4a017862396b28865d757e6e9a79b4ec Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 7 Jul 2017 15:30:31 +0100 Subject: [PATCH] Remove two possible sources for the "AutoComplete stays visible bug which is now https://github.com/vector-im/riot-web/issues/4537 <- there. This does two things: - Track which query was the most recent one requesting completion and only process completions for that one. (In this case the empty string "" doesn't have any completions but we still track it so that previous calls with non-empty queries would not race and cause completions to be shown when we actuall don't want any.) - Make the "do we want to show the AutoComplete box?" logic a bit more sane --- src/components/views/rooms/Autocomplete.js | 29 +++++++++++-------- .../views/rooms/MessageComposerInput.js | 3 +- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/components/views/rooms/Autocomplete.js b/src/components/views/rooms/Autocomplete.js index 807e93cc0b..026be0da62 100644 --- a/src/components/views/rooms/Autocomplete.js +++ b/src/components/views/rooms/Autocomplete.js @@ -50,6 +50,7 @@ export default class Autocomplete extends React.Component { } complete(query, selection) { + this.queryRequested = query; if (this.debounceCompletionsRequest) { clearTimeout(this.debounceCompletionsRequest); } @@ -74,16 +75,25 @@ export default class Autocomplete extends React.Component { const deferred = Q.defer(); this.debounceCompletionsRequest = setTimeout(() => { - getCompletions( - query, selection, this.state.forceComplete, - ).then((completions) => { - this.processCompletions(completions); + this.processQuery(query, selection).then(() => { deferred.resolve(); }); }, autocompleteDelay); return deferred.promise; } + processQuery(query, selection) { + return getCompletions( + query, selection, this.state.forceComplete, + ).then((completions) => { + // Only ever process the completions for the most recent query being processed + if (query !== this.queryRequested) { + return; + } + this.processCompletions(completions); + }); + } + processCompletions(completions) { const completionList = flatMap(completions, (provider) => provider.completions); @@ -105,14 +115,9 @@ export default class Autocomplete extends React.Component { } let hide = this.state.hide; - // These are lists of booleans that indicate whether whether the corresponding provider had a matching pattern - const oldMatches = this.state.completions.map((completion) => !!completion.command.command), - newMatches = completions.map((completion) => !!completion.command.command); - - // So, essentially, we re-show autocomplete if any provider finds a new pattern or stops finding an old one - if (!isEqual(oldMatches, newMatches)) { - hide = false; - } + // If `completion.command.command` is truthy, then a provider has matched with the query + const anyMatches = completions.some((completion) => !!completion.command.command); + hide = !anyMatches; this.setState({ completions, diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index 3465b2ad14..488a8229a6 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -514,6 +514,7 @@ export default class MessageComposerInput extends React.Component { const currentBlockType = RichUtils.getCurrentBlockType(this.state.editorState); // If we're in any of these three types of blocks, shift enter should insert soft newlines // And just enter should end the block + // XXX: Empirically enter does not end these blocks if(['blockquote', 'unordered-list-item', 'ordered-list-item'].includes(currentBlockType)) { return false; } @@ -629,8 +630,6 @@ export default class MessageComposerInput extends React.Component { editorState: this.createEditorState(), }); - this.autocomplete.hide(); - return true; }