in kahuna/public/js/components/gu-lazy-preview/gu-lazy-preview.js [20:99]
ctrl.init = function({items$, totalItems$, preloadedItems$, currentIndex$}) {
const itemsCount$ = items$.map(items => items.length).distinctUntilChanged();
const totalItemsCount$ = totalItems$.map(totalItems => {
return totalItems.length;
}).distinctUntilChanged();
const buttonCommands$ = Rx.Observable.create(observer => {
ctrl.prevItem = () => observer.onNext('prevItem');
ctrl.nextItem = () => observer.onNext('nextItem');
// Make sure we start at the beginning
observer.onNext('previewStart');
});
const itemsOffset$ = buttonCommands$.combineLatest(
itemsCount$,
(command, itemsCount) => {
return {command, itemsCount};
}).withLatestFrom(
currentIndex$,
({command}, currentIndex) => {
return {
prevItem: -1,
nextItem: +1,
previewStart: currentIndex * -1
}[command] || 0;
}
);
const updatedIndex$ = itemsOffset$.withLatestFrom(
currentIndex$, itemsCount$, totalItemsCount$,
(itemsOffset, currentIndex, itemsCount, totalItemsCount) => {
const updatedIndex = currentIndex + itemsOffset;
// Update the index if it's in the range of items
if (updatedIndex >= 0 && updatedIndex < totalItemsCount) {
return updatedIndex;
} else {
return currentIndex;
}
});
const item$ = updatedIndex$.withLatestFrom(
totalItemsCount$, items$,
(updatedIndex, totalItemsCount, items) => {
currentIndex$.onNext(updatedIndex);
return items[updatedIndex];
});
const currentPage$ = currentIndex$.withLatestFrom(
preloadedItems$,
(currentIndex, preloadedItems) => {
return Math.floor(currentIndex / preloadedItems);
});
const rangeToLoad$ = currentPage$.withLatestFrom(
preloadedItems$,
(currentPage, preloadedItems) => {
const start = currentPage * preloadedItems;
const end = ((currentPage + 1) * preloadedItems) - 1;
return {start, end};
}).
// Debounce range loading, which also helps discard
// erroneous large ranges while combining
// loadedRangeStart$ and loadedRangeEnd$ changes (one after the other)
debounce(10).
// Ignore if either end isn't set (whole range already loaded)
filter(({start, end}) => start !== -1 && end !== -1).
// Ignore if $start after $end (incomplete combine$ state)
filter(({start, end}) => start <= end).
distinctUntilChanged(({start, end}) => `${start}-${end}`);
return {
item$,
rangeToLoad$
};
};