Fix force tab complete not working since switching to React 18 createRoot API (#28505)

`setState` now has different timings so we cannot assume the state changes are available immediately and must await them

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
Michael Telatynski 2024-11-20 18:52:10 +00:00 committed by GitHub
parent 95630f525f
commit 72989ea646
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -10,6 +10,7 @@ import React, { createRef, KeyboardEvent, RefObject } from "react";
import classNames from "classnames"; import classNames from "classnames";
import { flatMap } from "lodash"; import { flatMap } from "lodash";
import { Room } from "matrix-js-sdk/src/matrix"; import { Room } from "matrix-js-sdk/src/matrix";
import { defer } from "matrix-js-sdk/src/utils";
import Autocompleter, { ICompletion, ISelectionRange, IProviderCompletions } from "../../../autocomplete/Autocompleter"; import Autocompleter, { ICompletion, ISelectionRange, IProviderCompletions } from "../../../autocomplete/Autocompleter";
import SettingsStore from "../../../settings/SettingsStore"; import SettingsStore from "../../../settings/SettingsStore";
@ -127,18 +128,21 @@ export default class Autocomplete extends React.PureComponent<IProps, IState> {
} }
private async processQuery(query: string, selection: ISelectionRange): Promise<void> { private async processQuery(query: string, selection: ISelectionRange): Promise<void> {
return this.autocompleter if (!this.autocompleter) return;
?.getCompletions(query, selection, this.state.forceComplete, MAX_PROVIDER_MATCHES) const completions = await this.autocompleter.getCompletions(
.then((completions) => { query,
// Only ever process the completions for the most recent query being processed selection,
if (query !== this.queryRequested) { this.state.forceComplete,
return; MAX_PROVIDER_MATCHES,
} );
this.processCompletions(completions); // Only ever process the completions for the most recent query being processed
}); if (query !== this.queryRequested) {
return;
}
await this.processCompletions(completions);
} }
private processCompletions(completions: IProviderCompletions[]): void { private async processCompletions(completions: IProviderCompletions[]): Promise<void> {
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.
@ -169,14 +173,19 @@ export default class Autocomplete extends React.PureComponent<IProps, IState> {
} }
} }
this.setState({ const deferred = defer<void>();
completions, this.setState(
completionList, {
selectionOffset, completions,
hide, completionList,
// Force complete is turned off each time since we can't edit the query in that case selectionOffset,
forceComplete: false, hide,
}); // Force complete is turned off each time since we can't edit the query in that case
forceComplete: false,
},
deferred.resolve,
);
await deferred.promise;
} }
public hasSelection(): boolean { public hasSelection(): boolean {