import { Observable , of , fromEvent } from 'rxjs' ; import { map , mergeMap , tap , throttleTime , filter } from 'rxjs/operators' ; import * as Models from '../models' ; import { AxisResolver } from './axis-resolver' ; import { shouldTriggerEvents } from './event-trigger' ; import { resolveContainerElement } from './ngx-ins-utils' ; import { calculatePoints , createResolver } from './position-resolver' ; import * as ScrollResolver from './scroll-resolver' ; import { ScrollState } from './scroll-state' ; export function createScroller ( config ) { const { scrollContainer , scrollWindow , element , fromRoot } = config ; const resolver = createResolver ( { axis : new AxisResolver ( ! config . horizontal ) , windowElement : resolveContainerElement ( scrollContainer , scrollWindow , element , fromRoot ) } ) ; const scrollState = new ScrollState ( { totalToScroll : calculatePoints ( element , resolver ) } ) ; const options = { container : resolver . container , throttle : config . throttle } ; const distance = { up : config . upDistance , down : config . downDistance } ; return attachScrollEvent ( options ) . pipe ( mergeMap ( ( ) => of ( calculatePoints ( element , resolver ) ) ) , map ( ( positionStats ) => toInfiniteScrollParams ( scrollState . lastScrollPosition , positionStats , distance ) ) , tap ( ( { stats } ) => scrollState . updateScroll ( stats . scrolled , stats . totalToScroll ) ) , filter ( ( { fire , scrollDown , stats : { totalToScroll } } ) => shouldTriggerEvents ( config . alwaysCallback , fire , scrollState . isTriggeredScroll ( totalToScroll , scrollDown ) ) ) , tap ( ( { scrollDown , stats : { totalToScroll } } ) => { scrollState . updateTriggeredFlag ( totalToScroll , scrollDown ) ; } ) , map ( toInfiniteScrollAction ) ) ; } export function attachScrollEvent ( options ) { let obs = fromEvent ( options . container , 'scroll' ) ; if ( options . throttle ) { obs = obs . pipe ( throttleTime ( options . throttle ) ) ; } return obs ; } export function toInfiniteScrollParams ( lastScrollPosition , stats , distance ) { const { scrollDown , fire } = ScrollResolver . getScrollStats ( lastScrollPosition , stats , distance ) ; return { scrollDown , fire , stats } ; } export const InfiniteScrollActions = { DOWN : '[NGX_ISE] DOWN' , UP : '[NGX_ISE] UP' } ; export function toInfiniteScrollAction ( response ) { const { scrollDown , stats : { scrolled : currentScrollPosition } } = response ; return { type : scrollDown ? InfiniteScrollActions . DOWN : InfiniteScrollActions . UP , payload : { currentScrollPosition } } ; }