Skip to content

Commit

Permalink
Fix force tab complete not working since switching to React 18 create…
Browse files Browse the repository at this point in the history
…Root 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 <[email protected]>
  • Loading branch information
t3chguy authored Nov 20, 2024
1 parent 95630f5 commit 72989ea
Showing 1 changed file with 27 additions and 18 deletions.
45 changes: 27 additions & 18 deletions src/components/views/rooms/Autocomplete.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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) => {
// Only ever process the completions for the most recent query being processed
if (query !== this.queryRequested) {
return;
}
this.processCompletions(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;
}
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.
Expand Down Expand Up @@ -169,14 +173,19 @@ export default class Autocomplete extends React.PureComponent<IProps, IState> {
}
}

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,
});
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 {
Expand Down

0 comments on commit 72989ea

Please sign in to comment.