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,
selection,
this.state.forceComplete,
MAX_PROVIDER_MATCHES,
);
// Only ever process the completions for the most recent query being processed // Only ever process the completions for the most recent query being processed
if (query !== this.queryRequested) { if (query !== this.queryRequested) {
return; return;
} }
this.processCompletions(completions); 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>();
this.setState(
{
completions, completions,
completionList, completionList,
selectionOffset, selectionOffset,
hide, hide,
// Force complete is turned off each time since we can't edit the query in that case // Force complete is turned off each time since we can't edit the query in that case
forceComplete: false, forceComplete: false,
}); },
deferred.resolve,
);
await deferred.promise;
} }
public hasSelection(): boolean { public hasSelection(): boolean {