Do debouncing for autocomplete in a sane way
- Fixes https://github.com/vector-im/riot-web/issues/4419 - Fixes https://github.com/matrix-org/matrix-react-sdk/pull/518#issuecomment-285901871 - Fixes https://github.com/matrix-org/matrix-react-sdk/pull/518#issuecomment-285910503 - Fixes bug where the setting being used was the `autocompleteDelay` "syncedSetting" when it should have been the "localSetting" (so the setting being used was always the default)
This commit is contained in:
parent
b3eee0c007
commit
de81188b13
1 changed files with 44 additions and 28 deletions
|
@ -40,25 +40,51 @@ export default class Autocomplete extends React.Component {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async componentWillReceiveProps(props, state) {
|
componentWillReceiveProps(newProps, state) {
|
||||||
if (props.query === this.props.query) {
|
// Query hasn't changed so don't try to complete it
|
||||||
return null;
|
if (newProps.query === this.props.query) {
|
||||||
}
|
|
||||||
|
|
||||||
return await this.complete(props.query, props.selection);
|
|
||||||
}
|
|
||||||
|
|
||||||
async complete(query, selection) {
|
|
||||||
let forceComplete = this.state.forceComplete;
|
|
||||||
const completionPromise = getCompletions(query, selection, forceComplete);
|
|
||||||
this.completionPromise = completionPromise;
|
|
||||||
const completions = await this.completionPromise;
|
|
||||||
|
|
||||||
// There's a newer completion request, so ignore results.
|
|
||||||
if (completionPromise !== this.completionPromise) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.complete(newProps.query, newProps.selection);
|
||||||
|
}
|
||||||
|
|
||||||
|
complete(query, selection) {
|
||||||
|
if (this.debounceCompletionsRequest) {
|
||||||
|
clearTimeout(this.debounceCompletionsRequest);
|
||||||
|
}
|
||||||
|
if (query === "") {
|
||||||
|
this.setState({
|
||||||
|
// Clear displayed completions
|
||||||
|
completions: [],
|
||||||
|
completionList: [],
|
||||||
|
// Reset selected completion
|
||||||
|
selectionOffset: COMPOSER_SELECTED,
|
||||||
|
// Hide the autocomplete box
|
||||||
|
hide: true,
|
||||||
|
});
|
||||||
|
return Q(null);
|
||||||
|
}
|
||||||
|
let autocompleteDelay = UserSettingsStore.getLocalSetting('autocompleteDelay', 200);
|
||||||
|
|
||||||
|
// Don't debounce if we are already showing completions
|
||||||
|
if (this.state.completions.length > 0) {
|
||||||
|
autocompleteDelay = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const deferred = Q.defer();
|
||||||
|
this.debounceCompletionsRequest = setTimeout(() => {
|
||||||
|
getCompletions(
|
||||||
|
query, selection, this.state.forceComplete,
|
||||||
|
).then((completions) => {
|
||||||
|
this.processCompletions(completions);
|
||||||
|
deferred.resolve();
|
||||||
|
});
|
||||||
|
}, autocompleteDelay);
|
||||||
|
return deferred.promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
processCompletions(completions) {
|
||||||
const completionList = flatMap(completions, (provider) => provider.completions);
|
const completionList = flatMap(completions, (provider) => provider.completions);
|
||||||
|
|
||||||
// Reset selection when completion list becomes empty.
|
// Reset selection when completion list becomes empty.
|
||||||
|
@ -88,23 +114,13 @@ export default class Autocomplete extends React.Component {
|
||||||
hide = false;
|
hide = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const autocompleteDelay = UserSettingsStore.getSyncedSetting('autocompleteDelay', 200);
|
|
||||||
|
|
||||||
// We had no completions before, but do now, so we should apply our display delay here
|
|
||||||
if (this.state.completionList.length === 0 && completionList.length > 0 &&
|
|
||||||
!forceComplete && autocompleteDelay > 0) {
|
|
||||||
await Q.delay(autocompleteDelay);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Force complete is turned off each time since we can't edit the query in that case
|
|
||||||
forceComplete = false;
|
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
completions,
|
completions,
|
||||||
completionList,
|
completionList,
|
||||||
selectionOffset,
|
selectionOffset,
|
||||||
hide,
|
hide,
|
||||||
forceComplete,
|
// Force complete is turned off each time since we can't edit the query in that case
|
||||||
|
forceComplete: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue