Merge pull request #3357 from NoelDeMartin/MOBILE-4069
MOBILE-4069 core: Fix race condition in loadingmain
commit
2407240134
|
@ -50,15 +50,15 @@ import { AsyncComponent } from '@classes/async-component';
|
||||||
})
|
})
|
||||||
export class CoreLoadingComponent implements OnInit, OnChanges, AfterViewInit, AsyncComponent {
|
export class CoreLoadingComponent implements OnInit, OnChanges, AfterViewInit, AsyncComponent {
|
||||||
|
|
||||||
@Input() hideUntil = false; // Determine when should the contents be shown.
|
@Input() hideUntil: unknown = false; // Determine when should the contents be shown.
|
||||||
@Input() message?: string; // Message to show while loading.
|
@Input() message?: string; // Message to show while loading.
|
||||||
@Input() fullscreen = true; // Use the whole screen.
|
@Input() fullscreen = true; // Use the whole screen.
|
||||||
|
|
||||||
uniqueId: string;
|
uniqueId: string;
|
||||||
loaded = false;
|
loaded = false;
|
||||||
|
|
||||||
protected scroll = 0;
|
|
||||||
protected element: HTMLElement; // Current element.
|
protected element: HTMLElement; // Current element.
|
||||||
|
protected lastScrollPosition = Promise.resolve<number | undefined>(undefined);
|
||||||
protected onReadyPromise = new CorePromisedValue<void>();
|
protected onReadyPromise = new CorePromisedValue<void>();
|
||||||
|
|
||||||
constructor(element: ElementRef) {
|
constructor(element: ElementRef) {
|
||||||
|
@ -85,7 +85,7 @@ export class CoreLoadingComponent implements OnInit, OnChanges, AfterViewInit, A
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
ngAfterViewInit(): void {
|
ngAfterViewInit(): void {
|
||||||
this.changeState(this.hideUntil);
|
this.changeState(!!this.hideUntil);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -93,7 +93,7 @@ export class CoreLoadingComponent implements OnInit, OnChanges, AfterViewInit, A
|
||||||
*/
|
*/
|
||||||
ngOnChanges(changes: { [name: string]: SimpleChange }): void {
|
ngOnChanges(changes: { [name: string]: SimpleChange }): void {
|
||||||
if (changes.hideUntil) {
|
if (changes.hideUntil) {
|
||||||
this.changeState(this.hideUntil);
|
this.changeState(!!this.hideUntil);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ export class CoreLoadingComponent implements OnInit, OnChanges, AfterViewInit, A
|
||||||
* @param loaded True to load, false otherwise.
|
* @param loaded True to load, false otherwise.
|
||||||
* @return Promise resolved when done.
|
* @return Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
async changeState(loaded: boolean): Promise<void> {
|
changeState(loaded: boolean): void {
|
||||||
this.element.classList.toggle('core-loading-loaded', loaded);
|
this.element.classList.toggle('core-loading-loaded', loaded);
|
||||||
this.element.setAttribute('aria-busy', loaded ? 'false' : 'true');
|
this.element.setAttribute('aria-busy', loaded ? 'false' : 'true');
|
||||||
|
|
||||||
|
@ -111,16 +111,13 @@ export class CoreLoadingComponent implements OnInit, OnChanges, AfterViewInit, A
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!loaded) {
|
|
||||||
await this.saveScrollPosition();
|
|
||||||
}
|
|
||||||
this.loaded = loaded;
|
this.loaded = loaded;
|
||||||
|
|
||||||
if (loaded) {
|
if (loaded) {
|
||||||
this.onReadyPromise.resolve();
|
this.onReadyPromise.resolve();
|
||||||
|
this.restoreScrollPosition();
|
||||||
// Recover last scroll.
|
} else {
|
||||||
await this.recoverScrollPosition();
|
this.lastScrollPosition = this.getScrollPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Event has been deprecated since app 4.0.
|
// Event has been deprecated since app 4.0.
|
||||||
|
@ -131,41 +128,36 @@ export class CoreLoadingComponent implements OnInit, OnChanges, AfterViewInit, A
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves current scroll position.
|
* Gets current scroll position.
|
||||||
*/
|
*/
|
||||||
protected async saveScrollPosition(): Promise<void> {
|
protected async getScrollPosition(): Promise<number | undefined> {
|
||||||
const content = this.element.closest('ion-content');
|
const content = this.element.closest('ion-content');
|
||||||
if (!content) {
|
const scrollElement = await content?.getScrollElement();
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const scrollElement = await content.getScrollElement();
|
return scrollElement?.scrollTop;
|
||||||
this.scroll = scrollElement.scrollTop;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recovers last set scroll position.
|
* Restores last known scroll position.
|
||||||
*/
|
*/
|
||||||
protected async recoverScrollPosition(): Promise<void> {
|
protected async restoreScrollPosition(): Promise<void> {
|
||||||
if (this.scroll <= 0) {
|
const scrollPosition = await this.lastScrollPosition;
|
||||||
|
|
||||||
|
if (scrollPosition === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const content = this.element.closest('ion-content');
|
const content = this.element.closest('ion-content');
|
||||||
if (!content) {
|
const scrollElement = await content?.getScrollElement();
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const scrollElement = await content.getScrollElement();
|
scrollElement?.scrollTo({ top: scrollPosition });
|
||||||
|
|
||||||
scrollElement.scrollTo(0, this.scroll);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
async ready(): Promise<void> {
|
async ready(): Promise<void> {
|
||||||
return await this.onReadyPromise;
|
await this.onReadyPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue