Browse Source

Use nucleus restartables in chapters presenter. Fix some database methods. Add swipe refresh to chapters fragment. Use Icepick library.

inorichi 10 năm trước cách đây
mục cha
commit
1719959bc8

+ 3 - 0
app/build.gradle

@@ -49,6 +49,7 @@ dependencies {
     final MOCKITO_VERSION = '1.10.19'
     final STORIO_VERSION = '1.4.0'
     final NUCLEUS_VERSION = '2.0.1'
+    final ICEPICK_VERSION = '3.1.0'
 
     compile fileTree(dir: 'libs', include: ['*.jar'])
 
@@ -75,6 +76,8 @@ dependencies {
     compile 'com.jakewharton.timber:timber:3.1.0'
     compile 'uk.co.ribot:easyadapter:1.5.0@aar'
     compile 'ch.acra:acra:4.6.2'
+    compile "frankiesardo:icepick:$ICEPICK_VERSION"
+    provided "frankiesardo:icepick-processor:$ICEPICK_VERSION"
 
     compile "com.google.dagger:dagger:$DAGGER_VERSION"
     apt "com.google.dagger:dagger-compiler:$DAGGER_VERSION"

+ 7 - 0
app/proguard-rules.pro

@@ -93,4 +93,11 @@
 
 -keep public class * extends android.support.v4.view.ActionProvider {
     public <init>(android.content.Context);
+}
+
+# Icepick
+-dontwarn icepick.**
+-keep class **$$Icepick { *; }
+-keepclasseswithmembernames class * {
+    @icepick.* <fields>;
 }

+ 2 - 1
app/src/main/java/eu/kanade/mangafeed/data/helpers/DatabaseHelper.java

@@ -7,6 +7,7 @@ import com.pushtorefresh.storio.sqlite.StorIOSQLite;
 import com.pushtorefresh.storio.sqlite.impl.DefaultStorIOSQLite;
 import com.pushtorefresh.storio.sqlite.operations.delete.DeleteResult;
 import com.pushtorefresh.storio.sqlite.operations.delete.DeleteResults;
+import com.pushtorefresh.storio.sqlite.operations.post.PostResult;
 import com.pushtorefresh.storio.sqlite.operations.put.PutResult;
 import com.pushtorefresh.storio.sqlite.operations.put.PutResults;
 
@@ -73,7 +74,7 @@ public class DatabaseHelper implements MangaManager, ChapterManager {
     }
 
     @Override
-    public Observable insertOrRemoveChapters(Manga manga, List<Chapter> chapters) {
+    public Observable<PostResult> insertOrRemoveChapters(Manga manga, List<Chapter> chapters) {
         return mChapterManager.insertOrRemoveChapters(manga, chapters);
     }
 

+ 2 - 1
app/src/main/java/eu/kanade/mangafeed/data/managers/ChapterManager.java

@@ -2,6 +2,7 @@ package eu.kanade.mangafeed.data.managers;
 
 import com.pushtorefresh.storio.sqlite.operations.delete.DeleteResult;
 import com.pushtorefresh.storio.sqlite.operations.delete.DeleteResults;
+import com.pushtorefresh.storio.sqlite.operations.post.PostResult;
 import com.pushtorefresh.storio.sqlite.operations.put.PutResult;
 import com.pushtorefresh.storio.sqlite.operations.put.PutResults;
 
@@ -21,7 +22,7 @@ public interface ChapterManager {
 
     Observable<PutResults<Chapter>> insertChapters(List<Chapter> chapters);
 
-    Observable insertOrRemoveChapters(Manga manga, List<Chapter> chapters);
+    Observable<PostResult> insertOrRemoveChapters(Manga manga, List<Chapter> chapters);
 
     Observable<DeleteResult> deleteChapter(Chapter chapter);
 

+ 4 - 0
app/src/main/java/eu/kanade/mangafeed/data/managers/ChapterManagerImpl.java

@@ -70,6 +70,10 @@ public class ChapterManagerImpl extends BaseManager implements ChapterManager {
     // Add new chapters or delete if the source deletes them
     @Override
     public Observable<PostResult> insertOrRemoveChapters(Manga manga, List<Chapter> chapters) {
+        for (Chapter chapter : chapters) {
+            chapter.manga_id = manga.id;
+        }
+
         Observable<List<Chapter>> chapterList = Observable.create(subscriber -> {
             subscriber.onNext(prepareGetChapters(manga).executeAsBlocking());
             subscriber.onCompleted();

+ 16 - 0
app/src/main/java/eu/kanade/mangafeed/presenter/BasePresenter.java

@@ -1,11 +1,27 @@
 package eu.kanade.mangafeed.presenter;
 
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+
 import de.greenrobot.event.EventBus;
+import icepick.Icepick;
 import nucleus.presenter.RxPresenter;
 import nucleus.view.ViewWithPresenter;
 
 public class BasePresenter<V extends ViewWithPresenter> extends RxPresenter<V> {
 
+    @Override
+    protected void onCreate(Bundle savedState) {
+        super.onCreate(savedState);
+        Icepick.restoreInstanceState(this, savedState);
+    }
+
+    @Override
+    protected void onSave(@NonNull Bundle state) {
+        super.onSave(state);
+        Icepick.saveInstanceState(this, state);
+    }
+
     public void registerForStickyEvents() {
         EventBus.getDefault().registerSticky(this);
     }

+ 44 - 35
app/src/main/java/eu/kanade/mangafeed/presenter/MangaChaptersPresenter.java

@@ -1,15 +1,22 @@
 package eu.kanade.mangafeed.presenter;
 
+import android.os.Bundle;
+
+import com.pushtorefresh.storio.sqlite.operations.post.PostResult;
+
+import java.util.List;
+
 import javax.inject.Inject;
 
 import eu.kanade.mangafeed.data.helpers.DatabaseHelper;
 import eu.kanade.mangafeed.data.helpers.SourceManager;
+import eu.kanade.mangafeed.data.models.Chapter;
 import eu.kanade.mangafeed.data.models.Manga;
-import eu.kanade.mangafeed.sources.Source;
 import eu.kanade.mangafeed.ui.fragment.MangaChaptersFragment;
-import rx.Subscription;
+import rx.Observable;
 import rx.android.schedulers.AndroidSchedulers;
 import rx.schedulers.Schedulers;
+import timber.log.Timber;
 
 public class MangaChaptersPresenter extends BasePresenter<MangaChaptersFragment> {
 
@@ -17,9 +24,24 @@ public class MangaChaptersPresenter extends BasePresenter<MangaChaptersFragment>
     @Inject SourceManager sourceManager;
 
     private Manga manga;
-    private Subscription chaptersSubscription;
-    private Subscription onlineChaptersSubscription;
-    private boolean doingRequest = false;
+
+    private static final int DB_CHAPTERS = 1;
+    private static final int ONLINE_CHAPTERS = 2;
+
+    @Override
+    protected void onCreate(Bundle savedState) {
+        super.onCreate(savedState);
+
+        restartableLatestCache(DB_CHAPTERS,
+                this::getDbChaptersObs,
+                MangaChaptersFragment::onNextChapters
+        );
+
+        restartableLatestCache(ONLINE_CHAPTERS,
+                this::getOnlineChaptersObs,
+                (view, result) -> view.onNextOnlineChapters()
+        );
+    }
 
     @Override
     protected void onTakeView(MangaChaptersFragment view) {
@@ -34,43 +56,30 @@ public class MangaChaptersPresenter extends BasePresenter<MangaChaptersFragment>
     }
 
     public void onEventMainThread(Manga manga) {
-        this.manga = manga;
-        getChapters();
+        if (this.manga == null) {
+            this.manga = manga;
+            start(DB_CHAPTERS);
+        }
     }
 
-    public void refreshChapters() {
-        if (manga != null && !doingRequest)
-            getChaptersFromSource(manga);
+    public void refreshChapters(MangaChaptersFragment view) {
+        if (manga != null) {
+            view.setSwipeRefreshing();
+            start(ONLINE_CHAPTERS);
+        }
     }
 
-    public void getChapters() {
-        if (chaptersSubscription != null)
-            return;
-
-        add(chaptersSubscription = db.getChapters(manga.id)
+    private Observable<List<Chapter>> getDbChaptersObs() {
+        return db.getChapters(manga.id)
                 .subscribeOn(Schedulers.io())
-                .observeOn(AndroidSchedulers.mainThread())
-                .compose(deliverLatestCache())
-                .subscribe(this.split(MangaChaptersFragment::onNextChapters)));
+                .observeOn(AndroidSchedulers.mainThread());
     }
 
-    public void getChaptersFromSource(Manga manga) {
-        if (onlineChaptersSubscription != null)
-            remove(onlineChaptersSubscription);
-
-        Source source = sourceManager.get(manga.source);
-        doingRequest = true;
-
-        onlineChaptersSubscription = source.pullChaptersFromNetwork(manga.url)
+    private Observable<PostResult> getOnlineChaptersObs() {
+        return sourceManager.get(manga.source)
+                .pullChaptersFromNetwork(manga.url)
                 .subscribeOn(Schedulers.io())
-                .observeOn(AndroidSchedulers.mainThread())
-                .compose(deliverLatestCache())
-                .subscribe(this.split((view, chapters) -> {
-                    doingRequest = false;
-                }), throwable -> {
-                    doingRequest = false;
-                });
-
-        add(onlineChaptersSubscription);
+                .flatMap(chapters -> db.insertOrRemoveChapters(manga, chapters))
+                .observeOn(AndroidSchedulers.mainThread());
     }
 }

+ 15 - 1
app/src/main/java/eu/kanade/mangafeed/ui/fragment/MangaChaptersFragment.java

@@ -2,6 +2,7 @@ package eu.kanade.mangafeed.ui.fragment;
 
 import android.os.Bundle;
 import android.support.v4.app.Fragment;
+import android.support.v4.widget.SwipeRefreshLayout;
 import android.support.v7.widget.LinearLayoutManager;
 import android.support.v7.widget.RecyclerView;
 import android.view.LayoutInflater;
@@ -26,6 +27,7 @@ import uk.co.ribot.easyadapter.EasyRecyclerAdapter;
 public class MangaChaptersFragment extends BaseFragment<MangaChaptersPresenter> {
 
     @Bind(R.id.chapter_list) RecyclerView chapters;
+    @Bind(R.id.swipe_refresh) SwipeRefreshLayout swipe_refresh;
 
     private EasyRecyclerAdapter<Chapter> adapter;
 
@@ -48,6 +50,7 @@ public class MangaChaptersFragment extends BaseFragment<MangaChaptersPresenter>
 
         chapters.setLayoutManager(new LinearLayoutManager(getActivity()));
         createAdapter();
+        setSwipeRefreshListener();
 
         return view;
     }
@@ -62,7 +65,7 @@ public class MangaChaptersFragment extends BaseFragment<MangaChaptersPresenter>
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
             case R.id.action_refresh:
-                getPresenter().refreshChapters();
+                getPresenter().refreshChapters(this);
                 break;
         }
         return super.onOptionsItemSelected(item);
@@ -73,8 +76,19 @@ public class MangaChaptersFragment extends BaseFragment<MangaChaptersPresenter>
         chapters.setAdapter(adapter);
     }
 
+    private void setSwipeRefreshListener() {
+        swipe_refresh.setOnRefreshListener(() -> getPresenter().refreshChapters(this));
+    }
+
     public void onNextChapters(List<Chapter> chapters) {
         adapter.setItems(chapters);
     }
 
+    public void onNextOnlineChapters() {
+        swipe_refresh.setRefreshing(false);
+    }
+
+    public void setSwipeRefreshing() {
+        swipe_refresh.setRefreshing(true);
+    }
 }

+ 11 - 4
app/src/main/res/layout/fragment_manga_chapters.xml

@@ -3,11 +3,18 @@
     android:orientation="vertical" android:layout_width="match_parent"
     android:layout_height="match_parent">
 
-    <android.support.v7.widget.RecyclerView
+    <android.support.v4.widget.SwipeRefreshLayout
+        android:id="@+id/swipe_refresh"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:id="@+id/chapter_list">
+        android:layout_height="match_parent">
 
-    </android.support.v7.widget.RecyclerView>
+        <android.support.v7.widget.RecyclerView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:id="@+id/chapter_list">
+
+        </android.support.v7.widget.RecyclerView>
+
+    </android.support.v4.widget.SwipeRefreshLayout>
 
 </LinearLayout>

+ 1 - 0
build.gradle

@@ -16,5 +16,6 @@ buildscript {
 allprojects {
     repositories {
         jcenter()
+        maven {url "https://clojars.org/repo/"}
     }
 }