Use nucleus restartables in chapters presenter. Fix some database methods. Add swipe refresh to chapters fragment. Use Icepick library.
This commit is contained in:
parent
920a71601b
commit
1719959bc8
10 changed files with 105 additions and 42 deletions
|
@ -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
app/proguard-rules.pro
vendored
7
app/proguard-rules.pro
vendored
|
@ -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>;
|
||||
}
|
|
@ -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,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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
|
@ -16,5 +16,6 @@ buildscript {
|
|||
allprojects {
|
||||
repositories {
|
||||
jcenter()
|
||||
maven {url "https://clojars.org/repo/"}
|
||||
}
|
||||
}
|
||||
|
|
Reference in a new issue