mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-31 14:27:57 +01:00 
			
		
		
		
	Use subscriptions in onCreate method in CataloguePresenter
This commit is contained in:
		| @@ -1,7 +1,6 @@ | ||||
| package eu.kanade.mangafeed.presenter; | ||||
|  | ||||
| import android.os.Bundle; | ||||
| import android.support.annotation.NonNull; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| @@ -14,11 +13,13 @@ import eu.kanade.mangafeed.data.helpers.SourceManager; | ||||
| import eu.kanade.mangafeed.data.models.Manga; | ||||
| import eu.kanade.mangafeed.sources.Source; | ||||
| import eu.kanade.mangafeed.ui.activity.CatalogueActivity; | ||||
| import eu.kanade.mangafeed.util.PageBundle; | ||||
| import eu.kanade.mangafeed.util.RxPager; | ||||
| import icepick.State; | ||||
| import nucleus.presenter.RxPresenter; | ||||
| import rx.Observable; | ||||
| import rx.Subscription; | ||||
| import rx.android.schedulers.AndroidSchedulers; | ||||
| import rx.internal.util.SubscriptionList; | ||||
| import rx.schedulers.Schedulers; | ||||
| import rx.subjects.PublishSubject; | ||||
| import timber.log.Timber; | ||||
| @@ -33,28 +34,34 @@ public class CataloguePresenter extends RxPresenter<CatalogueActivity> { | ||||
|     private String mSearchName; | ||||
|     private boolean mSearchMode; | ||||
|     private final int SEARCH_TIMEOUT = 1000; | ||||
|     private int mCurrentPage = 1; | ||||
|  | ||||
|     private Subscription mMangaFetchSubscription; | ||||
|     private Subscription mMangaSearchSubscription; | ||||
|     @State protected int mCurrentPage; | ||||
|     private RxPager pager; | ||||
|  | ||||
|     private Subscription mSearchViewSubscription; | ||||
|     private Subscription mMangaDetailFetchSubscription; | ||||
|     private PublishSubject<Observable<String>> mSearchViewPublishSubject; | ||||
|     private PublishSubject<Observable<List<Manga>>> mMangaDetailPublishSubject; | ||||
|     private SubscriptionList mResultSubscriptions = new SubscriptionList(); | ||||
|  | ||||
|     private final String CURRENT_PAGE = "CATALOGUE_CURRENT_PAGE"; | ||||
|     private static final int GET_MANGA_LIST = 1; | ||||
|  | ||||
|     @Override | ||||
|     protected void onCreate(Bundle savedState) { | ||||
|         super.onCreate(savedState); | ||||
|  | ||||
|         if (savedState != null) { | ||||
|             mCurrentPage = savedState.getInt(CURRENT_PAGE); | ||||
|         } | ||||
|         restartableReplay(GET_MANGA_LIST, | ||||
|                 () -> pager.pages().<PageBundle<List<Manga>>>concatMap( | ||||
|                         page -> getMangaObs(page + 1) | ||||
|                                 .map(mangas -> new PageBundle<>(page, mangas)) | ||||
|                                 .observeOn(AndroidSchedulers.mainThread()) | ||||
|                 ), | ||||
|                 (view, page) -> { | ||||
|                     view.hideProgressBar(); | ||||
|                     view.onAddPage(page); | ||||
|                     if (mMangaDetailPublishSubject != null) | ||||
|                         mMangaDetailPublishSubject.onNext(Observable.just(page.data)); | ||||
|                 }); | ||||
|  | ||||
|         selectedSource = sourceManager.getSelectedSource(); | ||||
|         getMangasFromSource(mCurrentPage); | ||||
|         initializeSearch(); | ||||
|         initializeMangaDetailsLoader(); | ||||
|     } | ||||
| @@ -63,24 +70,40 @@ public class CataloguePresenter extends RxPresenter<CatalogueActivity> { | ||||
|     protected void onTakeView(CatalogueActivity view) { | ||||
|         super.onTakeView(view); | ||||
|  | ||||
|         view.setScrollPage(mCurrentPage - 1); | ||||
|  | ||||
|         view.setToolbarTitle(selectedSource.getName()); | ||||
|  | ||||
|         if (view.getAdapter().getCount() == 0) | ||||
|             view.showProgressBar(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected void onSave(@NonNull Bundle state) { | ||||
|         super.onSave(state); | ||||
|         state.putInt(CURRENT_PAGE, mCurrentPage); | ||||
|     public void requestNext() { | ||||
|         pager.requestNext(++mCurrentPage); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected void onDestroy() { | ||||
|         super.onDestroy(); | ||||
|         mResultSubscriptions.unsubscribe(); | ||||
|     public void initializeRequest(int source_id) { | ||||
|         this.selectedSource = sourceManager.get(source_id); | ||||
|         restartRequest(); | ||||
|     } | ||||
|  | ||||
|     private void restartRequest() { | ||||
|         stop(GET_MANGA_LIST); | ||||
|         mCurrentPage = 1; | ||||
|         pager = new RxPager(); | ||||
|         start(GET_MANGA_LIST); | ||||
|     } | ||||
|  | ||||
|     private Observable<List<Manga>> getMangaObs(int page) { | ||||
|         Observable<List<Manga>> obs; | ||||
|         if (mSearchMode) | ||||
|             obs = selectedSource.searchMangasFromNetwork(mSearchName, page); | ||||
|         else | ||||
|             obs = selectedSource.pullPopularMangasFromNetwork(page); | ||||
|  | ||||
|         return obs.subscribeOn(Schedulers.io()) | ||||
|                 .flatMap(Observable::from) | ||||
|                 .map(this::networkToLocalManga) | ||||
|                 .toList() | ||||
|                 .observeOn(AndroidSchedulers.mainThread()); | ||||
|     } | ||||
|  | ||||
|     private void initializeSearch() { | ||||
| @@ -134,36 +157,6 @@ public class CataloguePresenter extends RxPresenter<CatalogueActivity> { | ||||
|         add(mMangaDetailFetchSubscription); | ||||
|     } | ||||
|  | ||||
|     public void getMangasFromSource(int page) { | ||||
|         mMangaFetchSubscription = getMangasSubscriber( | ||||
|                 selectedSource.pullPopularMangasFromNetwork(page)); | ||||
|  | ||||
|         mResultSubscriptions.add(mMangaFetchSubscription); | ||||
|     } | ||||
|  | ||||
|     public void getMangasFromSearch(int page) { | ||||
|         mMangaSearchSubscription = getMangasSubscriber( | ||||
|                 selectedSource.searchMangasFromNetwork(mSearchName, page)); | ||||
|  | ||||
|         mResultSubscriptions.add(mMangaSearchSubscription); | ||||
|     } | ||||
|  | ||||
|     private Subscription getMangasSubscriber(Observable<List<Manga>> mangas) { | ||||
|         return mangas | ||||
|                 .subscribeOn(Schedulers.io()) | ||||
|                 .flatMap(Observable::from) | ||||
|                 .map(this::networkToLocalManga) | ||||
|                 .toList() | ||||
|                 .observeOn(AndroidSchedulers.mainThread()) | ||||
|                 .compose(deliverReplay()) | ||||
|                 .subscribe(this.split((view, newMangas) -> { | ||||
|                     view.hideProgressBar(); | ||||
|                     view.onMangasNext(newMangas); | ||||
|                     if (mMangaDetailPublishSubject != null) | ||||
|                         mMangaDetailPublishSubject.onNext(Observable.just(newMangas)); | ||||
|                 })); | ||||
|     } | ||||
|  | ||||
|     private Manga networkToLocalManga(Manga networkManga) { | ||||
|         Manga localManga = db.getMangaBlock(networkManga.url); | ||||
|         if (localManga == null) { | ||||
| @@ -186,31 +179,20 @@ public class CataloguePresenter extends RxPresenter<CatalogueActivity> { | ||||
|         // If going to search mode | ||||
|         else if (mSearchName.equals("") && !query.equals("")) { | ||||
|             mSearchMode = true; | ||||
|             mResultSubscriptions.clear(); | ||||
|         } | ||||
|         // If going to normal mode | ||||
|         else if (!mSearchName.equals("") && query.equals("")) { | ||||
|             mSearchMode = false; | ||||
|             mResultSubscriptions.clear(); | ||||
|         } | ||||
|  | ||||
|         mSearchName = query; | ||||
|         getView().getAdapter().getItems().clear(); | ||||
|         getView().showProgressBar(); | ||||
|         getView().resetScrollListener(); | ||||
|         loadMoreMangas(1); | ||||
|     } | ||||
|  | ||||
|     public void loadMoreMangas(int page) { | ||||
|         if (page > 1) { | ||||
|             getView().showGridProgressBar(); | ||||
|         if (getView() != null) { | ||||
|             if (mCurrentPage == 1) | ||||
|                 getView().showProgressBar(); | ||||
|             else | ||||
|                 getView().showGridProgressBar(); | ||||
|         } | ||||
|         if (mSearchMode) { | ||||
|             getMangasFromSearch(page); | ||||
|         } else { | ||||
|             getMangasFromSource(page); | ||||
|         } | ||||
|         mCurrentPage = page; | ||||
|         restartRequest(); | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -13,6 +13,7 @@ import android.widget.ProgressBar; | ||||
|  | ||||
| import com.bumptech.glide.Glide; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
|  | ||||
| import butterknife.Bind; | ||||
| @@ -22,6 +23,7 @@ import eu.kanade.mangafeed.R; | ||||
| import eu.kanade.mangafeed.data.models.Manga; | ||||
| import eu.kanade.mangafeed.presenter.CataloguePresenter; | ||||
| import eu.kanade.mangafeed.ui.adapter.CatalogueHolder; | ||||
| import eu.kanade.mangafeed.util.PageBundle; | ||||
| import eu.kanade.mangafeed.widget.EndlessScrollListener; | ||||
| import nucleus.factory.RequiresPresenter; | ||||
| import uk.co.ribot.easyadapter.EasyAdapter; | ||||
| @@ -62,6 +64,11 @@ public class CatalogueActivity extends BaseActivity<CataloguePresenter> { | ||||
|  | ||||
|         initializeAdapter(); | ||||
|         initializeScrollListener(); | ||||
|  | ||||
|         int source_id = getIntent().getIntExtra(SOURCE_ID, -1); | ||||
|  | ||||
|         if (savedInstanceState == null) | ||||
|             getPresenter().initializeRequest(source_id); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @@ -107,14 +114,7 @@ public class CatalogueActivity extends BaseActivity<CataloguePresenter> { | ||||
|     } | ||||
|  | ||||
|     public void initializeScrollListener() { | ||||
|         scroll_listener = new EndlessScrollListener() { | ||||
|             @Override | ||||
|             public boolean onLoadMore(int page, int totalItemsCount) { | ||||
|                 getPresenter().loadMoreMangas(page); | ||||
|                 return true; | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         scroll_listener = new EndlessScrollListener(getPresenter()::requestNext); | ||||
|         manga_list.setOnScrollListener(scroll_listener); | ||||
|     } | ||||
|  | ||||
| @@ -122,14 +122,6 @@ public class CatalogueActivity extends BaseActivity<CataloguePresenter> { | ||||
|         scroll_listener.resetScroll(); | ||||
|     } | ||||
|  | ||||
|     public int getScrollPage() { | ||||
|         return scroll_listener.getCurrentPage(); | ||||
|     } | ||||
|  | ||||
|     public void setScrollPage(int page) { | ||||
|         scroll_listener.setCurrentPage(page); | ||||
|     } | ||||
|  | ||||
|     public void showProgressBar() { | ||||
|         progress.setVisibility(ProgressBar.VISIBLE); | ||||
|     } | ||||
| @@ -143,8 +135,12 @@ public class CatalogueActivity extends BaseActivity<CataloguePresenter> { | ||||
|         progress_grid.setVisibility(ProgressBar.GONE); | ||||
|     } | ||||
|  | ||||
|     public void onMangasNext(List<Manga> newMangas) { | ||||
|         adapter.addItems(newMangas); | ||||
|     public void onAddPage(PageBundle<List<Manga>> page) { | ||||
|         if (page.page == 0) { | ||||
|             adapter.setItems(new ArrayList<>()); | ||||
|             resetScrollListener(); | ||||
|         } | ||||
|         adapter.addItems(page.data); | ||||
|     } | ||||
|  | ||||
|     private int getMangaIndex(Manga manga) { | ||||
| @@ -175,4 +171,5 @@ public class CatalogueActivity extends BaseActivity<CataloguePresenter> { | ||||
|                     .into(imageView); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -10,6 +10,7 @@ import android.support.v4.app.FragmentManager; | ||||
| import android.support.v4.app.FragmentPagerAdapter; | ||||
| import android.support.v4.view.ViewPager; | ||||
| import android.support.v7.widget.Toolbar; | ||||
| import android.view.MenuItem; | ||||
|  | ||||
| import butterknife.Bind; | ||||
| import butterknife.ButterKnife; | ||||
| @@ -57,6 +58,16 @@ public class MangaDetailActivity extends BaseActivity<MangaDetailPresenter> { | ||||
|         setupViewPager(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean onOptionsItemSelected(MenuItem item) { | ||||
|         switch (item.getItemId()) { | ||||
|             case android.R.id.home: | ||||
|                 finish(); | ||||
|                 return true; | ||||
|         } | ||||
|         return super.onOptionsItemSelected(item); | ||||
|     } | ||||
|  | ||||
|     private void disableToolbarElevation() { | ||||
|         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | ||||
|             toolbar.setElevation(0); | ||||
|   | ||||
							
								
								
									
										12
									
								
								app/src/main/java/eu/kanade/mangafeed/util/PageBundle.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								app/src/main/java/eu/kanade/mangafeed/util/PageBundle.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| package eu.kanade.mangafeed.util; | ||||
|  | ||||
| public class PageBundle<T> { | ||||
|  | ||||
|     public final int page; | ||||
|     public final T data; | ||||
|  | ||||
|     public PageBundle(int page, T data) { | ||||
|         this.page = page; | ||||
|         this.data = data; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										32
									
								
								app/src/main/java/eu/kanade/mangafeed/util/RxPager.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								app/src/main/java/eu/kanade/mangafeed/util/RxPager.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| package eu.kanade.mangafeed.util; | ||||
|  | ||||
| import rx.Observable; | ||||
| import rx.subjects.PublishSubject; | ||||
|  | ||||
| public class RxPager { | ||||
|  | ||||
|     private final int initialPageCount; | ||||
|     private final PublishSubject<Integer> requests = PublishSubject.create(); | ||||
|     private int requestedCount; | ||||
|  | ||||
|     public RxPager() { | ||||
|         this(1); | ||||
|     } | ||||
|  | ||||
|     public RxPager(int initialPageCount) { | ||||
|         this.initialPageCount = initialPageCount; | ||||
|     } | ||||
|  | ||||
|     public void requestNext(int page) { | ||||
|         requests.onNext(page); | ||||
|     } | ||||
|  | ||||
|     public Observable<Integer> pages() { | ||||
|         return requests | ||||
|             .concatMap(targetPage -> targetPage <= requestedCount ? | ||||
|                     Observable.<Integer>never() : | ||||
|                     Observable.range(requestedCount, targetPage - requestedCount)) | ||||
|             .startWith(Observable.range(0, initialPageCount)) | ||||
|             .doOnNext(it -> requestedCount = it + 1); | ||||
|     } | ||||
| } | ||||
| @@ -2,35 +2,25 @@ package eu.kanade.mangafeed.widget; | ||||
|  | ||||
| import android.widget.AbsListView; | ||||
|  | ||||
| public abstract class EndlessScrollListener implements AbsListView.OnScrollListener { | ||||
| import rx.functions.Action0; | ||||
|  | ||||
| public class EndlessScrollListener implements AbsListView.OnScrollListener { | ||||
|     // The minimum amount of items to have below your current scroll position | ||||
|     // before loading more. | ||||
|     private int visibleThreshold = 5; | ||||
|     // The current offset index of data you have loaded | ||||
|     private int currentPage = 0; | ||||
|     // The total number of items in the dataset after the last load | ||||
|     private int previousTotalItemCount = 0; | ||||
|     // True if we are still waiting for the last set of data to load. | ||||
|     private boolean loading = true; | ||||
|     // Sets the starting page index | ||||
|     private int startingPageIndex = 0; | ||||
|  | ||||
|     public EndlessScrollListener() { | ||||
|     } | ||||
|     private Action0 requestNext; | ||||
|  | ||||
|     public EndlessScrollListener(int visibleThreshold) { | ||||
|         this.visibleThreshold = visibleThreshold; | ||||
|     } | ||||
|  | ||||
|     public EndlessScrollListener(int visibleThreshold, int startPage) { | ||||
|         this.visibleThreshold = visibleThreshold; | ||||
|         this.startingPageIndex = startPage; | ||||
|         this.currentPage = startPage; | ||||
|     public EndlessScrollListener(Action0 requestNext) { | ||||
|         this.requestNext = requestNext; | ||||
|     } | ||||
|  | ||||
|     public void resetScroll() { | ||||
|         this.currentPage = 0; | ||||
|         this.startingPageIndex = 0; | ||||
|         this.previousTotalItemCount = 0; | ||||
|         this.loading = true; | ||||
|     } | ||||
|  | ||||
| @@ -43,7 +33,6 @@ public abstract class EndlessScrollListener implements AbsListView.OnScrollListe | ||||
|         // If the total item count is zero and the previous isn't, assume the | ||||
|         // list is invalidated and should be reset back to initial state | ||||
|         if (totalItemCount < previousTotalItemCount) { | ||||
|             this.currentPage = this.startingPageIndex; | ||||
|             this.previousTotalItemCount = totalItemCount; | ||||
|             if (totalItemCount == 0) { this.loading = true; } | ||||
|         } | ||||
| @@ -53,31 +42,20 @@ public abstract class EndlessScrollListener implements AbsListView.OnScrollListe | ||||
|         if (loading && (totalItemCount > previousTotalItemCount)) { | ||||
|             loading = false; | ||||
|             previousTotalItemCount = totalItemCount; | ||||
|             currentPage++; | ||||
|         } | ||||
|  | ||||
|         // If it isn’t currently loading, we check to see if we have breached | ||||
|         // the visibleThreshold and need to reload more data. | ||||
|         // If we do need to reload some more data, we execute onLoadMore to fetch the data. | ||||
|         if (!loading && (totalItemCount - visibleItemCount)<=(firstVisibleItem + visibleThreshold)) { | ||||
|             loading = onLoadMore(currentPage + 1, totalItemCount); | ||||
|             requestNext.call(); | ||||
|             loading = true; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Defines the process for actually loading more data based on page | ||||
|     // Returns true if more data is being loaded; returns false if there is no more data to load. | ||||
|     public abstract boolean onLoadMore(int page, int totalItemsCount); | ||||
|  | ||||
|     @Override | ||||
|     public void onScrollStateChanged(AbsListView view, int scrollState) { | ||||
|         // Don't take any action on changed | ||||
|     } | ||||
|  | ||||
|     public int getCurrentPage() { | ||||
|         return currentPage; | ||||
|     } | ||||
|  | ||||
|     public void setCurrentPage(int currentPage) { | ||||
|         this.currentPage = currentPage; | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user