diff --git a/src/components/loading/core-loading.html b/src/components/loading/core-loading.html index 22b9c6ef8..0e34fe572 100644 --- a/src/components/loading/core-loading.html +++ b/src/components/loading/core-loading.html @@ -4,7 +4,7 @@

{{message}}

-
+
\ No newline at end of file diff --git a/src/components/loading/loading.ts b/src/components/loading/loading.ts index 00831ac28..293ff885b 100644 --- a/src/components/loading/loading.ts +++ b/src/components/loading/loading.ts @@ -15,6 +15,8 @@ import { Component, Input, OnInit, OnChanges, SimpleChange, ViewChild, ElementRef } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; import { coreShowHideAnimation } from '@classes/animations'; +import { CoreEventsProvider } from '@providers/events'; +import { CoreUtilsProvider } from '@providers/utils/utils'; /** * Component to show a loading spinner and message while data is being loaded. @@ -45,10 +47,16 @@ export class CoreLoadingComponent implements OnInit, OnChanges { @Input() hideUntil: boolean; // Determine when should the contents be shown. @Input() message?: string; // Message to show while loading. @ViewChild('content') content: ElementRef; + + protected uniqueId: string; protected element: HTMLElement; // Current element. - constructor(private translate: TranslateService, element: ElementRef) { + constructor(private translate: TranslateService, element: ElementRef, private eventsProvider: CoreEventsProvider, + utils: CoreUtilsProvider) { this.element = element.nativeElement; + + // Calculate the unique ID. + this.uniqueId = 'core-loading-content-' + utils.getUniqueId('CoreLoadingComponent'); } /** @@ -62,14 +70,27 @@ export class CoreLoadingComponent implements OnInit, OnChanges { } ngOnChanges(changes: { [name: string]: SimpleChange }): void { - if (changes.hideUntil.currentValue === true) { - setTimeout(() => { - // Content is loaded so, center the spinner on the content itself. - this.element.classList.add('core-loading-loaded'); + if (changes.hideUntil) { + if (changes.hideUntil.currentValue === true) { setTimeout(() => { - // Change CSS to force calculate height. - this.content.nativeElement.classList.add('core-loading-content'); - }, 500); + // Content is loaded so, center the spinner on the content itself. + this.element.classList.add('core-loading-loaded'); + setTimeout(() => { + // Change CSS to force calculate height. + this.content.nativeElement.classList.add('core-loading-content'); + }, 500); + }); + } else { + this.element.classList.remove('core-loading-loaded'); + this.content.nativeElement.classList.remove('core-loading-content'); + } + + // Trigger the event after a timeout since the elements inside ngIf haven't been added to DOM yet. + setTimeout(() => { + this.eventsProvider.trigger(CoreEventsProvider.CORE_LOADING_CHANGED, { + loaded: changes.hideUntil.currentValue, + uniqueId: this.uniqueId + }); }); } } diff --git a/src/directives/format-text.ts b/src/directives/format-text.ts index 5d5bf1f36..b4bec6d50 100644 --- a/src/directives/format-text.ts +++ b/src/directives/format-text.ts @@ -16,6 +16,7 @@ import { Directive, ElementRef, Input, Output, EventEmitter, OnChanges, SimpleCh import { Platform, NavController, Content } from 'ionic-angular'; import { TranslateService } from '@ngx-translate/core'; import { CoreAppProvider } from '@providers/app'; +import { CoreEventsProvider } from '@providers/events'; import { CoreFilepoolProvider } from '@providers/filepool'; import { CoreLoggerProvider } from '@providers/logger'; import { CoreSitesProvider } from '@providers/sites'; @@ -58,6 +59,7 @@ export class CoreFormatTextDirective implements OnChanges { protected element: HTMLElement; protected showMoreDisplayed: boolean; + protected loadingChangedListener; constructor(element: ElementRef, private sitesProvider: CoreSitesProvider, private domUtils: CoreDomUtilsProvider, private textUtils: CoreTextUtilsProvider, private translate: TranslateService, private platform: Platform, @@ -65,7 +67,7 @@ export class CoreFormatTextDirective implements OnChanges { private filepoolProvider: CoreFilepoolProvider, private appProvider: CoreAppProvider, private contentLinksHelper: CoreContentLinksHelperProvider, @Optional() private navCtrl: NavController, @Optional() private content: Content, @Optional() private svComponent: CoreSplitViewComponent, - private iframeUtils: CoreIframeUtilsProvider) { + private iframeUtils: CoreIframeUtilsProvider, private eventsProvider: CoreEventsProvider) { this.element = element.nativeElement; this.element.classList.add('opacity-hide'); // Hide contents until they're treated. this.afterRender = new EventEmitter(); @@ -174,10 +176,16 @@ export class CoreFormatTextDirective implements OnChanges { * Calculate the height and check if we need to display show more or not. */ protected calculateHeight(): void { - // Height cannot be calculated if the element is not shown while calculating. - // Force shorten if it was previously shortened. // @todo: Work on calculate this height better. - const height = this.element.style.maxHeight ? 0 : this.getElementHeight(this.element); + + // Remove max-height (if any) to calculate the real height. + const initialMaxHeight = this.element.style.maxHeight; + this.element.style.maxHeight = null; + + const height = this.getElementHeight(this.element); + + // Restore the max height now. + this.element.style.maxHeight = initialMaxHeight; // If cannot calculate height, shorten always. if (!height || height > this.maxHeight) { @@ -290,6 +298,16 @@ export class CoreFormatTextDirective implements OnChanges { this.calculateHeight(); } }); + + if (!this.loadingChangedListener) { + // Recalculate the height if a parent core-loading displays the content. + this.loadingChangedListener = this.eventsProvider.on(CoreEventsProvider.CORE_LOADING_CHANGED, (data) => { + if (data.loaded && this.domUtils.closest(this.element.parentElement, '#' + data.uniqueId)) { + // The format-text is inside the loading, re-calculate the height. + this.calculateHeight(); + } + }); + } } else { this.domUtils.moveChildren(div, this.element); } diff --git a/src/providers/events.ts b/src/providers/events.ts index 7c4e27599..80764ed37 100644 --- a/src/providers/events.ts +++ b/src/providers/events.ts @@ -55,6 +55,7 @@ export class CoreEventsProvider { static APP_LAUNCHED_URL = 'app_launched_url'; // App opened with a certain URL (custom URL scheme). static FILE_SHARED = 'file_shared'; static KEYBOARD_CHANGE = 'keyboard_change'; + static CORE_LOADING_CHANGED = 'core_loading_changed'; protected logger; protected observables: { [s: string]: Subject } = {}; diff --git a/src/providers/utils/utils.ts b/src/providers/utils/utils.ts index 74e6819f2..ad37890cf 100644 --- a/src/providers/utils/utils.ts +++ b/src/providers/utils/utils.ts @@ -59,6 +59,7 @@ export interface PromiseDefer { export class CoreUtilsProvider { protected logger; protected iabInstance: InAppBrowserObject; + protected uniqueIds: {[name: string]: number} = {}; constructor(private iab: InAppBrowser, private appProvider: CoreAppProvider, private clipboard: Clipboard, private domUtils: CoreDomUtilsProvider, logger: CoreLoggerProvider, private translate: TranslateService, @@ -571,6 +572,20 @@ export class CoreUtilsProvider { }); } + /** + * Get a unique ID for a certain name. + * + * @param {string} name The name to get the ID for. + * @return {number} Unique ID. + */ + getUniqueId(name: string): number { + if (!this.uniqueIds[name]) { + this.uniqueIds[name] = 0; + } + + return ++this.uniqueIds[name]; + } + /** * Given a list of files, check if there are repeated names. *