Prechádzať zdrojové kódy

Use subscriptions in onCreate method in CataloguePresenter

inorichi 9 rokov pred
rodič
commit
264d627dea

+ 0 - 4
app/src/main/AndroidManifest.xml

@@ -27,15 +27,11 @@
             android:name=".ui.activity.MangaDetailActivity"
             android:label="@string/title_activity_manga_detail"
             android:parentActivityName=".ui.activity.MainActivity" >
-            <meta-data
-                android:name="android.support.PARENT_ACTIVITY"
-                android:value="eu.kanade.mangafeed.ui.activity.MainActivity" />
         </activity>
         <activity
             android:name=".ui.activity.CatalogueActivity"
             android:label="@string/title_activity_catalogue_list"
             android:parentActivityName=".ui.activity.MainActivity"
-            android:launchMode="singleTop"
             android:theme="@style/AppTheme" >
             <meta-data
                 android:name="android.support.PARENT_ACTIVITY"

+ 51 - 69
app/src/main/java/eu/kanade/mangafeed/presenter/CataloguePresenter.java

@@ -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 (mSearchMode) {
-            getMangasFromSearch(page);
-        } else {
-            getMangasFromSource(page);
+        if (getView() != null) {
+            if (mCurrentPage == 1)
+                getView().showProgressBar();
+            else
+                getView().showGridProgressBar();
         }
-        mCurrentPage = page;
+        restartRequest();
     }
 
 }

+ 15 - 18
app/src/main/java/eu/kanade/mangafeed/ui/activity/CatalogueActivity.java

@@ -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);
         }
     }
+
 }

+ 11 - 0
app/src/main/java/eu/kanade/mangafeed/ui/activity/MangaDetailActivity.java

@@ -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 - 0
app/src/main/java/eu/kanade/mangafeed/util/PageBundle.java

@@ -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 - 0
app/src/main/java/eu/kanade/mangafeed/util/RxPager.java

@@ -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);
+    }
+}

+ 9 - 31
app/src/main/java/eu/kanade/mangafeed/widget/EndlessScrollListener.java

@@ -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() {
-    }
 
-    public EndlessScrollListener(int visibleThreshold) {
-        this.visibleThreshold = visibleThreshold;
-    }
+    private Action0 requestNext;
 
-    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;
-    }
 }