MOBILE-3675 infinite-loader: Improve calculations

main
Noel De Martin 2021-02-10 10:43:29 +01:00
parent 6d5901ee28
commit 1786f908b9
1 changed files with 23 additions and 20 deletions

View File

@ -12,9 +12,12 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { Component, Input, Output, EventEmitter, OnChanges, SimpleChange, Optional, ViewChild, ElementRef } from '@angular/core'; import { Component, Input, Output, EventEmitter, OnChanges, SimpleChange, ViewChild, ElementRef } from '@angular/core';
import { IonContent, IonInfiniteScroll } from '@ionic/angular'; import { IonContent, IonInfiniteScroll } from '@ionic/angular';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreUtils } from '@services/utils/utils';
const THRESHOLD = .15; // % of the scroll element height that must be close to the edge to consider loading more items necessary.
/** /**
* Component to show a infinite loading trigger and spinner while more data is being loaded. * Component to show a infinite loading trigger and spinner while more data is being loaded.
@ -41,12 +44,7 @@ export class CoreInfiniteLoadingComponent implements OnChanges {
loadingMore = false; // Hide button and avoid loading more. loadingMore = false; // Hide button and avoid loading more.
protected threshold = parseFloat('15%') / 100; constructor(protected element: ElementRef) {
constructor(
protected element: ElementRef,
@Optional() protected content: IonContent,
) {
this.action = new EventEmitter(); this.action = new EventEmitter();
} }
@ -70,26 +68,31 @@ export class CoreInfiniteLoadingComponent implements OnChanges {
* like the Ionic component does. * like the Ionic component does.
*/ */
protected async checkScrollDistance(): Promise<void> { protected async checkScrollDistance(): Promise<void> {
if (this.enabled) { if (!this.enabled) {
const scrollElement = await this.content.getScrollElement(); return;
}
const infiniteHeight = this.element.nativeElement.getBoundingClientRect().height; // Wait until next tick to allow items to render and scroll content to grow.
await CoreUtils.instance.nextTick();
const scrollTop = scrollElement.scrollTop; // Calculate distance from edge.
const height = scrollElement.offsetHeight; const content = this.element.nativeElement.closest('ion-content') as IonContent;
const threshold = height * this.threshold; const scrollElement = await content.getScrollElement();
const distanceFromInfinite = (this.position === 'bottom') const infiniteHeight = this.element.nativeElement.getBoundingClientRect().height;
? scrollElement.scrollHeight - infiniteHeight - scrollTop - threshold - height const scrollTop = scrollElement.scrollTop;
: scrollTop - infiniteHeight - threshold; const height = scrollElement.offsetHeight;
const threshold = height * THRESHOLD;
const distanceFromInfinite = (this.position === 'bottom')
? scrollElement.scrollHeight - infiniteHeight - scrollTop - threshold - height
: scrollTop - infiniteHeight - threshold;
if (distanceFromInfinite < 0 && !this.loadingMore && this.enabled) { // If it's close enough the edge, trigger the action to load more items.
this.loadMore(); if (distanceFromInfinite < 0 && !this.loadingMore && this.enabled) {
} this.loadMore();
} }
} }
/** /**
* Load More items calling the action provided. * Load More items calling the action provided.
*/ */