aretherecookies-mobile/js/streams/ProductsStream.js
2020-04-17 22:50:23 -05:00

81 lines
2.3 KiB
JavaScript

//@flow
import { BehaviorSubject } from 'rxjs';
import ProductRecord, { createProduct } from '../records/ProductRecord';
import { setById } from '../helpers/ImmutableHelpers';
import { Map, set, getIn } from 'immutable';
import location$ from './LocationStream';
import { getProducts, type ProductsForLocation } from '../apis/ProductsApi';
import Filter$ from './FilterStream';
import Quantity$ from './QuantityStream';
import type { QuantityFragment } from '../constants/QuantityConstants';
// import { type ImageFragment } from '../records/ImageRecord';
// import Image$ from './ImagesStream';
import places$ from './PlacesStream';
const productSubject: BehaviorSubject<ProductRecord> = new BehaviorSubject();
export function emitter(val?: ?ProductRecord) {
productSubject.next(val);
}
emitter(null);
const manualUpdate$ = productSubject.scan(
(productMap: Map<string, ProductRecord>, product: ProductRecord) => {
return product ? productMap.set(product.id, product) : productMap;
},
Map()
);
const fetchedProducts$ = Filter$.combineLatest(location$)
.debounceTime(200)
.mergeMap(([filter, loc]) => {
if (!loc) {
return Promise.resolve({});
}
return getProducts({ filter, loc });
})
.map(({ products }: ProductsForLocation) => {
if (products) {
return products.map(createProduct).reduce(setById, new Map());
}
return null;
});
export default fetchedProducts$
.combineLatest(manualUpdate$, (productMap: Map<string, ProductRecord>, manualUpdates) => {
if (productMap) {
return productMap.mergeDeep(manualUpdates);
}
})
.combineLatest(
Quantity$,
(
products: ?Map<string, ProductRecord>,
quantitiesFromStream: Map<string, QuantityFragment>
) => {
if (products) {
return products.mergeDeep(quantitiesFromStream);
}
}
)
.combineLatest(places$, (products, places) => {
if (!places || !products) {
return products;
}
const getPlaceIdForNearest = placeType => getIn(places, [placeType, 0, 'id'], '');
return products.map(product =>
set(product, 'placeId', getPlaceIdForNearest(product.placeType))
);
});
// )
// .combineLatest(
// Image$,
// (products: ?Map<string, ProductRecord>, latestFromImages$: Map<String, ImageFragment>) => {
// if (products) {
// return products.mergeDeep(latestFromImages$);
// }
// }
// );