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 MOCKITO_VERSION = '1.10.19' | ||||||
|     final STORIO_VERSION = '1.4.0' |     final STORIO_VERSION = '1.4.0' | ||||||
|     final NUCLEUS_VERSION = '2.0.1' |     final NUCLEUS_VERSION = '2.0.1' | ||||||
|  |     final ICEPICK_VERSION = '3.1.0' | ||||||
| 
 | 
 | ||||||
|     compile fileTree(dir: 'libs', include: ['*.jar']) |     compile fileTree(dir: 'libs', include: ['*.jar']) | ||||||
| 
 | 
 | ||||||
| @ -75,6 +76,8 @@ dependencies { | |||||||
|     compile 'com.jakewharton.timber:timber:3.1.0' |     compile 'com.jakewharton.timber:timber:3.1.0' | ||||||
|     compile 'uk.co.ribot:easyadapter:1.5.0@aar' |     compile 'uk.co.ribot:easyadapter:1.5.0@aar' | ||||||
|     compile 'ch.acra:acra:4.6.2' |     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" |     compile "com.google.dagger:dagger:$DAGGER_VERSION" | ||||||
|     apt "com.google.dagger:dagger-compiler:$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 { | -keep public class * extends android.support.v4.view.ActionProvider { | ||||||
|     public <init>(android.content.Context); |     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.impl.DefaultStorIOSQLite; | ||||||
| import com.pushtorefresh.storio.sqlite.operations.delete.DeleteResult; | import com.pushtorefresh.storio.sqlite.operations.delete.DeleteResult; | ||||||
| import com.pushtorefresh.storio.sqlite.operations.delete.DeleteResults; | 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.PutResult; | ||||||
| import com.pushtorefresh.storio.sqlite.operations.put.PutResults; | import com.pushtorefresh.storio.sqlite.operations.put.PutResults; | ||||||
| 
 | 
 | ||||||
| @ -73,7 +74,7 @@ public class DatabaseHelper implements MangaManager, ChapterManager { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     public Observable insertOrRemoveChapters(Manga manga, List<Chapter> chapters) { |     public Observable<PostResult> insertOrRemoveChapters(Manga manga, List<Chapter> chapters) { | ||||||
|         return mChapterManager.insertOrRemoveChapters(manga, 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.DeleteResult; | ||||||
| import com.pushtorefresh.storio.sqlite.operations.delete.DeleteResults; | 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.PutResult; | ||||||
| import com.pushtorefresh.storio.sqlite.operations.put.PutResults; | import com.pushtorefresh.storio.sqlite.operations.put.PutResults; | ||||||
| 
 | 
 | ||||||
| @ -21,7 +22,7 @@ public interface ChapterManager { | |||||||
| 
 | 
 | ||||||
|     Observable<PutResults<Chapter>> insertChapters(List<Chapter> chapters); |     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); |     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 |     // Add new chapters or delete if the source deletes them | ||||||
|     @Override |     @Override | ||||||
|     public Observable<PostResult> insertOrRemoveChapters(Manga manga, List<Chapter> chapters) { |     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 -> { |         Observable<List<Chapter>> chapterList = Observable.create(subscriber -> { | ||||||
|             subscriber.onNext(prepareGetChapters(manga).executeAsBlocking()); |             subscriber.onNext(prepareGetChapters(manga).executeAsBlocking()); | ||||||
|             subscriber.onCompleted(); |             subscriber.onCompleted(); | ||||||
|  | |||||||
| @ -1,11 +1,27 @@ | |||||||
| package eu.kanade.mangafeed.presenter; | package eu.kanade.mangafeed.presenter; | ||||||
| 
 | 
 | ||||||
|  | import android.os.Bundle; | ||||||
|  | import android.support.annotation.NonNull; | ||||||
|  | 
 | ||||||
| import de.greenrobot.event.EventBus; | import de.greenrobot.event.EventBus; | ||||||
|  | import icepick.Icepick; | ||||||
| import nucleus.presenter.RxPresenter; | import nucleus.presenter.RxPresenter; | ||||||
| import nucleus.view.ViewWithPresenter; | import nucleus.view.ViewWithPresenter; | ||||||
| 
 | 
 | ||||||
| public class BasePresenter<V extends ViewWithPresenter> extends RxPresenter<V> { | 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() { |     public void registerForStickyEvents() { | ||||||
|         EventBus.getDefault().registerSticky(this); |         EventBus.getDefault().registerSticky(this); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -1,15 +1,22 @@ | |||||||
| package eu.kanade.mangafeed.presenter; | 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 javax.inject.Inject; | ||||||
| 
 | 
 | ||||||
| import eu.kanade.mangafeed.data.helpers.DatabaseHelper; | import eu.kanade.mangafeed.data.helpers.DatabaseHelper; | ||||||
| import eu.kanade.mangafeed.data.helpers.SourceManager; | 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.data.models.Manga; | ||||||
| import eu.kanade.mangafeed.sources.Source; |  | ||||||
| import eu.kanade.mangafeed.ui.fragment.MangaChaptersFragment; | import eu.kanade.mangafeed.ui.fragment.MangaChaptersFragment; | ||||||
| import rx.Subscription; | import rx.Observable; | ||||||
| import rx.android.schedulers.AndroidSchedulers; | import rx.android.schedulers.AndroidSchedulers; | ||||||
| import rx.schedulers.Schedulers; | import rx.schedulers.Schedulers; | ||||||
|  | import timber.log.Timber; | ||||||
| 
 | 
 | ||||||
| public class MangaChaptersPresenter extends BasePresenter<MangaChaptersFragment> { | public class MangaChaptersPresenter extends BasePresenter<MangaChaptersFragment> { | ||||||
| 
 | 
 | ||||||
| @ -17,9 +24,24 @@ public class MangaChaptersPresenter extends BasePresenter<MangaChaptersFragment> | |||||||
|     @Inject SourceManager sourceManager; |     @Inject SourceManager sourceManager; | ||||||
| 
 | 
 | ||||||
|     private Manga manga; |     private Manga manga; | ||||||
|     private Subscription chaptersSubscription; | 
 | ||||||
|     private Subscription onlineChaptersSubscription; |     private static final int DB_CHAPTERS = 1; | ||||||
|     private boolean doingRequest = false; |     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 |     @Override | ||||||
|     protected void onTakeView(MangaChaptersFragment view) { |     protected void onTakeView(MangaChaptersFragment view) { | ||||||
| @ -34,43 +56,30 @@ public class MangaChaptersPresenter extends BasePresenter<MangaChaptersFragment> | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public void onEventMainThread(Manga manga) { |     public void onEventMainThread(Manga manga) { | ||||||
|         this.manga = manga; |         if (this.manga == null) { | ||||||
|         getChapters(); |             this.manga = manga; | ||||||
|  |             start(DB_CHAPTERS); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public void refreshChapters() { |     public void refreshChapters(MangaChaptersFragment view) { | ||||||
|         if (manga != null && !doingRequest) |         if (manga != null) { | ||||||
|             getChaptersFromSource(manga); |             view.setSwipeRefreshing(); | ||||||
|  |             start(ONLINE_CHAPTERS); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public void getChapters() { |     private Observable<List<Chapter>> getDbChaptersObs() { | ||||||
|         if (chaptersSubscription != null) |         return db.getChapters(manga.id) | ||||||
|             return; |  | ||||||
| 
 |  | ||||||
|         add(chaptersSubscription = db.getChapters(manga.id) |  | ||||||
|                 .subscribeOn(Schedulers.io()) |                 .subscribeOn(Schedulers.io()) | ||||||
|                 .observeOn(AndroidSchedulers.mainThread()) |                 .observeOn(AndroidSchedulers.mainThread()); | ||||||
|                 .compose(deliverLatestCache()) |  | ||||||
|                 .subscribe(this.split(MangaChaptersFragment::onNextChapters))); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public void getChaptersFromSource(Manga manga) { |     private Observable<PostResult> getOnlineChaptersObs() { | ||||||
|         if (onlineChaptersSubscription != null) |         return sourceManager.get(manga.source) | ||||||
|             remove(onlineChaptersSubscription); |                 .pullChaptersFromNetwork(manga.url) | ||||||
| 
 |  | ||||||
|         Source source = sourceManager.get(manga.source); |  | ||||||
|         doingRequest = true; |  | ||||||
| 
 |  | ||||||
|         onlineChaptersSubscription = source.pullChaptersFromNetwork(manga.url) |  | ||||||
|                 .subscribeOn(Schedulers.io()) |                 .subscribeOn(Schedulers.io()) | ||||||
|                 .observeOn(AndroidSchedulers.mainThread()) |                 .flatMap(chapters -> db.insertOrRemoveChapters(manga, chapters)) | ||||||
|                 .compose(deliverLatestCache()) |                 .observeOn(AndroidSchedulers.mainThread()); | ||||||
|                 .subscribe(this.split((view, chapters) -> { |  | ||||||
|                     doingRequest = false; |  | ||||||
|                 }), throwable -> { |  | ||||||
|                     doingRequest = false; |  | ||||||
|                 }); |  | ||||||
| 
 |  | ||||||
|         add(onlineChaptersSubscription); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -2,6 +2,7 @@ package eu.kanade.mangafeed.ui.fragment; | |||||||
| 
 | 
 | ||||||
| import android.os.Bundle; | import android.os.Bundle; | ||||||
| import android.support.v4.app.Fragment; | import android.support.v4.app.Fragment; | ||||||
|  | import android.support.v4.widget.SwipeRefreshLayout; | ||||||
| import android.support.v7.widget.LinearLayoutManager; | import android.support.v7.widget.LinearLayoutManager; | ||||||
| import android.support.v7.widget.RecyclerView; | import android.support.v7.widget.RecyclerView; | ||||||
| import android.view.LayoutInflater; | import android.view.LayoutInflater; | ||||||
| @ -26,6 +27,7 @@ import uk.co.ribot.easyadapter.EasyRecyclerAdapter; | |||||||
| public class MangaChaptersFragment extends BaseFragment<MangaChaptersPresenter> { | public class MangaChaptersFragment extends BaseFragment<MangaChaptersPresenter> { | ||||||
| 
 | 
 | ||||||
|     @Bind(R.id.chapter_list) RecyclerView chapters; |     @Bind(R.id.chapter_list) RecyclerView chapters; | ||||||
|  |     @Bind(R.id.swipe_refresh) SwipeRefreshLayout swipe_refresh; | ||||||
| 
 | 
 | ||||||
|     private EasyRecyclerAdapter<Chapter> adapter; |     private EasyRecyclerAdapter<Chapter> adapter; | ||||||
| 
 | 
 | ||||||
| @ -48,6 +50,7 @@ public class MangaChaptersFragment extends BaseFragment<MangaChaptersPresenter> | |||||||
| 
 | 
 | ||||||
|         chapters.setLayoutManager(new LinearLayoutManager(getActivity())); |         chapters.setLayoutManager(new LinearLayoutManager(getActivity())); | ||||||
|         createAdapter(); |         createAdapter(); | ||||||
|  |         setSwipeRefreshListener(); | ||||||
| 
 | 
 | ||||||
|         return view; |         return view; | ||||||
|     } |     } | ||||||
| @ -62,7 +65,7 @@ public class MangaChaptersFragment extends BaseFragment<MangaChaptersPresenter> | |||||||
|     public boolean onOptionsItemSelected(MenuItem item) { |     public boolean onOptionsItemSelected(MenuItem item) { | ||||||
|         switch (item.getItemId()) { |         switch (item.getItemId()) { | ||||||
|             case R.id.action_refresh: |             case R.id.action_refresh: | ||||||
|                 getPresenter().refreshChapters(); |                 getPresenter().refreshChapters(this); | ||||||
|                 break; |                 break; | ||||||
|         } |         } | ||||||
|         return super.onOptionsItemSelected(item); |         return super.onOptionsItemSelected(item); | ||||||
| @ -73,8 +76,19 @@ public class MangaChaptersFragment extends BaseFragment<MangaChaptersPresenter> | |||||||
|         chapters.setAdapter(adapter); |         chapters.setAdapter(adapter); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     private void setSwipeRefreshListener() { | ||||||
|  |         swipe_refresh.setOnRefreshListener(() -> getPresenter().refreshChapters(this)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public void onNextChapters(List<Chapter> chapters) { |     public void onNextChapters(List<Chapter> chapters) { | ||||||
|         adapter.setItems(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:orientation="vertical" android:layout_width="match_parent" | ||||||
|     android:layout_height="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_width="match_parent" | ||||||
|         android:layout_height="wrap_content" |         android:layout_height="match_parent"> | ||||||
|         android:id="@+id/chapter_list"> |  | ||||||
| 
 | 
 | ||||||
|     </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> | </LinearLayout> | ||||||
| @ -16,5 +16,6 @@ buildscript { | |||||||
| allprojects { | allprojects { | ||||||
|     repositories { |     repositories { | ||||||
|         jcenter() |         jcenter() | ||||||
|  |         maven {url "https://clojars.org/repo/"} | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 inorichi
						inorichi