MOBILE-4304 core: Improve infinite-loader race conditions

main
Noel De Martin 2024-02-07 14:25:52 +01:00
parent 0c42071511
commit 7adf75f490
2 changed files with 23 additions and 9 deletions

View File

@ -69,17 +69,17 @@ export class CoreInfiniteLoadingComponent implements OnChanges {
return;
}
// Wait until next tick to allow items to render and scroll content to grow.
await CoreUtils.nextTick();
const scrollElement = await this.hostElement.closest('ion-content')?.getScrollElement();
// Calculate distance from edge.
const content = this.hostElement.closest('ion-content');
if (!content) {
if (!scrollElement) {
return;
}
const scrollElement = await content.getScrollElement();
// Wait to allow items to render and scroll content to grow.
await CoreUtils.nextTick();
await CoreUtils.waitFor(() => scrollElement.scrollHeight > scrollElement.clientHeight, { timeout: 1000 });
// Calculate distance from edge.
const infiniteHeight = this.hostElement.getBoundingClientRect().height;
const scrollTop = scrollElement.scrollTop;
const height = scrollElement.offsetHeight;

View File

@ -1826,23 +1826,29 @@ export class CoreUtilsProvider {
* @param condition Condition.
* @returns Cancellable promise.
*/
waitFor(condition: () => boolean, interval: number = 50): CoreCancellablePromise<void> {
waitFor(condition: () => boolean): CoreCancellablePromise<void>;
waitFor(condition: () => boolean, options: CoreUtilsWaitOptions): CoreCancellablePromise<void>;
waitFor(condition: () => boolean, interval: number): CoreCancellablePromise<void>;
waitFor(condition: () => boolean, optionsOrInterval: CoreUtilsWaitOptions | number = {}): CoreCancellablePromise<void> {
const options = typeof optionsOrInterval === 'number' ? { interval: optionsOrInterval } : optionsOrInterval;
if (condition()) {
return CoreCancellablePromise.resolve();
}
const startTime = Date.now();
let intervalId: number | undefined;
return new CoreCancellablePromise<void>(
async (resolve) => {
intervalId = window.setInterval(() => {
if (!condition()) {
if (!condition() && (!options.timeout || (Date.now() - startTime < options.timeout))) {
return;
}
resolve();
window.clearInterval(intervalId);
}, interval);
}, options.interval ?? 50);
},
() => window.clearInterval(intervalId),
);
@ -1939,6 +1945,14 @@ export type CoreUtilsOpenInAppOptions = InAppBrowserOptions & {
originalUrl?: string; // Original URL to open (in case the URL was treated, e.g. to add a token or an auto-login).
};
/**
* Options for waiting.
*/
export type CoreUtilsWaitOptions = {
interval?: number;
timeout?: number;
};
/**
* Possible default picker actions.
*/