Use a publisher to get manga details. Refactor CatalogueListPresenter
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
package eu.kanade.mangafeed.presenter;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -41,6 +44,7 @@ public class CatalogueListPresenter extends BasePresenter {
|
||||
private Subscription mSearchViewSubscription;
|
||||
private Subscription mMangaDetailFetchSubscription;
|
||||
private PublishSubject<Observable<String>> mSearchViewPublishSubject;
|
||||
private PublishSubject<Observable<List<Manga>>> mMangaDetailPublishSubject;
|
||||
|
||||
|
||||
public CatalogueListPresenter(CatalogueListView view) {
|
||||
@@ -49,17 +53,79 @@ public class CatalogueListPresenter extends BasePresenter {
|
||||
}
|
||||
|
||||
public void initialize() {
|
||||
initializeSource();
|
||||
initializeAdapter();
|
||||
initializeSearch();
|
||||
initializeMangaDetailsLoader();
|
||||
|
||||
getMangasFromSource(1);
|
||||
}
|
||||
|
||||
private void initializeSource() {
|
||||
int sourceId = view.getIntent().getIntExtra(Intent.EXTRA_UID, -1);
|
||||
selectedSource = sourceManager.get(sourceId);
|
||||
view.setSourceTitle(selectedSource.getName());
|
||||
}
|
||||
|
||||
private void initializeAdapter() {
|
||||
adapter = new EasyAdapter<>(view.getActivity(), CatalogueListHolder.class);
|
||||
view.setAdapter(adapter);
|
||||
view.setScrollListener();
|
||||
}
|
||||
|
||||
initializeSearch();
|
||||
private void initializeSearch() {
|
||||
mSearchName = "";
|
||||
mSearchMode = false;
|
||||
mSearchViewPublishSubject = PublishSubject.create();
|
||||
|
||||
getMangasFromSource(1);
|
||||
mSearchViewSubscription = Observable.switchOnNext(mSearchViewPublishSubject)
|
||||
.debounce(SEARCH_TIMEOUT, TimeUnit.MILLISECONDS)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
this::queryFromSearch,
|
||||
error -> Timber.e(error.getCause(), error.getMessage()));
|
||||
|
||||
subscriptions.add(mSearchViewSubscription);
|
||||
}
|
||||
|
||||
private void initializeMangaDetailsLoader() {
|
||||
mMangaDetailPublishSubject = PublishSubject.create();
|
||||
|
||||
mMangaDetailFetchSubscription = Observable.switchOnNext(mMangaDetailPublishSubject)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.flatMap(Observable::from)
|
||||
.filter(manga -> !manga.initialized)
|
||||
.buffer(5)
|
||||
.concatMap(localMangas -> {
|
||||
List<Observable<Manga>> mangaObservables = new ArrayList<>();
|
||||
for (Manga manga : localMangas) {
|
||||
Observable<Manga> tempObs = selectedSource.pullMangaFromNetwork(manga.url)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.flatMap(networkManga -> {
|
||||
Manga.copyFromNetwork(manga, networkManga);
|
||||
db.insertMangaBlock(manga);
|
||||
return Observable.just(manga);
|
||||
});
|
||||
mangaObservables.add(tempObs);
|
||||
}
|
||||
return Observable.merge(mangaObservables);
|
||||
})
|
||||
.filter(manga -> manga.initialized)
|
||||
.onBackpressureBuffer()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(manga -> {
|
||||
// Get manga index in the adapter
|
||||
int index = getMangaIndex(manga);
|
||||
// Get the image view associated with the manga.
|
||||
// If it's null (not visible in the screen) there's no need to update the image.
|
||||
ImageView imageView = view.getImageView(index);
|
||||
if (imageView != null) {
|
||||
updateImage(imageView, manga.thumbnail_url);
|
||||
}
|
||||
});
|
||||
|
||||
subscriptions.add(mMangaDetailFetchSubscription);
|
||||
}
|
||||
|
||||
public void getMangasFromSource(int page) {
|
||||
@@ -73,7 +139,7 @@ public class CatalogueListPresenter extends BasePresenter {
|
||||
.toList()
|
||||
.subscribe(newMangas -> {
|
||||
adapter.addItems(newMangas);
|
||||
getMangaDetails(newMangas);
|
||||
mMangaDetailPublishSubject.onNext(Observable.just(newMangas));
|
||||
});
|
||||
|
||||
subscriptions.add(mMangaFetchSubscription);
|
||||
@@ -90,7 +156,7 @@ public class CatalogueListPresenter extends BasePresenter {
|
||||
.toList()
|
||||
.subscribe(newMangas -> {
|
||||
adapter.addItems(newMangas);
|
||||
getMangaDetails(newMangas);
|
||||
mMangaDetailPublishSubject.onNext(Observable.just(newMangas));
|
||||
});
|
||||
|
||||
subscriptions.add(mMangaSearchSubscription);
|
||||
@@ -105,61 +171,11 @@ public class CatalogueListPresenter extends BasePresenter {
|
||||
return localManga;
|
||||
}
|
||||
|
||||
private void getMangaDetails(List<Manga> mangas) {
|
||||
subscriptions.remove(mMangaDetailFetchSubscription);
|
||||
|
||||
mMangaDetailFetchSubscription = Observable.from(mangas)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.filter(manga -> !manga.initialized)
|
||||
.buffer(3)
|
||||
.concatMap(localMangas -> {
|
||||
List<Observable<Manga>> mangaObservables = new ArrayList<>();
|
||||
for (Manga manga : localMangas) {
|
||||
Observable<Manga> tempObs = selectedSource.pullMangaFromNetwork(manga.url)
|
||||
.flatMap(networkManga -> {
|
||||
Manga.copyFromNetwork(manga, networkManga);
|
||||
db.insertMangaBlock(manga);
|
||||
return Observable.just(manga);
|
||||
})
|
||||
.subscribeOn(Schedulers.io());
|
||||
mangaObservables.add(tempObs);
|
||||
}
|
||||
return Observable.merge(mangaObservables);
|
||||
})
|
||||
.filter(manga -> manga.initialized)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(manga -> {
|
||||
int i;
|
||||
for (i = 0; i < adapter.getCount(); i++) {
|
||||
if (manga.id == adapter.getItem(i).id) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
view.updateImage(i, manga.thumbnail_url);
|
||||
});
|
||||
|
||||
subscriptions.add(mMangaDetailFetchSubscription);
|
||||
}
|
||||
|
||||
public void onQueryTextChange(String query) {
|
||||
if (mSearchViewPublishSubject != null)
|
||||
mSearchViewPublishSubject.onNext(Observable.just(query));
|
||||
}
|
||||
|
||||
private void initializeSearch() {
|
||||
mSearchName = "";
|
||||
mSearchMode = false;
|
||||
mSearchViewPublishSubject = PublishSubject.create();
|
||||
mSearchViewSubscription = Observable.switchOnNext(mSearchViewPublishSubject)
|
||||
.debounce(SEARCH_TIMEOUT, TimeUnit.MILLISECONDS)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
this::queryFromSearch,
|
||||
error -> Timber.e(error.getCause(), error.getMessage()));
|
||||
|
||||
subscriptions.add(mSearchViewSubscription);
|
||||
}
|
||||
|
||||
private void queryFromSearch(String query) {
|
||||
// If search button clicked
|
||||
@@ -189,4 +205,21 @@ public class CatalogueListPresenter extends BasePresenter {
|
||||
}
|
||||
}
|
||||
|
||||
private int getMangaIndex(Manga manga) {
|
||||
int i;
|
||||
for (i = 0; i < adapter.getCount(); i++) {
|
||||
if (manga.id == adapter.getItem(i).id) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private void updateImage(ImageView imageView, String thumbnail) {
|
||||
Glide.with(view.getActivity())
|
||||
.load(thumbnail)
|
||||
.centerCrop()
|
||||
.into(imageView);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user