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>
pull/28509/head
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
1 changed files with 27 additions and 18 deletions

View File

@ -10,6 +10,7 @@ import React, { createRef, KeyboardEvent, RefObject } from "react";
import classNames from "classnames";
import { flatMap } from "lodash";
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 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> {
return this.autocompleter
?.getCompletions(query, selection, this.state.forceComplete, MAX_PROVIDER_MATCHES)
.then((completions) => {
if (!this.autocompleter) return;
const completions = await this.autocompleter.getCompletions(
query,
selection,
this.state.forceComplete,
MAX_PROVIDER_MATCHES,
);
// Only ever process the completions for the most recent query being processed
if (query !== this.queryRequested) {
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);
// 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,
completionList,
selectionOffset,
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 {