mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-30 22:07:57 +01:00 
			
		
		
		
	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); | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -8,8 +8,6 @@ import android.view.View; | ||||
| import android.widget.GridView; | ||||
| import android.widget.ImageView; | ||||
|  | ||||
| import com.bumptech.glide.Glide; | ||||
|  | ||||
| import butterknife.Bind; | ||||
| import butterknife.ButterKnife; | ||||
| import eu.kanade.mangafeed.R; | ||||
| @@ -72,14 +70,19 @@ public class CatalogueListActivity extends BaseActivity implements CatalogueList | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     // CatalogueListView | ||||
|  | ||||
|     @Override | ||||
|     public void setSourceTitle(String title) { | ||||
|         setToolbarTitle(title); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void setAdapter(EasyAdapter adapter) { | ||||
|         manga_list.setAdapter(adapter); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void setScrollListener() { | ||||
|         scrollListener = new EndlessScrollListener() { | ||||
|             @Override | ||||
| @@ -92,23 +95,19 @@ public class CatalogueListActivity extends BaseActivity implements CatalogueList | ||||
|         manga_list.setOnScrollListener(scrollListener); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void resetScrollListener() { | ||||
|         scrollListener.resetScroll(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void updateImage(int position, String thumbnail) { | ||||
|     public ImageView getImageView(int position) { | ||||
|         View v = manga_list.getChildAt(position - | ||||
|                 manga_list.getFirstVisiblePosition()); | ||||
|  | ||||
|         if(v == null) | ||||
|             return; | ||||
|             return null; | ||||
|  | ||||
|         ImageView imageView = (ImageView) v.findViewById(R.id.catalogue_thumbnail); | ||||
|  | ||||
|         Glide.with(getActivity()) | ||||
|                 .load(thumbnail) | ||||
|                 .centerCrop() | ||||
|                 .into(imageView); | ||||
|         return (ImageView) v.findViewById(R.id.catalogue_thumbnail); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| package eu.kanade.mangafeed.view; | ||||
|  | ||||
| import android.content.Intent; | ||||
| import android.widget.ImageView; | ||||
|  | ||||
| import eu.kanade.mangafeed.sources.Source; | ||||
| import uk.co.ribot.easyadapter.EasyAdapter; | ||||
|  | ||||
| public interface CatalogueListView extends BaseView { | ||||
| @@ -11,5 +11,5 @@ public interface CatalogueListView extends BaseView { | ||||
|     void setAdapter(EasyAdapter adapter); | ||||
|     void setScrollListener(); | ||||
|     void resetScrollListener(); | ||||
|     void updateImage(int position, String thumbnail); | ||||
|     ImageView getImageView(int position); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user