MOBILE-3833 collapsible: Do not calculate if not visible

main
Pau Ferrer Ocaña 2022-03-30 13:00:30 +02:00
parent 1ae5c6b3a7
commit a17886ad53
3 changed files with 70 additions and 7 deletions

View File

@ -50,6 +50,9 @@ export class CoreCollapsibleFooterDirective implements OnInit, OnDestroy {
protected endContentScrollListener?: EventListener; protected endContentScrollListener?: EventListener;
protected resizeListener?: CoreEventObserver; protected resizeListener?: CoreEventObserver;
protected slotPromise?: CoreCancellablePromise<void>; protected slotPromise?: CoreCancellablePromise<void>;
protected calcPending = false;
protected pageDidEnterListener?: EventListener;
protected page?: HTMLElement;
constructor(el: ElementRef, protected ionContent: IonContent) { constructor(el: ElementRef, protected ionContent: IonContent) {
this.element = el.nativeElement; this.element = el.nativeElement;
@ -82,6 +85,14 @@ export class CoreCollapsibleFooterDirective implements OnInit, OnDestroy {
* Calculate the height of the footer. * Calculate the height of the footer.
*/ */
protected async calculateHeight(): Promise<void> { protected async calculateHeight(): Promise<void> {
if (!CoreDom.isElementVisible(this.element)) {
this.calcPending = true;
return;
}
this.calcPending = false;
this.element.classList.remove('is-active'); this.element.classList.remove('is-active');
await CoreUtils.nextTick(); await CoreUtils.nextTick();
@ -159,6 +170,16 @@ export class CoreCollapsibleFooterDirective implements OnInit, OnDestroy {
this.resizeListener = CoreDom.onWindowResize(() => { this.resizeListener = CoreDom.onWindowResize(() => {
this.calculateHeight(); this.calculateHeight();
}, 50); }, 50);
this.page = this.content.closest<HTMLElement>('.ion-page') || undefined;
this.page?.addEventListener(
'ionViewDidEnter',
this.pageDidEnterListener = () => {
if (this.calcPending) {
this.calculateHeight();
}
},
);
} }
/** /**
@ -228,6 +249,9 @@ export class CoreCollapsibleFooterDirective implements OnInit, OnDestroy {
if (this.content && this.endContentScrollListener) { if (this.content && this.endContentScrollListener) {
this.content.removeEventListener('ionScrollEnd', this.endContentScrollListener); this.content.removeEventListener('ionScrollEnd', this.endContentScrollListener);
} }
if (this.page && this.pageDidEnterListener) {
this.page.removeEventListener('ionViewDidEnter', this.pageDidEnterListener);
}
this.resizeListener?.off(); this.resizeListener?.off();
this.slotPromise?.cancel(); this.slotPromise?.cancel();

View File

@ -77,6 +77,8 @@ export class CoreCollapsibleHeaderDirective implements OnInit, OnChanges, OnDest
protected isWithinContent = false; protected isWithinContent = false;
protected enteredPromise = new CorePromisedValue<void>(); protected enteredPromise = new CorePromisedValue<void>();
protected mutationObserver?: MutationObserver; protected mutationObserver?: MutationObserver;
protected firstEnter = true;
protected initPending = false;
constructor(el: ElementRef) { constructor(el: ElementRef) {
this.collapsedHeader = el.nativeElement; this.collapsedHeader = el.nativeElement;
@ -145,14 +147,19 @@ export class CoreCollapsibleHeaderDirective implements OnInit, OnChanges, OnDest
this.page.addEventListener( this.page.addEventListener(
'ionViewDidEnter', 'ionViewDidEnter',
this.pageDidEnterListener = () => { this.pageDidEnterListener = () => {
clearTimeout(timeout); if (this.firstEnter) {
this.enteredPromise.resolve(); this.firstEnter = false;
clearTimeout(timeout);
this.enteredPromise.resolve();
} else if (this.initPending) {
this.initializeFloatingTitle();
}
}, },
{ once: true },
); );
// Timeout in case event is never fired. // Timeout in case event is never fired.
const timeout = window.setTimeout(() => { const timeout = window.setTimeout(() => {
this.firstEnter = false;
this.enteredPromise.reject(new Error('[collapsible-header] Waiting for ionViewDidEnter timeout reached')); this.enteredPromise.reject(new Error('[collapsible-header] Waiting for ionViewDidEnter timeout reached'));
}, 5000); }, 5000);
@ -259,6 +266,14 @@ export class CoreCollapsibleHeaderDirective implements OnInit, OnChanges, OnDest
throw new Error('[collapsible-header] Couldn\'t create floating title'); throw new Error('[collapsible-header] Couldn\'t create floating title');
} }
if (!CoreDom.isElementVisible(this.expandedHeader)) {
this.initPending = true;
return;
}
this.initPending = false;
this.page.classList.remove('collapsible-header-page-is-active'); this.page.classList.remove('collapsible-header-page-is-active');
CoreUtils.nextTick(); CoreUtils.nextTick();

View File

@ -56,6 +56,9 @@ export class CoreCollapsibleItemDirective implements OnInit, OnDestroy {
protected darkModeListener?: Subscription; protected darkModeListener?: Subscription;
protected domPromise?: CoreCancellablePromise<void>; protected domPromise?: CoreCancellablePromise<void>;
protected uniqueId: string; protected uniqueId: string;
protected calcPending = false;
protected pageDidEnterListener?: EventListener;
protected page?: HTMLElement;
constructor(el: ElementRef<HTMLElement>) { constructor(el: ElementRef<HTMLElement>) {
this.element = el.nativeElement; this.element = el.nativeElement;
@ -93,6 +96,15 @@ export class CoreCollapsibleItemDirective implements OnInit, OnDestroy {
await this.calculateHeight(); await this.calculateHeight();
this.page?.addEventListener(
'ionViewDidEnter',
this.pageDidEnterListener = () => {
if (this.calcPending) {
this.calculateHeight();
}
},
);
this.resizeListener = CoreDom.onWindowResize(() => { this.resizeListener = CoreDom.onWindowResize(() => {
this.calculateHeight(); this.calculateHeight();
}, 50); }, 50);
@ -112,13 +124,12 @@ export class CoreCollapsibleItemDirective implements OnInit, OnDestroy {
await this.domPromise; await this.domPromise;
const page = this.element.closest('.ion-page'); this.page = this.element.closest<HTMLElement>('.ion-page') || undefined;
if (!this.page) {
if (!page) {
return; return;
} }
await CoreComponentsRegistry.waitComponentsReady(page, 'core-loading', CoreLoadingComponent); await CoreComponentsRegistry.waitComponentsReady(this.page, 'core-loading', CoreLoadingComponent);
} }
/** /**
@ -137,6 +148,15 @@ export class CoreCollapsibleItemDirective implements OnInit, OnDestroy {
await this.waitFormatTextsRendered(); await this.waitFormatTextsRendered();
if (!this.element.clientHeight) {
this.calcPending = true;
this.element.classList.remove('collapsible-loading-height');
return;
}
this.calcPending = false;
this.expandedHeight = this.element.getBoundingClientRect().height; this.expandedHeight = this.element.getBoundingClientRect().height;
// Restore the max height now. // Restore the max height now.
@ -278,6 +298,10 @@ export class CoreCollapsibleItemDirective implements OnInit, OnDestroy {
this.resizeListener?.off(); this.resizeListener?.off();
this.darkModeListener?.unsubscribe(); this.darkModeListener?.unsubscribe();
this.domPromise?.cancel(); this.domPromise?.cancel();
if (this.page && this.pageDidEnterListener) {
this.page.removeEventListener('ionViewDidEnter', this.pageDidEnterListener);
}
} }
} }