import { ReachBottomListener, ReachBottomListenerParams, ScrollableWindow, } from '../reach-bottom-listener'; import { CollectionState, FiltersMap, PartialLodash } from '@wix/bex-core'; export interface CollectionReachBottomParams< T, F extends FiltersMap = FiltersMap, > { collection: CollectionState; reachBottomParams?: Partial; lodash: PartialLodash; } export class CollectionReachBottom { collection: CollectionState; reachBottom: ReachBottomListener; constructor(params: CollectionReachBottomParams) { const { reachBottomParams, lodash } = params; this.collection = params.collection; this.reachBottom = new ReachBottomListener({ onReachBottom: this.collection.fetchNextPageIfNeeded, delay: 200, // this constance is a naive heuristic: amount of pixels covered in 250ms (avg server latency) when scrolling 1 pixel per millisecond (avg scrolling speed) offsetPX: 250, lodash, ...reachBottomParams, container: reachBottomParams?.container ?? new ScrollableWindow(), }); } triggerListenerIfReached = () => { return this.reachBottom.triggerListenerIfReached(); }; waitForScrollIdle = () => { const { reachBottom } = this; // if currently scrolling, return a promise for when the scrolling is idle if (!reachBottom.isScrolling) { return; } return new Promise((resolve) => { reachBottom.events.once('idle', resolve); }); }; subscribe() { const { reachBottom } = this; reachBottom.subscribe(); } unsubscribe() { const { reachBottom, collection } = this; collection.beforeSetData = undefined; reachBottom.unsubscribe(); } }