MOBILE-4304 core: Improve infinite-loader race conditions
parent
0c42071511
commit
7adf75f490
|
@ -69,17 +69,17 @@ export class CoreInfiniteLoadingComponent implements OnChanges {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait until next tick to allow items to render and scroll content to grow.
|
const scrollElement = await this.hostElement.closest('ion-content')?.getScrollElement();
|
||||||
await CoreUtils.nextTick();
|
|
||||||
|
|
||||||
// Calculate distance from edge.
|
if (!scrollElement) {
|
||||||
const content = this.hostElement.closest('ion-content');
|
|
||||||
if (!content) {
|
|
||||||
return;
|
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 infiniteHeight = this.hostElement.getBoundingClientRect().height;
|
||||||
const scrollTop = scrollElement.scrollTop;
|
const scrollTop = scrollElement.scrollTop;
|
||||||
const height = scrollElement.offsetHeight;
|
const height = scrollElement.offsetHeight;
|
||||||
|
|
|
@ -1826,23 +1826,29 @@ export class CoreUtilsProvider {
|
||||||
* @param condition Condition.
|
* @param condition Condition.
|
||||||
* @returns Cancellable promise.
|
* @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()) {
|
if (condition()) {
|
||||||
return CoreCancellablePromise.resolve();
|
return CoreCancellablePromise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const startTime = Date.now();
|
||||||
let intervalId: number | undefined;
|
let intervalId: number | undefined;
|
||||||
|
|
||||||
return new CoreCancellablePromise<void>(
|
return new CoreCancellablePromise<void>(
|
||||||
async (resolve) => {
|
async (resolve) => {
|
||||||
intervalId = window.setInterval(() => {
|
intervalId = window.setInterval(() => {
|
||||||
if (!condition()) {
|
if (!condition() && (!options.timeout || (Date.now() - startTime < options.timeout))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
resolve();
|
resolve();
|
||||||
window.clearInterval(intervalId);
|
window.clearInterval(intervalId);
|
||||||
}, interval);
|
}, options.interval ?? 50);
|
||||||
},
|
},
|
||||||
() => window.clearInterval(intervalId),
|
() => 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).
|
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.
|
* Possible default picker actions.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue