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
					
				| @ -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
									
									
								
							| @ -94,3 +94,10 @@ | ||||
| -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) { | ||||
|         if (this.manga == null) { | ||||
|             this.manga = manga; | ||||
|         getChapters(); | ||||
|             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,6 +3,11 @@ | ||||
|     android:orientation="vertical" android:layout_width="match_parent" | ||||
|     android:layout_height="match_parent"> | ||||
| 
 | ||||
|     <android.support.v4.widget.SwipeRefreshLayout | ||||
|         android:id="@+id/swipe_refresh" | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="match_parent"> | ||||
| 
 | ||||
|         <android.support.v7.widget.RecyclerView | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="wrap_content" | ||||
| @ -10,4 +15,6 @@ | ||||
| 
 | ||||
|         </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/"} | ||||
|     } | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 inorichi
						inorichi