From 2fa5d0cbafd456476a554ab0b925c395f28549af Mon Sep 17 00:00:00 2001 From: len Date: Sun, 10 Apr 2016 04:32:43 +0200 Subject: [PATCH] Add presenter subscriptions to the subscription list when using custom subscribe methods --- .../tachiyomi/ui/backup/BackupFragment.kt | 8 ++- .../tachiyomi/ui/backup/BackupPresenter.kt | 66 +++++++------------ .../ui/base/presenter/BasePresenter.kt | 27 +++++++- .../ui/base/presenter/RxPresenter.java | 11 +++- .../tachiyomi/ui/manga/MangaPresenter.kt | 4 +- .../ui/manga/chapter/ChaptersPresenter.kt | 4 +- .../ui/manga/info/MangaInfoPresenter.kt | 4 +- 7 files changed, 70 insertions(+), 54 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/backup/BackupFragment.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/backup/BackupFragment.kt index 15f4b0c04..f840944e0 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/backup/BackupFragment.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/backup/BackupFragment.kt @@ -32,7 +32,7 @@ class BackupFragment : BaseRxFragment() { return inflater.inflate(R.layout.fragment_backup, container, false) } - override fun onViewCreated(view: View?, savedState: Bundle?) { + override fun onViewCreated(view: View, savedState: Bundle?) { backup_button.setOnClickListener { val today = SimpleDateFormat("yyyy-MM-dd").format(Date()) val file = File(activity.externalCacheDir, "tachiyomi-$today.json") @@ -55,12 +55,14 @@ class BackupFragment : BaseRxFragment() { /** * Called from the presenter when the backup is completed. + * + * @param file the file where the backup is saved. */ - fun onBackupCompleted() { + fun onBackupCompleted(file: File) { dismissBackupDialog() val intent = Intent(Intent.ACTION_SEND) intent.type = "text/plain" - intent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + presenter.backupFile)) + intent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + file)) startActivity(Intent.createChooser(intent, "")) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/backup/BackupPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/backup/BackupPresenter.kt index 1be74c597..f943f997c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/backup/BackupPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/backup/BackupPresenter.kt @@ -5,6 +5,7 @@ import eu.kanade.tachiyomi.data.backup.BackupManager import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter import rx.Observable +import rx.Subscription import rx.android.schedulers.AndroidSchedulers import rx.schedulers.Schedulers import java.io.File @@ -27,39 +28,18 @@ class BackupPresenter : BasePresenter() { private lateinit var backupManager: BackupManager /** - * File where the backup is saved. + * Subscription where the backup is restored. */ - var backupFile: File? = null - private set + private var restoreSubscription: Subscription? = null /** - * Stream to restore a backup. + * Subscription where the backup is created. */ - private var restoreStream: InputStream? = null - - /** - * Id of the restartable that creates a backup. - */ - private val CREATE_BACKUP = 1 - - /** - * Id of the restartable that restores a backup. - */ - private val RESTORE_BACKUP = 2 + private var backupSubscription: Subscription? = null override fun onCreate(savedState: Bundle?) { super.onCreate(savedState) backupManager = BackupManager(db) - - startableFirst(CREATE_BACKUP, - { getBackupObservable() }, - { view, next -> view.onBackupCompleted() }, - { view, error -> view.onBackupError(error) }) - - startableFirst(RESTORE_BACKUP, - { getRestoreObservable() }, - { view, next -> view.onRestoreCompleted() }, - { view, error -> view.onRestoreError(error) }) } /** @@ -68,9 +48,13 @@ class BackupPresenter : BasePresenter() { * @param file the path where the file will be saved. */ fun createBackup(file: File) { - if (isUnsubscribed(CREATE_BACKUP)) { - backupFile = file - start(CREATE_BACKUP) + if (isUnsubscribed(backupSubscription)) { + backupSubscription = getBackupObservable(file) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeFirst( + { view, result -> view.onBackupCompleted(file) }, + { view, error -> view.onBackupError(error) }) } } @@ -80,30 +64,30 @@ class BackupPresenter : BasePresenter() { * @param stream the input stream of the backup file. */ fun restoreBackup(stream: InputStream) { - if (isUnsubscribed(RESTORE_BACKUP)) { - restoreStream = stream - start(RESTORE_BACKUP) + if (isUnsubscribed(restoreSubscription)) { + restoreSubscription = getRestoreObservable(stream) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeFirst( + { view, result -> view.onRestoreCompleted() }, + { view, error -> view.onRestoreError(error) }) } } /** * Returns the observable to save a backup. */ - private fun getBackupObservable(): Observable { - return Observable.fromCallable { - backupManager.backupToFile(backupFile!!) - true - }.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()) + private fun getBackupObservable(file: File) = Observable.fromCallable { + backupManager.backupToFile(file) + true } /** * Returns the observable to restore a backup. */ - private fun getRestoreObservable(): Observable { - return Observable.fromCallable { - backupManager.restoreFromStream(restoreStream!!) - true - }.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()) + private fun getRestoreObservable(stream: InputStream) = Observable.fromCallable { + backupManager.restoreFromStream(stream) + true } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/base/presenter/BasePresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/base/presenter/BasePresenter.kt index 50f9eda78..dc91615b3 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/base/presenter/BasePresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/base/presenter/BasePresenter.kt @@ -8,13 +8,34 @@ open class BasePresenter> : RxPresenter() { lateinit var context: Context + /** + * Subscribes an observable with [deliverFirst] and adds it to the presenter's lifecycle + * subscription list. + * + * @param onNext function to execute when the observable emits an item. + * @param onError function to execute when the observable throws an error. + */ fun Observable.subscribeFirst(onNext: (V, T) -> Unit, onError: ((V, Throwable) -> Unit)? = null) - = compose(deliverFirst()).subscribe(split(onNext, onError)) + = compose(deliverFirst()).subscribe(split(onNext, onError)).apply { add(this) } + /** + * Subscribes an observable with [deliverLatestCache] and adds it to the presenter's lifecycle + * subscription list. + * + * @param onNext function to execute when the observable emits an item. + * @param onError function to execute when the observable throws an error. + */ fun Observable.subscribeLatestCache(onNext: (V, T) -> Unit, onError: ((V, Throwable) -> Unit)? = null) - = compose(deliverLatestCache()).subscribe(split(onNext, onError)) + = compose(deliverLatestCache()).subscribe(split(onNext, onError)).apply { add(this) } + /** + * Subscribes an observable with [deliverReplay] and adds it to the presenter's lifecycle + * subscription list. + * + * @param onNext function to execute when the observable emits an item. + * @param onError function to execute when the observable throws an error. + */ fun Observable.subscribeReplay(onNext: (V, T) -> Unit, onError: ((V, Throwable) -> Unit)? = null) - = compose(deliverReplay()).subscribe(split(onNext, onError)) + = compose(deliverReplay()).subscribe(split(onNext, onError)).apply { add(this) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/base/presenter/RxPresenter.java b/app/src/main/java/eu/kanade/tachiyomi/ui/base/presenter/RxPresenter.java index 7789e13e2..370ab64f9 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/base/presenter/RxPresenter.java +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/base/presenter/RxPresenter.java @@ -113,7 +113,16 @@ public class RxPresenter extends Presenter { * @return true if the subscription is null or unsubscribed, false otherwise. */ public boolean isUnsubscribed(int restartableId) { - Subscription subscription = restartableSubscriptions.get(restartableId); + return isUnsubscribed(restartableSubscriptions.get(restartableId)); + } + + /** + * Checks if a subscription is unsubscribed. + * + * @param subscription the subscription to check. + * @return true if the subscription is null or unsubscribed, false otherwise. + */ + public boolean isUnsubscribed(@Nullable Subscription subscription) { return subscription == null || subscription.isUnsubscribed(); } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt index d7d1867ec..825eba8cf 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt @@ -49,8 +49,8 @@ class MangaPresenter : BasePresenter() { // Prepare a subject to communicate the chapters and info presenters for the chapter count. SharedData.put(ChapterCountEvent()) - add(Observable.just(manga) - .subscribeLatestCache({ view, manga -> view.onSetManga(manga) })) + Observable.just(manga) + .subscribeLatestCache({ view, manga -> view.onSetManga(manga) }) } override fun onDestroy() { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersPresenter.kt index c64ecf138..38eb5be3d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersPresenter.kt @@ -69,8 +69,8 @@ class ChaptersPresenter : BasePresenter() { { view, error -> Timber.e(error.cause, error.message) }) manga = SharedData.get(MangaEvent::class.java)?.manga ?: return - add(Observable.just(manga) - .subscribeLatestCache({ view, manga -> view.onNextManga(manga) })) + Observable.just(manga) + .subscribeLatestCache({ view, manga -> view.onNextManga(manga) }) source = sourceManager.get(manga.source)!! start(DB_CHAPTERS) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoPresenter.kt index 4c25c81a1..4ff860b3f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoPresenter.kt @@ -79,9 +79,9 @@ class MangaInfoPresenter : BasePresenter() { // Update chapter count SharedData.get(ChapterCountEvent::class.java)?.let { - add(it.observable + it.observable .observeOn(AndroidSchedulers.mainThread()) - .subscribeLatestCache({ view, count -> view.setChapterCount(count) })) + .subscribeLatestCache({ view, count -> view.setChapterCount(count) }) } }