Commit 84f1e786 authored by topjohnwu's avatar topjohnwu

Consolidate base viewmodel implementation

parent 3490ba0a
...@@ -16,7 +16,6 @@ import androidx.databinding.ViewDataBinding ...@@ -16,7 +16,6 @@ import androidx.databinding.ViewDataBinding
import com.topjohnwu.magisk.BR import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.Config import com.topjohnwu.magisk.Config
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.base.viewmodel.BaseViewModel
import com.topjohnwu.magisk.extensions.set import com.topjohnwu.magisk.extensions.set
import com.topjohnwu.magisk.model.events.EventHandler import com.topjohnwu.magisk.model.events.EventHandler
import com.topjohnwu.magisk.model.permissions.PermissionRequestBuilder import com.topjohnwu.magisk.model.permissions.PermissionRequestBuilder
......
...@@ -8,7 +8,6 @@ import androidx.databinding.DataBindingUtil ...@@ -8,7 +8,6 @@ import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import com.topjohnwu.magisk.BR import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.base.viewmodel.BaseViewModel
import com.topjohnwu.magisk.model.events.EventHandler import com.topjohnwu.magisk.model.events.EventHandler
import com.topjohnwu.magisk.model.events.ViewEvent import com.topjohnwu.magisk.model.events.ViewEvent
......
package com.topjohnwu.magisk.base
import androidx.annotation.CallSuper
import androidx.core.graphics.Insets
import androidx.databinding.Bindable
import androidx.databinding.PropertyChangeRegistry
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.Info
import com.topjohnwu.magisk.extensions.doOnSubscribeUi
import com.topjohnwu.magisk.model.events.*
import com.topjohnwu.magisk.model.observer.Observer
import com.topjohnwu.magisk.utils.KObservableField
import io.reactivex.*
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
import io.reactivex.subjects.PublishSubject
import org.koin.core.KoinComponent
import androidx.databinding.Observable as BindingObservable
abstract class BaseViewModel(
initialState: State = State.LOADING
) : ViewModel(), BindingObservable, KoinComponent {
enum class State {
LOADED, LOADING, LOADING_FAILED
}
val loading @Bindable get() = state == State.LOADING
val loaded @Bindable get() = state == State.LOADED
val loadingFailed @Bindable get() = state == State.LOADING_FAILED
val isConnected = Observer(Info.isConnected) { Info.isConnected.value }
val viewEvents: LiveData<ViewEvent> get() = _viewEvents
val insets = KObservableField(Insets.NONE)
var state: State = initialState
set(value) {
field = value
notifyStateChanged()
}
private val disposables = CompositeDisposable()
private val _viewEvents = MutableLiveData<ViewEvent>()
private var runningTask: Disposable? = null
private val refreshCallback = object : androidx.databinding.Observable.OnPropertyChangedCallback() {
override fun onPropertyChanged(sender: androidx.databinding.Observable?, propertyId: Int) {
requestRefresh()
}
}
init {
isConnected.addOnPropertyChangedCallback(refreshCallback)
}
/** This should probably never be called manually, it's called manually via delegate. */
@Synchronized
fun requestRefresh() {
if (runningTask?.isDisposed?.not() == true) {
return
}
runningTask = refresh()
}
protected open fun refresh(): Disposable? = null
open fun notifyStateChanged() {
notifyPropertyChanged(BR.loading)
notifyPropertyChanged(BR.loaded)
notifyPropertyChanged(BR.loadingFailed)
}
@CallSuper
override fun onCleared() {
isConnected.removeOnPropertyChangedCallback(refreshCallback)
disposables.clear()
super.onCleared()
}
fun withView(action: BaseActivity<*, *>.() -> Unit) {
ViewActionEvent(action).publish()
}
fun withPermissions(vararg permissions: String): Observable<Boolean> {
val subject = PublishSubject.create<Boolean>()
return subject.doOnSubscribeUi { PermissionEvent(permissions.toList(), subject).publish() }
}
fun back() = BackPressEvent().publish()
fun <Event : ViewEvent> Event.publish() {
_viewEvents.postValue(this)
}
fun Int.publish() {
_viewEvents.postValue(SimpleViewEvent(this))
}
fun Disposable.add() {
disposables.add(this)
}
// The following is copied from androidx.databinding.BaseObservable
@Transient
private var callbacks: PropertyChangeRegistry? = null
@Synchronized
override fun addOnPropertyChangedCallback(callback: BindingObservable.OnPropertyChangedCallback) {
if (callbacks == null) {
callbacks = PropertyChangeRegistry()
}
callbacks?.add(callback)
}
@Synchronized
override fun removeOnPropertyChangedCallback(callback: BindingObservable.OnPropertyChangedCallback) {
callbacks?.remove(callback)
}
/**
* Notifies listeners that all properties of this instance have changed.
*/
@Synchronized
fun notifyChange() {
callbacks?.notifyCallbacks(this, 0, null)
}
/**
* Notifies listeners that a specific property has changed. The getter for the property
* that changes should be marked with [androidx.databinding.Bindable] to generate a field in
* `BR` to be used as `fieldId`.
*
* @param fieldId The generated BR id for the Bindable field.
*/
fun notifyPropertyChanged(fieldId: Int) {
callbacks?.notifyCallbacks(this, fieldId, null)
}
//region Rx
protected fun <T> Observable<T>.applyViewModel(viewModel: BaseViewModel, allowFinishing: Boolean = true) =
doOnSubscribe { viewModel.state =
State.LOADING
}
.doOnError { viewModel.state =
State.LOADING_FAILED
}
.doOnNext { if (allowFinishing) viewModel.state =
State.LOADED
}
protected fun <T> Single<T>.applyViewModel(viewModel: BaseViewModel, allowFinishing: Boolean = true) =
doOnSubscribe { viewModel.state =
State.LOADING
}
.doOnError { viewModel.state =
State.LOADING_FAILED
}
.doOnSuccess { if (allowFinishing) viewModel.state =
State.LOADED
}
protected fun <T> Maybe<T>.applyViewModel(viewModel: BaseViewModel, allowFinishing: Boolean = true) =
doOnSubscribe { viewModel.state =
State.LOADING
}
.doOnError { viewModel.state =
State.LOADING_FAILED
}
.doOnComplete { if (allowFinishing) viewModel.state =
State.LOADED
}
.doOnSuccess { if (allowFinishing) viewModel.state =
State.LOADED
}
protected fun <T> Flowable<T>.applyViewModel(viewModel: BaseViewModel, allowFinishing: Boolean = true) =
doOnSubscribe { viewModel.state =
State.LOADING
}
.doOnError { viewModel.state =
State.LOADING_FAILED
}
.doOnNext { if (allowFinishing) viewModel.state =
State.LOADED
}
protected fun Completable.applyViewModel(viewModel: BaseViewModel, allowFinishing: Boolean = true) =
doOnSubscribe { viewModel.state =
State.LOADING
}
.doOnError { viewModel.state =
State.LOADING_FAILED
}
.doOnComplete { if (allowFinishing) viewModel.state =
State.LOADED
}
//endregion
}
package com.topjohnwu.magisk.base.viewmodel
import com.topjohnwu.magisk.base.BaseActivity
import com.topjohnwu.magisk.extensions.doOnSubscribeUi
import com.topjohnwu.magisk.model.events.BackPressEvent
import com.topjohnwu.magisk.model.events.PermissionEvent
import com.topjohnwu.magisk.model.events.ViewActionEvent
import com.topjohnwu.magisk.model.observer.Observer
import io.reactivex.Observable
import io.reactivex.subjects.PublishSubject
import com.topjohnwu.magisk.Info.isConnected as gIsConnected
abstract class BaseViewModel(
initialState: State = State.LOADING
) : LoadingViewModel(initialState) {
val isConnected = Observer(gIsConnected) { gIsConnected.value }
fun withView(action: BaseActivity<*, *>.() -> Unit) {
ViewActionEvent(action).publish()
}
fun withPermissions(vararg permissions: String): Observable<Boolean> {
val subject = PublishSubject.create<Boolean>()
return subject.doOnSubscribeUi { PermissionEvent(permissions.toList(), subject).publish() }
}
fun back() = BackPressEvent().publish()
}
package com.topjohnwu.magisk.base.viewmodel
import androidx.databinding.Bindable
import com.topjohnwu.magisk.BR
import io.reactivex.*
abstract class LoadingViewModel(defaultState: State = State.LOADING) :
StatefulViewModel<LoadingViewModel.State>(defaultState) {
val loading @Bindable get() = state == State.LOADING
val loaded @Bindable get() = state == State.LOADED
val loadingFailed @Bindable get() = state == State.LOADING_FAILED
@Deprecated(
"Direct access is recommended since 0.2. This access method will be removed in 1.0",
ReplaceWith("state = State.LOADING", "com.topjohnwu.magisk.base.viewmodel.LoadingViewModel.State"),
DeprecationLevel.WARNING
)
fun setLoading() {
state = State.LOADING
}
@Deprecated(
"Direct access is recommended since 0.2. This access method will be removed in 1.0",
ReplaceWith("state = State.LOADED", "com.topjohnwu.magisk.base.viewmodel.LoadingViewModel.State"),
DeprecationLevel.WARNING
)
fun setLoaded() {
state = State.LOADED
}
@Deprecated(
"Direct access is recommended since 0.2. This access method will be removed in 1.0",
ReplaceWith("state = State.LOADING_FAILED", "com.topjohnwu.magisk.base.viewmodel.LoadingViewModel.State"),
DeprecationLevel.WARNING
)
fun setLoadingFailed() {
state = State.LOADING_FAILED
}
override fun notifyStateChanged() {
notifyPropertyChanged(BR.loading)
notifyPropertyChanged(BR.loaded)
notifyPropertyChanged(BR.loadingFailed)
}
enum class State {
LOADED, LOADING, LOADING_FAILED
}
//region Rx
protected fun <T> Observable<T>.applyViewModel(viewModel: LoadingViewModel, allowFinishing: Boolean = true) =
doOnSubscribe { viewModel.state = State.LOADING }
.doOnError { viewModel.state = State.LOADING_FAILED }
.doOnNext { if (allowFinishing) viewModel.state = State.LOADED }
protected fun <T> Single<T>.applyViewModel(viewModel: LoadingViewModel, allowFinishing: Boolean = true) =
doOnSubscribe { viewModel.state = State.LOADING }
.doOnError { viewModel.state = State.LOADING_FAILED }
.doOnSuccess { if (allowFinishing) viewModel.state = State.LOADED }
protected fun <T> Maybe<T>.applyViewModel(viewModel: LoadingViewModel, allowFinishing: Boolean = true) =
doOnSubscribe { viewModel.state = State.LOADING }
.doOnError { viewModel.state = State.LOADING_FAILED }
.doOnComplete { if (allowFinishing) viewModel.state = State.LOADED }
.doOnSuccess { if (allowFinishing) viewModel.state = State.LOADED }
protected fun <T> Flowable<T>.applyViewModel(viewModel: LoadingViewModel, allowFinishing: Boolean = true) =
doOnSubscribe { viewModel.state = State.LOADING }
.doOnError { viewModel.state = State.LOADING_FAILED }
.doOnNext { if (allowFinishing) viewModel.state = State.LOADED }
protected fun Completable.applyViewModel(viewModel: LoadingViewModel, allowFinishing: Boolean = true) =
doOnSubscribe { viewModel.state = State.LOADING }
.doOnError { viewModel.state = State.LOADING_FAILED }
.doOnComplete { if (allowFinishing) viewModel.state = State.LOADED }
//endregion
}
\ No newline at end of file
package com.topjohnwu.magisk.base.viewmodel
import androidx.databinding.Observable
import androidx.databinding.PropertyChangeRegistry
import androidx.lifecycle.ViewModel
/**
* Copy of [androidx.databinding.BaseObservable] which extends [ViewModel]
*/
abstract class ObservableViewModel : TeanityViewModel(), Observable {
@Transient
private var callbacks: PropertyChangeRegistry? = null
@Synchronized
override fun addOnPropertyChangedCallback(callback: Observable.OnPropertyChangedCallback) {
if (callbacks == null) {
callbacks = PropertyChangeRegistry()
}
callbacks?.add(callback)
}
@Synchronized
override fun removeOnPropertyChangedCallback(callback: Observable.OnPropertyChangedCallback) {
callbacks?.remove(callback)
}
/**
* Notifies listeners that all properties of this instance have changed.
*/
@Synchronized
fun notifyChange() {
callbacks?.notifyCallbacks(this, 0, null)
}
/**
* Notifies listeners that a specific property has changed. The getter for the property
* that changes should be marked with [androidx.databinding.Bindable] to generate a field in
* `BR` to be used as `fieldId`.
*
* @param fieldId The generated BR id for the Bindable field.
*/
fun notifyPropertyChanged(fieldId: Int) {
callbacks?.notifyCallbacks(this, fieldId, null)
}
}
package com.topjohnwu.magisk.base.viewmodel
abstract class StatefulViewModel<State : Enum<*>>(
val defaultState: State
) : ObservableViewModel() {
var state: State = defaultState
set(value) {
field = value
notifyStateChanged()
}
open fun notifyStateChanged() = Unit
}
\ No newline at end of file
package com.topjohnwu.magisk.base.viewmodel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.topjohnwu.magisk.model.events.SimpleViewEvent
import com.topjohnwu.magisk.model.events.ViewEvent
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
abstract class TeanityViewModel : ViewModel() {
private val disposables = CompositeDisposable()
private val _viewEvents = MutableLiveData<ViewEvent>()
val viewEvents: LiveData<ViewEvent> get() = _viewEvents
override fun onCleared() {
super.onCleared()
disposables.clear()
}
fun <Event : ViewEvent> Event.publish() {
_viewEvents.postValue(this)
}
fun Int.publish() {
_viewEvents.postValue(SimpleViewEvent(this))
}
fun Disposable.add() {
disposables.add(this)
}
}
\ No newline at end of file
...@@ -11,7 +11,7 @@ import com.topjohnwu.magisk.BR ...@@ -11,7 +11,7 @@ import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.Config import com.topjohnwu.magisk.Config
import com.topjohnwu.magisk.Const import com.topjohnwu.magisk.Const
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.base.viewmodel.BaseViewModel import com.topjohnwu.magisk.base.BaseViewModel
import com.topjohnwu.magisk.databinding.ComparableRvItem import com.topjohnwu.magisk.databinding.ComparableRvItem
import com.topjohnwu.magisk.extensions.* import com.topjohnwu.magisk.extensions.*
import com.topjohnwu.magisk.model.entity.recycler.ConsoleRvItem import com.topjohnwu.magisk.model.entity.recycler.ConsoleRvItem
......
...@@ -10,7 +10,7 @@ import com.topjohnwu.magisk.BuildConfig ...@@ -10,7 +10,7 @@ import com.topjohnwu.magisk.BuildConfig
import com.topjohnwu.magisk.Config import com.topjohnwu.magisk.Config
import com.topjohnwu.magisk.Const import com.topjohnwu.magisk.Const
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.base.viewmodel.BaseViewModel import com.topjohnwu.magisk.base.BaseViewModel
import com.topjohnwu.magisk.data.database.PolicyDao import com.topjohnwu.magisk.data.database.PolicyDao
import com.topjohnwu.magisk.databinding.ComparableRvItem import com.topjohnwu.magisk.databinding.ComparableRvItem
import com.topjohnwu.magisk.extensions.now import com.topjohnwu.magisk.extensions.now
......
package com.topjohnwu.magisk.ui package com.topjohnwu.magisk.ui
import com.topjohnwu.magisk.ui.compat.CompatViewModel import com.topjohnwu.magisk.base.BaseViewModel
class MainViewModel : CompatViewModel() class MainViewModel : BaseViewModel()
...@@ -11,6 +11,7 @@ import androidx.databinding.OnRebindCallback ...@@ -11,6 +11,7 @@ import androidx.databinding.OnRebindCallback
import androidx.databinding.ViewDataBinding import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import com.topjohnwu.magisk.base.BaseActivity import com.topjohnwu.magisk.base.BaseActivity
import com.topjohnwu.magisk.base.BaseViewModel
import com.topjohnwu.magisk.extensions.snackbar import com.topjohnwu.magisk.extensions.snackbar
import com.topjohnwu.magisk.extensions.startAnimations import com.topjohnwu.magisk.extensions.startAnimations
import com.topjohnwu.magisk.model.events.SnackbarEvent import com.topjohnwu.magisk.model.events.SnackbarEvent
...@@ -21,7 +22,7 @@ import com.topjohnwu.magisk.ui.theme.Theme ...@@ -21,7 +22,7 @@ import com.topjohnwu.magisk.ui.theme.Theme
import kotlin.reflect.KClass import kotlin.reflect.KClass
abstract class CompatActivity<ViewModel : CompatViewModel, Binding : ViewDataBinding> : abstract class CompatActivity<ViewModel : BaseViewModel, Binding : ViewDataBinding> :
BaseActivity<ViewModel, Binding>(), CompatView<ViewModel>, Navigator { BaseActivity<ViewModel, Binding>(), CompatView<ViewModel>, Navigator {
override val themeRes = Theme.selected.themeRes override val themeRes = Theme.selected.themeRes
......
...@@ -7,10 +7,11 @@ import androidx.databinding.OnRebindCallback ...@@ -7,10 +7,11 @@ import androidx.databinding.OnRebindCallback
import androidx.databinding.ViewDataBinding import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import com.topjohnwu.magisk.base.BaseFragment import com.topjohnwu.magisk.base.BaseFragment
import com.topjohnwu.magisk.base.BaseViewModel
import com.topjohnwu.magisk.extensions.startAnimations import com.topjohnwu.magisk.extensions.startAnimations
import com.topjohnwu.magisk.model.events.ViewEvent import com.topjohnwu.magisk.model.events.ViewEvent
abstract class CompatFragment<ViewModel : CompatViewModel, Binding : ViewDataBinding> abstract class CompatFragment<ViewModel : BaseViewModel, Binding : ViewDataBinding>
: BaseFragment<ViewModel, Binding>(), CompatView<ViewModel> { : BaseFragment<ViewModel, Binding>(), CompatView<ViewModel> {
override val viewRoot: View get() = binding.root override val viewRoot: View get() = binding.root
......
...@@ -2,8 +2,9 @@ package com.topjohnwu.magisk.ui.compat ...@@ -2,8 +2,9 @@ package com.topjohnwu.magisk.ui.compat
import android.view.View import android.view.View
import androidx.core.graphics.Insets import androidx.core.graphics.Insets
import com.topjohnwu.magisk.base.BaseViewModel
internal interface CompatView<ViewModel : CompatViewModel> { internal interface CompatView<ViewModel : BaseViewModel> {
val viewRoot: View val viewRoot: View
val viewModel: ViewModel val viewModel: ViewModel
......
package com.topjohnwu.magisk.ui.compat
import androidx.annotation.CallSuper
import androidx.core.graphics.Insets
import androidx.databinding.Observable
import com.topjohnwu.magisk.base.viewmodel.BaseViewModel
import com.topjohnwu.magisk.utils.KObservableField
import io.reactivex.disposables.Disposable
import org.koin.core.KoinComponent
abstract class CompatViewModel(
initialState: State = State.LOADING
) : BaseViewModel(initialState), KoinComponent {
val insets = KObservableField(Insets.NONE)
private var runningTask: Disposable? = null
private val refreshCallback = object : Observable.OnPropertyChangedCallback() {
override fun onPropertyChanged(sender: Observable?, propertyId: Int) {
requestRefresh()
}
}
init {
isConnected.addOnPropertyChangedCallback(refreshCallback)
}
/** This should probably never be called manually, it's called manually via delegate. */
@Synchronized
fun requestRefresh() {
if (runningTask?.isDisposed?.not() == true) {
return
}
runningTask = refresh()
}
protected open fun refresh(): Disposable? = null
@CallSuper
override fun onCleared() {
isConnected.removeOnPropertyChangedCallback(refreshCallback)
super.onCleared()
}
}
package com.topjohnwu.magisk.ui.flash package com.topjohnwu.magisk.ui.flash
import com.topjohnwu.magisk.ui.compat.CompatViewModel import com.topjohnwu.magisk.base.BaseViewModel
class FlashViewModel : CompatViewModel() class FlashViewModel : BaseViewModel()
...@@ -12,7 +12,7 @@ import com.topjohnwu.magisk.model.entity.ProcessHideApp ...@@ -12,7 +12,7 @@ import com.topjohnwu.magisk.model.entity.ProcessHideApp
import com.topjohnwu.magisk.model.entity.StatefulProcess import com.topjohnwu.magisk.model.entity.StatefulProcess
import com.topjohnwu.magisk.model.entity.recycler.HideItem import com.topjohnwu.magisk.model.entity.recycler.HideItem
import com.topjohnwu.magisk.model.entity.recycler.HideProcessItem import com.topjohnwu.magisk.model.entity.recycler.HideProcessItem
import com.topjohnwu.magisk.ui.compat.CompatViewModel import com.topjohnwu.magisk.base.BaseViewModel
import com.topjohnwu.magisk.ui.compat.Queryable import com.topjohnwu.magisk.ui.compat.Queryable
import com.topjohnwu.magisk.ui.compat.filterableListOf import com.topjohnwu.magisk.ui.compat.filterableListOf
import com.topjohnwu.magisk.ui.compat.itemBindingOf import com.topjohnwu.magisk.ui.compat.itemBindingOf
...@@ -21,7 +21,7 @@ import com.topjohnwu.magisk.utils.currentLocale ...@@ -21,7 +21,7 @@ import com.topjohnwu.magisk.utils.currentLocale
class HideViewModel( class HideViewModel(
private val magiskRepo: MagiskRepository private val magiskRepo: MagiskRepository
) : CompatViewModel(), Queryable by Queryable.impl(1000) { ) : BaseViewModel(), Queryable by Queryable.impl(1000) {
override val queryRunnable = Runnable { query() } override val queryRunnable = Runnable { query() }
......
...@@ -22,7 +22,7 @@ import com.topjohnwu.magisk.model.events.dialog.ManagerInstallDialog ...@@ -22,7 +22,7 @@ import com.topjohnwu.magisk.model.events.dialog.ManagerInstallDialog
import com.topjohnwu.magisk.model.events.dialog.UninstallDialog import com.topjohnwu.magisk.model.events.dialog.UninstallDialog
import com.topjohnwu.magisk.model.navigation.Navigation import com.topjohnwu.magisk.model.navigation.Navigation
import com.topjohnwu.magisk.model.observer.Observer import com.topjohnwu.magisk.model.observer.Observer
import com.topjohnwu.magisk.ui.compat.CompatViewModel import com.topjohnwu.magisk.base.BaseViewModel
import com.topjohnwu.magisk.ui.compat.itemBindingOf import com.topjohnwu.magisk.ui.compat.itemBindingOf
import com.topjohnwu.magisk.utils.KObservableField import com.topjohnwu.magisk.utils.KObservableField
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
...@@ -35,7 +35,7 @@ enum class MagiskState { ...@@ -35,7 +35,7 @@ enum class MagiskState {
class HomeViewModel( class HomeViewModel(
private val repoMagisk: MagiskRepository private val repoMagisk: MagiskRepository
) : CompatViewModel() { ) : BaseViewModel() {
val isNoticeVisible = KObservableField(Config.safetyNotice) val isNoticeVisible = KObservableField(Config.safetyNotice)
......
...@@ -8,14 +8,14 @@ import com.topjohnwu.magisk.model.download.RemoteFileService ...@@ -8,14 +8,14 @@ import com.topjohnwu.magisk.model.download.RemoteFileService
import com.topjohnwu.magisk.model.entity.internal.Configuration import com.topjohnwu.magisk.model.entity.internal.Configuration
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
import com.topjohnwu.magisk.model.events.RequestFileEvent import com.topjohnwu.magisk.model.events.RequestFileEvent
import com.topjohnwu.magisk.ui.compat.CompatViewModel import com.topjohnwu.magisk.base.BaseViewModel
import com.topjohnwu.magisk.utils.KObservableField import com.topjohnwu.magisk.utils.KObservableField
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.ShellUtils import com.topjohnwu.superuser.ShellUtils
import org.koin.core.get import org.koin.core.get
import kotlin.math.roundToInt import kotlin.math.roundToInt
class InstallViewModel : CompatViewModel(State.LOADED) { class InstallViewModel : BaseViewModel(State.LOADED) {
val isRooted = Shell.rootAccess() val isRooted = Shell.rootAccess()
val isAB = isABDevice() val isAB = isABDevice()
......
...@@ -12,7 +12,7 @@ import com.topjohnwu.magisk.model.entity.recycler.ConsoleItem ...@@ -12,7 +12,7 @@ import com.topjohnwu.magisk.model.entity.recycler.ConsoleItem
import com.topjohnwu.magisk.model.entity.recycler.LogItem import com.topjohnwu.magisk.model.entity.recycler.LogItem
import com.topjohnwu.magisk.model.entity.recycler.TextItem import com.topjohnwu.magisk.model.entity.recycler.TextItem
import com.topjohnwu.magisk.model.events.SnackbarEvent import com.topjohnwu.magisk.model.events.SnackbarEvent
import com.topjohnwu.magisk.ui.compat.CompatViewModel import com.topjohnwu.magisk.base.BaseViewModel
import com.topjohnwu.magisk.ui.compat.diffListOf import com.topjohnwu.magisk.ui.compat.diffListOf
import com.topjohnwu.magisk.ui.compat.itemBindingOf import com.topjohnwu.magisk.ui.compat.itemBindingOf
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
...@@ -26,7 +26,7 @@ import java.util.* ...@@ -26,7 +26,7 @@ import java.util.*
class LogViewModel( class LogViewModel(
private val repo: LogRepository private val repo: LogRepository
) : CompatViewModel() { ) : BaseViewModel() {
// --- empty view // --- empty view
......
...@@ -6,6 +6,7 @@ import androidx.databinding.ObservableArrayList ...@@ -6,6 +6,7 @@ import androidx.databinding.ObservableArrayList
import com.topjohnwu.magisk.BR import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.Config import com.topjohnwu.magisk.Config
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.base.BaseViewModel
import com.topjohnwu.magisk.data.database.RepoByNameDao import com.topjohnwu.magisk.data.database.RepoByNameDao
import com.topjohnwu.magisk.data.database.RepoByUpdatedDao import com.topjohnwu.magisk.data.database.RepoByUpdatedDao
import com.topjohnwu.magisk.databinding.ComparableRvItem import com.topjohnwu.magisk.databinding.ComparableRvItem
...@@ -37,7 +38,7 @@ class ModuleViewModel( ...@@ -37,7 +38,7 @@ class ModuleViewModel(
private val repoName: RepoByNameDao, private val repoName: RepoByNameDao,
private val repoUpdated: RepoByUpdatedDao, private val repoUpdated: RepoByUpdatedDao,
private val repoUpdater: RepoUpdater private val repoUpdater: RepoUpdater
) : CompatViewModel(), Queryable by Queryable.impl(1000) { ) : BaseViewModel(), Queryable by Queryable.impl(1000) {
override val queryRunnable = Runnable { query() } override val queryRunnable = Runnable { query() }
......
package com.topjohnwu.magisk.ui.request package com.topjohnwu.magisk.ui.request
import com.topjohnwu.magisk.ui.compat.CompatViewModel import com.topjohnwu.magisk.base.BaseViewModel
class RequestViewModel : CompatViewModel() class RequestViewModel : BaseViewModel()
...@@ -6,7 +6,7 @@ import com.topjohnwu.magisk.R ...@@ -6,7 +6,7 @@ import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.extensions.subscribeK import com.topjohnwu.magisk.extensions.subscribeK
import com.topjohnwu.magisk.model.events.SafetyNetResult import com.topjohnwu.magisk.model.events.SafetyNetResult
import com.topjohnwu.magisk.model.events.UpdateSafetyNetEvent import com.topjohnwu.magisk.model.events.UpdateSafetyNetEvent
import com.topjohnwu.magisk.ui.compat.CompatViewModel import com.topjohnwu.magisk.base.BaseViewModel
import com.topjohnwu.magisk.ui.safetynet.SafetyNetState.* import com.topjohnwu.magisk.ui.safetynet.SafetyNetState.*
import com.topjohnwu.magisk.utils.KObservableField import com.topjohnwu.magisk.utils.KObservableField
import com.topjohnwu.magisk.utils.RxBus import com.topjohnwu.magisk.utils.RxBus
...@@ -18,7 +18,7 @@ enum class SafetyNetState { ...@@ -18,7 +18,7 @@ enum class SafetyNetState {
class SafetynetViewModel( class SafetynetViewModel(
rxBus: RxBus rxBus: RxBus
) : CompatViewModel() { ) : BaseViewModel() {
private var currentState = IDLE private var currentState = IDLE
set(value) { set(value) {
......
...@@ -15,7 +15,7 @@ import com.topjohnwu.magisk.model.events.PermissionEvent ...@@ -15,7 +15,7 @@ import com.topjohnwu.magisk.model.events.PermissionEvent
import com.topjohnwu.magisk.model.events.RecreateEvent import com.topjohnwu.magisk.model.events.RecreateEvent
import com.topjohnwu.magisk.model.events.dialog.BiometricDialog import com.topjohnwu.magisk.model.events.dialog.BiometricDialog
import com.topjohnwu.magisk.model.navigation.Navigation import com.topjohnwu.magisk.model.navigation.Navigation
import com.topjohnwu.magisk.ui.compat.CompatViewModel import com.topjohnwu.magisk.base.BaseViewModel
import com.topjohnwu.magisk.ui.compat.adapterOf import com.topjohnwu.magisk.ui.compat.adapterOf
import com.topjohnwu.magisk.ui.compat.diffListOf import com.topjohnwu.magisk.ui.compat.diffListOf
import com.topjohnwu.magisk.ui.compat.itemBindingOf import com.topjohnwu.magisk.ui.compat.itemBindingOf
...@@ -28,7 +28,7 @@ import org.koin.core.get ...@@ -28,7 +28,7 @@ import org.koin.core.get
class SettingsViewModel( class SettingsViewModel(
private val repositoryDao: RepoDao private val repositoryDao: RepoDao
) : CompatViewModel(), SettingsItem.Callback { ) : BaseViewModel(), SettingsItem.Callback {
val adapter = adapterOf<SettingsItem>() val adapter = adapterOf<SettingsItem>()
val itemBinding = itemBindingOf<SettingsItem> { it.bindExtra(BR.callback, this) } val itemBinding = itemBindingOf<SettingsItem> { it.bindExtra(BR.callback, this) }
......
...@@ -19,7 +19,7 @@ import com.topjohnwu.magisk.model.events.SnackbarEvent ...@@ -19,7 +19,7 @@ import com.topjohnwu.magisk.model.events.SnackbarEvent
import com.topjohnwu.magisk.model.events.dialog.BiometricDialog import com.topjohnwu.magisk.model.events.dialog.BiometricDialog
import com.topjohnwu.magisk.model.events.dialog.SuperuserRevokeDialog import com.topjohnwu.magisk.model.events.dialog.SuperuserRevokeDialog
import com.topjohnwu.magisk.model.navigation.Navigation import com.topjohnwu.magisk.model.navigation.Navigation
import com.topjohnwu.magisk.ui.compat.CompatViewModel import com.topjohnwu.magisk.base.BaseViewModel
import com.topjohnwu.magisk.ui.compat.adapterOf import com.topjohnwu.magisk.ui.compat.adapterOf
import com.topjohnwu.magisk.ui.compat.diffListOf import com.topjohnwu.magisk.ui.compat.diffListOf
import com.topjohnwu.magisk.ui.compat.itemBindingOf import com.topjohnwu.magisk.ui.compat.itemBindingOf
...@@ -32,7 +32,7 @@ class SuperuserViewModel( ...@@ -32,7 +32,7 @@ class SuperuserViewModel(
private val db: PolicyDao, private val db: PolicyDao,
private val packageManager: PackageManager, private val packageManager: PackageManager,
private val resources: Resources private val resources: Resources
) : CompatViewModel(), TappableHeadlineItem.Listener { ) : BaseViewModel(), TappableHeadlineItem.Listener {
private val itemNoData = TextItem(R.string.superuser_policy_none) private val itemNoData = TextItem(R.string.superuser_policy_none)
......
...@@ -3,9 +3,9 @@ package com.topjohnwu.magisk.ui.theme ...@@ -3,9 +3,9 @@ package com.topjohnwu.magisk.ui.theme
import com.topjohnwu.magisk.model.entity.recycler.TappableHeadlineItem import com.topjohnwu.magisk.model.entity.recycler.TappableHeadlineItem
import com.topjohnwu.magisk.model.events.RecreateEvent import com.topjohnwu.magisk.model.events.RecreateEvent
import com.topjohnwu.magisk.model.events.dialog.DarkThemeDialog import com.topjohnwu.magisk.model.events.dialog.DarkThemeDialog
import com.topjohnwu.magisk.ui.compat.CompatViewModel import com.topjohnwu.magisk.base.BaseViewModel
class ThemeViewModel : CompatViewModel(), TappableHeadlineItem.Listener { class ThemeViewModel : BaseViewModel(), TappableHeadlineItem.Listener {
val themeHeadline = TappableHeadlineItem.ThemeMode val themeHeadline = TappableHeadlineItem.ThemeMode
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment