diff --git a/app/build.gradle b/app/build.gradle index 5c1df6df9..e2c257a60 100644 --- a/app/build.gradle +++ b/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" diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index a9c47c4ec..51ce99484 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -93,4 +93,11 @@ -keep public class * extends android.support.v4.view.ActionProvider { public (android.content.Context); +} + +# Icepick +-dontwarn icepick.** +-keep class **$$Icepick { *; } +-keepclasseswithmembernames class * { + @icepick.* ; } \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/mangafeed/data/helpers/DatabaseHelper.java b/app/src/main/java/eu/kanade/mangafeed/data/helpers/DatabaseHelper.java index 9c2eb8c28..2176a9e5e 100644 --- a/app/src/main/java/eu/kanade/mangafeed/data/helpers/DatabaseHelper.java +++ b/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 chapters) { + public Observable insertOrRemoveChapters(Manga manga, List chapters) { return mChapterManager.insertOrRemoveChapters(manga, chapters); } diff --git a/app/src/main/java/eu/kanade/mangafeed/data/managers/ChapterManager.java b/app/src/main/java/eu/kanade/mangafeed/data/managers/ChapterManager.java index 2c0f118c0..0fe7ea33c 100644 --- a/app/src/main/java/eu/kanade/mangafeed/data/managers/ChapterManager.java +++ b/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> insertChapters(List chapters); - Observable insertOrRemoveChapters(Manga manga, List chapters); + Observable insertOrRemoveChapters(Manga manga, List chapters); Observable deleteChapter(Chapter chapter); diff --git a/app/src/main/java/eu/kanade/mangafeed/data/managers/ChapterManagerImpl.java b/app/src/main/java/eu/kanade/mangafeed/data/managers/ChapterManagerImpl.java index e8ffffc4d..9118aa67b 100644 --- a/app/src/main/java/eu/kanade/mangafeed/data/managers/ChapterManagerImpl.java +++ b/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 insertOrRemoveChapters(Manga manga, List chapters) { + for (Chapter chapter : chapters) { + chapter.manga_id = manga.id; + } + Observable> chapterList = Observable.create(subscriber -> { subscriber.onNext(prepareGetChapters(manga).executeAsBlocking()); subscriber.onCompleted(); diff --git a/app/src/main/java/eu/kanade/mangafeed/presenter/BasePresenter.java b/app/src/main/java/eu/kanade/mangafeed/presenter/BasePresenter.java index 6cacb8dd8..144944b47 100644 --- a/app/src/main/java/eu/kanade/mangafeed/presenter/BasePresenter.java +++ b/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 extends RxPresenter { + @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); } diff --git a/app/src/main/java/eu/kanade/mangafeed/presenter/MangaChaptersPresenter.java b/app/src/main/java/eu/kanade/mangafeed/presenter/MangaChaptersPresenter.java index 35d865865..1b21ef79f 100644 --- a/app/src/main/java/eu/kanade/mangafeed/presenter/MangaChaptersPresenter.java +++ b/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 { @@ -17,9 +24,24 @@ public class MangaChaptersPresenter extends BasePresenter @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 } 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> 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 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()); } } diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/fragment/MangaChaptersFragment.java b/app/src/main/java/eu/kanade/mangafeed/ui/fragment/MangaChaptersFragment.java index a48cdeb11..ef97f10fb 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/fragment/MangaChaptersFragment.java +++ b/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 { @Bind(R.id.chapter_list) RecyclerView chapters; + @Bind(R.id.swipe_refresh) SwipeRefreshLayout swipe_refresh; private EasyRecyclerAdapter adapter; @@ -48,6 +50,7 @@ public class MangaChaptersFragment extends BaseFragment chapters.setLayoutManager(new LinearLayoutManager(getActivity())); createAdapter(); + setSwipeRefreshListener(); return view; } @@ -62,7 +65,7 @@ public class MangaChaptersFragment extends BaseFragment 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 chapters.setAdapter(adapter); } + private void setSwipeRefreshListener() { + swipe_refresh.setOnRefreshListener(() -> getPresenter().refreshChapters(this)); + } + public void onNextChapters(List chapters) { adapter.setItems(chapters); } + public void onNextOnlineChapters() { + swipe_refresh.setRefreshing(false); + } + + public void setSwipeRefreshing() { + swipe_refresh.setRefreshing(true); + } } diff --git a/app/src/main/res/layout/fragment_manga_chapters.xml b/app/src/main/res/layout/fragment_manga_chapters.xml index 273ad35e6..25fb07566 100644 --- a/app/src/main/res/layout/fragment_manga_chapters.xml +++ b/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:layout_height="match_parent"> - + + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index 3a6660845..2384b2907 100644 --- a/build.gradle +++ b/build.gradle @@ -16,5 +16,6 @@ buildscript { allprojects { repositories { jcenter() + maven {url "https://clojars.org/repo/"} } }