package com.progscrape.app.data;
import com.progscrape.app.rx.RefreshableRemoteData;
import com.progscrape.app.rx.RemoteStatus;
import javax.inject.Inject;
import rx.Scheduler;
import rx.functions.Action1;
import rx.subjects.AsyncSubject;
import rx.subjects.PublishSubject;
import rx.subjects.ReplaySubject;
public class Model {
private RestSource rest;
private Scheduler scheduler;
private RefreshableRemoteData<Feed> feed;
private RefreshableRemoteData<Tags> tags;
private RefreshableRemoteData<Stories> stories;
@Inject
public Model(RestSource rest, Scheduler scheduler) {
this.rest = rest;
this.scheduler = scheduler;
feed = getFeed(null);
tags = feed.map($ -> new Tags($.getTopTags()));
stories = feed.map($ -> new Stories($.getStories()));
}
private RefreshableRemoteData<Feed> getFeed(String tag) {
ReplaySubject<RemoteStatus> statusSubject = ReplaySubject.createWithSize(1);
ReplaySubject<Feed> feedSubject = ReplaySubject.createWithSize(1);
PublishSubject<Void> refresh = PublishSubject.create();
refresh.observeOn(scheduler).forEach($ -> {
CacheMode mode = CacheMode.DISABLE_CACHE;
fetch(tag, feedSubject, statusSubject, mode);
});
fetch(tag, feedSubject, statusSubject, CacheMode.ENABLE_CACHE);
return new RefreshableRemoteData<>(feedSubject, statusSubject, refresh);
}
private void fetch(String tag, ReplaySubject<Feed> feedSubject, ReplaySubject<RemoteStatus> statusSubject, CacheMode mode) {
statusSubject.onNext(RemoteStatus.LOADING);
Action1<Feed> action = (x) -> {
statusSubject.onNext(RemoteStatus.NOT_LOADING);
feedSubject.onNext(x);
};
if (tag == null) {
rest.defaultFeed(mode).subscribe(action);
} else {
rest.search(mode, tag).subscribe(action);
}
}
public RefreshableRemoteData<Tags> topTags() {
return tags;
}
public RefreshableRemoteData<Stories> stories() {
return stories;
}
public RefreshableRemoteData<Stories> search(String tag) {
return getFeed(tag).map($ -> new Stories($.getStories()));
}
private RefreshableRemoteData<Feed> defaultFeed() {
return feed;
}
}