From f191db2fe0cd44d3fb2b209660cff8904c52b789 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Wed, 8 Jul 2020 01:50:28 -0700 Subject: [PATCH] Allow ViewModel to opt-out RxJava Transition period --- .../topjohnwu/magisk/ui/base/BaseViewModel.kt | 20 +++++++++++++++---- .../topjohnwu/magisk/ui/hide/HideViewModel.kt | 2 +- .../topjohnwu/magisk/ui/home/HomeViewModel.kt | 2 +- .../topjohnwu/magisk/ui/log/LogViewModel.kt | 2 +- .../magisk/ui/module/ModuleViewModel.kt | 8 +++----- .../magisk/ui/superuser/SuperuserViewModel.kt | 2 +- 6 files changed, 23 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/base/BaseViewModel.kt b/app/src/main/java/com/topjohnwu/magisk/ui/base/BaseViewModel.kt index f0b906273..fac30fe78 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/base/BaseViewModel.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/base/BaseViewModel.kt @@ -21,11 +21,13 @@ import io.reactivex.* import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.Disposable import io.reactivex.subjects.PublishSubject +import kotlinx.coroutines.Job import org.koin.core.KoinComponent import androidx.databinding.Observable as BindingObservable abstract class BaseViewModel( - initialState: State = State.LOADING + initialState: State = State.LOADING, + val useRx: Boolean = true ) : ViewModel(), BindingObservable, KoinComponent { enum class State { @@ -49,6 +51,7 @@ abstract class BaseViewModel( private val disposables = CompositeDisposable() private val _viewEvents = MutableLiveData() private var runningTask: Disposable? = null + private var runningJob: Job? = null private val refreshCallback = object : androidx.databinding.Observable.OnPropertyChangedCallback() { override fun onPropertyChanged(sender: androidx.databinding.Observable?, propertyId: Int) { requestRefresh() @@ -62,13 +65,22 @@ abstract class BaseViewModel( /** This should probably never be called manually, it's called manually via delegate. */ @Synchronized fun requestRefresh() { - if (runningTask?.isDisposed?.not() == true) { + if (useRx) { + if (runningTask?.isDisposed?.not() == true) { + return + } + runningTask = rxRefresh() return } - runningTask = refresh() + if (runningJob?.isActive == true) { + return + } + runningJob = refresh() } - protected open fun refresh(): Disposable? = null + protected open fun rxRefresh(): Disposable? = null + + protected open fun refresh(): Job? = null open fun notifyStateChanged() { notifyPropertyChanged(BR.loading) diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/hide/HideViewModel.kt b/app/src/main/java/com/topjohnwu/magisk/ui/hide/HideViewModel.kt index 6e8869367..e92797aec 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/hide/HideViewModel.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/hide/HideViewModel.kt @@ -50,7 +50,7 @@ class HideViewModel( val isFilterExpanded = KObservableField(false) - override fun refresh() = magiskRepo.fetchApps() + override fun rxRefresh() = magiskRepo.fetchApps() .map { it to magiskRepo.fetchHideTargets().blockingGet() } .map { pair -> pair.first.map { mergeAppTargets(it, pair.second) } } .flattenAsFlowable { it } diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/home/HomeViewModel.kt b/app/src/main/java/com/topjohnwu/magisk/ui/home/HomeViewModel.kt index fd49bfb29..cd07fe99b 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/home/HomeViewModel.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/home/HomeViewModel.kt @@ -72,7 +72,7 @@ class HomeViewModel( } } - override fun refresh() = repoMagisk.fetchUpdate() + override fun rxRefresh() = repoMagisk.fetchUpdate() .onErrorReturn { null } .subscribeK { it?.updateUI() } diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/log/LogViewModel.kt b/app/src/main/java/com/topjohnwu/magisk/ui/log/LogViewModel.kt index 17c9162b0..abcbef528 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/log/LogViewModel.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/log/LogViewModel.kt @@ -42,7 +42,7 @@ class LogViewModel( val consoleText = KObservableField(" ") - override fun refresh(): Disposable { + override fun rxRefresh(): Disposable { val logs = repo.fetchLogs() .map { it.map { LogItem(it) } } .observeOn(Schedulers.computation()) diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/module/ModuleViewModel.kt b/app/src/main/java/com/topjohnwu/magisk/ui/module/ModuleViewModel.kt index 73205a2aa..372295ad6 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/module/ModuleViewModel.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/module/ModuleViewModel.kt @@ -24,7 +24,6 @@ import com.topjohnwu.magisk.model.events.dialog.ModuleInstallDialog import com.topjohnwu.magisk.ui.base.* import com.topjohnwu.magisk.utils.EndlessRecyclerScrollListener import com.topjohnwu.magisk.utils.KObservableField -import io.reactivex.disposables.Disposable import kotlinx.coroutines.* import me.tatarka.bindingcollectionadapter2.collections.MergeObservableList import kotlin.math.roundToInt @@ -47,7 +46,7 @@ class ModuleViewModel( private val repoName: RepoByNameDao, private val repoUpdated: RepoByUpdatedDao, private val repoUpdater: RepoUpdater -) : BaseViewModel(), Queryable { +) : BaseViewModel(useRx = false), Queryable { override val queryDelay = 1000L private var queryJob: Job? = null @@ -168,11 +167,10 @@ class ModuleViewModel( // --- - override fun refresh(): Disposable? { + override fun refresh(): Job { if (itemsRemote.isEmpty()) loadRemote() - loadInstalled() - return null + return loadInstalled() } private suspend fun loadUpdates(installed: List) = withContext(Dispatchers.IO) { diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/superuser/SuperuserViewModel.kt b/app/src/main/java/com/topjohnwu/magisk/ui/superuser/SuperuserViewModel.kt index 8f559b5ed..2bd394c39 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/superuser/SuperuserViewModel.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/superuser/SuperuserViewModel.kt @@ -53,7 +53,7 @@ class SuperuserViewModel( // --- - override fun refresh() = db.fetchAll() + override fun rxRefresh() = db.fetchAll() .flattenAsFlowable { it } .parallel() .map { PolicyItem(it, it.applicationInfo.loadIcon(packageManager)) }