package ru.ltst.u2020mvp.data;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import ru.ltst.u2020mvp.ApplicationScope;
import ru.ltst.u2020mvp.data.api.GalleryService;
import ru.ltst.u2020mvp.data.api.Results;
import ru.ltst.u2020mvp.data.api.model.request.Section;
import ru.ltst.u2020mvp.data.api.model.request.Sort;
import ru.ltst.u2020mvp.data.api.model.response.Image;
import ru.ltst.u2020mvp.data.api.transforms.GalleryToImageList;
import ru.ltst.u2020mvp.data.rx.EndObserver;
import rx.Observable;
import rx.Observer;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
import rx.subjects.PublishSubject;
/**
* Poor-man's in-memory cache of responses. Must be accessed on the main thread.
*/
@ApplicationScope
public class GalleryDatabase {
private final GalleryService galleryService;
private final Map<Section, List<Image>> galleryCache = new LinkedHashMap<>();
private final Map<Section, PublishSubject<List<Image>>> galleryRequests = new LinkedHashMap<>();
@Inject
public GalleryDatabase(GalleryService galleryService) {
this.galleryService = galleryService;
}
// TODO pull underlying logic into a re-usable component for debouncing and caching last value.
public Subscription loadGallery(final Section section, Observer<List<Image>> observer) {
List<Image> images = galleryCache.get(section);
if (images != null) {
// We have a cached value. Emit it immediately.
observer.onNext(images);
}
PublishSubject<List<Image>> galleryRequest = galleryRequests.get(section);
if (galleryRequest != null) {
// There's an in-flight network request for this section already. Join it.
return galleryRequest.subscribe(observer);
}
galleryRequest = PublishSubject.create();
galleryRequests.put(section, galleryRequest);
Subscription subscription = galleryRequest.subscribe(observer);
galleryRequest.subscribe(new EndObserver<List<Image>>() {
@Override
public void onEnd() {
galleryRequests.remove(section);
}
@Override
public void onNext(List<Image> images) {
galleryCache.put(section, images);
}
});
galleryService.listGallery(section, Sort.VIRAL, 1)
.filter(Results.isSuccess())
.map(new GalleryToImageList())
.flatMap(Observable::from)
.filter(image -> {
return !image.is_album; // No albums.
})
.toList()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(galleryRequest);
return subscription;
}
}