mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-04 08:08:55 +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