From 1819c743a6ce8100c404fe0958ed54d9797c0928 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Wed, 16 Mar 2022 11:56:25 +0100 Subject: [PATCH] MOBILE-3814 chore: Create a wait to be visible function --- src/core/directives/on-appear.ts | 8 +++---- src/core/services/utils/dom.ts | 37 +++++++++++++++++++++++++++++++- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/core/directives/on-appear.ts b/src/core/directives/on-appear.ts index 267fd3f9f..c894878dc 100644 --- a/src/core/directives/on-appear.ts +++ b/src/core/directives/on-appear.ts @@ -27,7 +27,7 @@ export class CoreOnAppearDirective implements OnInit, OnDestroy { @Output() onAppear = new EventEmitter(); private element: HTMLElement; - protected domPromise?: CoreCancellablePromise; + protected visiblePromise?: CoreCancellablePromise; constructor(element: ElementRef) { this.element = element.nativeElement; @@ -37,9 +37,9 @@ export class CoreOnAppearDirective implements OnInit, OnDestroy { * @inheritdoc */ async ngOnInit(): Promise { - this.domPromise = CoreDomUtils.waitToBeInDOM(this.element); + this.visiblePromise = CoreDomUtils.waitToBeVisible(this.element); - await this.domPromise; + await this.visiblePromise; this.onAppear.emit(); } @@ -48,7 +48,7 @@ export class CoreOnAppearDirective implements OnInit, OnDestroy { * @inheritdoc */ ngOnDestroy(): void { - this.domPromise?.cancel(); + this.visiblePromise?.cancel(); } } diff --git a/src/core/services/utils/dom.ts b/src/core/services/utils/dom.ts index 380064f49..0e8f1dfc1 100644 --- a/src/core/services/utils/dom.ts +++ b/src/core/services/utils/dom.ts @@ -100,7 +100,7 @@ export class CoreDomUtilsProvider { * @param timeout If defined, timeout to wait before rejecting the promise. * @return Cancellable promise. */ - waitToBeInDOM(element: Element, timeout?: number): CoreCancellablePromise { + waitToBeInDOM(element: HTMLElement, timeout?: number): CoreCancellablePromise { const root = element.getRootNode({ composed: true }); if (root === document) { @@ -140,6 +140,41 @@ export class CoreDomUtilsProvider { ); } + /** + * Wait an element to be in dom and visible. + * + * @param element Element to wait. + * @return Cancellable promise. + */ + waitToBeVisible(element: HTMLElement): CoreCancellablePromise { + const domPromise = CoreDomUtils.waitToBeInDOM(element); + + let interval: number | undefined; + + return new CoreCancellablePromise( + async (resolve) => { + await domPromise; + + if (CoreDomUtils.isElementVisible(element)) { + return resolve(); + } + + interval = window.setInterval(() => { + if (!CoreDomUtils.isElementVisible(element)) { + return; + } + + resolve(); + window.clearInterval(interval); + }, 50); + }, + () => { + domPromise.cancel(); + window.clearInterval(interval); + }, + ); + } + /** * Window resize is widely checked and may have many performance issues, debouce usage is needed to avoid calling it too much. * This function helps setting up the debounce feature and remove listener easily.