mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-31 14:27:57 +01:00 
			
		
		
		
	Add presenter subscriptions to the subscription list when using custom subscribe methods
This commit is contained in:
		| @@ -32,7 +32,7 @@ class BackupFragment : BaseRxFragment<BackupPresenter>() { | ||||
|         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<BackupPresenter>() { | ||||
|  | ||||
|     /** | ||||
|      * 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, "")) | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -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<BackupFragment>() { | ||||
|     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<BackupFragment>() { | ||||
|      * @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<BackupFragment>() { | ||||
|      * @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<Boolean> { | ||||
|         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<Boolean> { | ||||
|         return Observable.fromCallable { | ||||
|             backupManager.restoreFromStream(restoreStream!!) | ||||
|             true | ||||
|         }.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()) | ||||
|     private fun getRestoreObservable(stream: InputStream) = Observable.fromCallable { | ||||
|         backupManager.restoreFromStream(stream) | ||||
|         true | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -8,13 +8,34 @@ open class BasePresenter<V : ViewWithPresenter<*>> : RxPresenter<V>() { | ||||
|  | ||||
|     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 <T> Observable<T>.subscribeFirst(onNext: (V, T) -> Unit, onError: ((V, Throwable) -> Unit)? = null) | ||||
|             = compose(deliverFirst<T>()).subscribe(split(onNext, onError)) | ||||
|             = compose(deliverFirst<T>()).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 <T> Observable<T>.subscribeLatestCache(onNext: (V, T) -> Unit, onError: ((V, Throwable) -> Unit)? = null) | ||||
|             = compose(deliverLatestCache<T>()).subscribe(split(onNext, onError)) | ||||
|             = compose(deliverLatestCache<T>()).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 <T> Observable<T>.subscribeReplay(onNext: (V, T) -> Unit, onError: ((V, Throwable) -> Unit)? = null) | ||||
|             = compose(deliverReplay<T>()).subscribe(split(onNext, onError)) | ||||
|             = compose(deliverReplay<T>()).subscribe(split(onNext, onError)).apply { add(this) } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -113,7 +113,16 @@ public class RxPresenter<View> extends Presenter<View> { | ||||
|      * @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(); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -49,8 +49,8 @@ class MangaPresenter : BasePresenter<MangaActivity>() { | ||||
|         // 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() { | ||||
|   | ||||
| @@ -69,8 +69,8 @@ class ChaptersPresenter : BasePresenter<ChaptersFragment>() { | ||||
|                 { 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) | ||||
|   | ||||
| @@ -79,9 +79,9 @@ class MangaInfoPresenter : BasePresenter<MangaInfoFragment>() { | ||||
|  | ||||
|         // 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) }) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user