mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-04-23 05:01:32 +00:00
Decouple state from BaseViewModel
This commit is contained in:
parent
aabc36f86b
commit
46d4708386
@ -4,17 +4,14 @@ import android.Manifest.permission.REQUEST_INSTALL_PACKAGES
|
|||||||
import android.Manifest.permission.WRITE_EXTERNAL_STORAGE
|
import android.Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.databinding.Bindable
|
|
||||||
import androidx.databinding.PropertyChangeRegistry
|
import androidx.databinding.PropertyChangeRegistry
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import androidx.navigation.NavDirections
|
import androidx.navigation.NavDirections
|
||||||
import com.topjohnwu.magisk.BR
|
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.databinding.ObservableHost
|
import com.topjohnwu.magisk.databinding.ObservableHost
|
||||||
import com.topjohnwu.magisk.databinding.set
|
|
||||||
import com.topjohnwu.magisk.events.BackPressEvent
|
import com.topjohnwu.magisk.events.BackPressEvent
|
||||||
import com.topjohnwu.magisk.events.NavigationEvent
|
import com.topjohnwu.magisk.events.NavigationEvent
|
||||||
import com.topjohnwu.magisk.events.PermissionEvent
|
import com.topjohnwu.magisk.events.PermissionEvent
|
||||||
@ -25,22 +22,8 @@ abstract class BaseViewModel : ViewModel(), ObservableHost {
|
|||||||
|
|
||||||
override var callbacks: PropertyChangeRegistry? = null
|
override var callbacks: PropertyChangeRegistry? = null
|
||||||
|
|
||||||
enum class State {
|
|
||||||
LOADED, LOADING, LOADING_FAILED
|
|
||||||
}
|
|
||||||
|
|
||||||
@get:Bindable
|
|
||||||
val loading get() = state == State.LOADING
|
|
||||||
@get:Bindable
|
|
||||||
val loaded get() = state == State.LOADED
|
|
||||||
@get:Bindable
|
|
||||||
val loadFailed get() = state == State.LOADING_FAILED
|
|
||||||
|
|
||||||
val viewEvents: LiveData<ViewEvent> get() = _viewEvents
|
val viewEvents: LiveData<ViewEvent> get() = _viewEvents
|
||||||
|
|
||||||
var state = State.LOADING
|
|
||||||
set(value) = set(value, field, { field = it }, BR.loading, BR.loaded, BR.loadFailed)
|
|
||||||
|
|
||||||
private val _viewEvents = MutableLiveData<ViewEvent>()
|
private val _viewEvents = MutableLiveData<ViewEvent>()
|
||||||
private var runningJob: Job? = null
|
private var runningJob: Job? = null
|
||||||
|
|
||||||
|
@ -2,14 +2,15 @@ package com.topjohnwu.magisk.ui.deny
|
|||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES
|
import android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES
|
||||||
|
import androidx.databinding.Bindable
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.topjohnwu.magisk.BR
|
import com.topjohnwu.magisk.BR
|
||||||
import com.topjohnwu.magisk.arch.BaseViewModel
|
import com.topjohnwu.magisk.arch.BaseViewModel
|
||||||
import com.topjohnwu.magisk.core.di.AppContext
|
import com.topjohnwu.magisk.core.di.AppContext
|
||||||
import com.topjohnwu.magisk.databinding.bindExtra
|
import com.topjohnwu.magisk.databinding.bindExtra
|
||||||
import com.topjohnwu.magisk.databinding.filterableListOf
|
import com.topjohnwu.magisk.databinding.filterableListOf
|
||||||
|
import com.topjohnwu.magisk.databinding.set
|
||||||
import com.topjohnwu.magisk.ktx.concurrentMap
|
import com.topjohnwu.magisk.ktx.concurrentMap
|
||||||
import com.topjohnwu.magisk.utils.Utils
|
|
||||||
import com.topjohnwu.superuser.Shell
|
import com.topjohnwu.superuser.Shell
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.asFlow
|
import kotlinx.coroutines.flow.asFlow
|
||||||
@ -43,13 +44,13 @@ class DenyListViewModel : BaseViewModel() {
|
|||||||
it.put(BR.viewModel, this)
|
it.put(BR.viewModel, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@get:Bindable
|
||||||
|
var loading = true
|
||||||
|
private set(value) = set(value, field, { field = it }, BR.loading)
|
||||||
|
|
||||||
@SuppressLint("InlinedApi")
|
@SuppressLint("InlinedApi")
|
||||||
override fun refresh() = viewModelScope.launch {
|
override fun refresh() = viewModelScope.launch {
|
||||||
if (!Utils.showSuperUser()) {
|
loading = true
|
||||||
state = State.LOADING_FAILED
|
|
||||||
return@launch
|
|
||||||
}
|
|
||||||
state = State.LOADING
|
|
||||||
val (apps, diff) = withContext(Dispatchers.Default) {
|
val (apps, diff) = withContext(Dispatchers.Default) {
|
||||||
val pm = AppContext.packageManager
|
val pm = AppContext.packageManager
|
||||||
val denyList = Shell.cmd("magisk --denylist ls").exec().out
|
val denyList = Shell.cmd("magisk --denylist ls").exec().out
|
||||||
@ -84,6 +85,6 @@ class DenyListViewModel : BaseViewModel() {
|
|||||||
|
|
||||||
(it.isChecked || (filterSystem() && filterOS())) && filterQuery()
|
(it.isChecked || (filterSystem() && filterOS())) && filterQuery()
|
||||||
}
|
}
|
||||||
state = State.LOADED
|
loading = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ class FlashFragment : BaseFragment<FragmentFlashMd2Binding>() {
|
|||||||
setHasOptionsMenu(true)
|
setHasOptionsMenu(true)
|
||||||
activity?.setTitle(R.string.flash_screen_title)
|
activity?.setTitle(R.string.flash_screen_title)
|
||||||
|
|
||||||
viewModel.flashState.observe(this) {
|
viewModel.state.observe(this) {
|
||||||
activity?.supportActionBar?.setSubtitle(
|
activity?.supportActionBar?.setSubtitle(
|
||||||
when (it) {
|
when (it) {
|
||||||
FlashViewModel.State.FLASHING -> R.string.flashing
|
FlashViewModel.State.FLASHING -> R.string.flashing
|
||||||
|
@ -32,9 +32,9 @@ class FlashViewModel : BaseViewModel() {
|
|||||||
FLASHING, SUCCESS, FAILED
|
FLASHING, SUCCESS, FAILED
|
||||||
}
|
}
|
||||||
|
|
||||||
private val _flashState = MutableLiveData(State.FLASHING)
|
private val _state = MutableLiveData(State.FLASHING)
|
||||||
val flashState: LiveData<State> get() = _flashState
|
val state: LiveData<State> get() = _state
|
||||||
val flashing = Transformations.map(flashState) { it == State.FLASHING }
|
val flashing = Transformations.map(state) { it == State.FLASHING }
|
||||||
|
|
||||||
@get:Bindable
|
@get:Bindable
|
||||||
var showReboot = Info.isRooted
|
var showReboot = Info.isRooted
|
||||||
@ -89,7 +89,7 @@ class FlashViewModel : BaseViewModel() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun onResult(success: Boolean) {
|
private fun onResult(success: Boolean) {
|
||||||
_flashState.value = if (success) State.SUCCESS else State.FAILED
|
_state.value = if (success) State.SUCCESS else State.FAILED
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onMenuItemClicked(item: MenuItem): Boolean {
|
fun onMenuItemClicked(item: MenuItem): Boolean {
|
||||||
|
@ -26,14 +26,14 @@ import com.topjohnwu.superuser.Shell
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
enum class MagiskState {
|
|
||||||
NOT_INSTALLED, UP_TO_DATE, OBSOLETE, LOADING
|
|
||||||
}
|
|
||||||
|
|
||||||
class HomeViewModel(
|
class HomeViewModel(
|
||||||
private val svc: NetworkService
|
private val svc: NetworkService
|
||||||
) : BaseViewModel() {
|
) : BaseViewModel() {
|
||||||
|
|
||||||
|
enum class State {
|
||||||
|
LOADING, INVALID, OUTDATED, UP_TO_DATE
|
||||||
|
}
|
||||||
|
|
||||||
val magiskTitleBarrierIds =
|
val magiskTitleBarrierIds =
|
||||||
intArrayOf(R.id.home_magisk_icon, R.id.home_magisk_title, R.id.home_magisk_button)
|
intArrayOf(R.id.home_magisk_icon, R.id.home_magisk_title, R.id.home_magisk_button)
|
||||||
val appTitleBarrierIds =
|
val appTitleBarrierIds =
|
||||||
@ -43,16 +43,16 @@ class HomeViewModel(
|
|||||||
var isNoticeVisible = Config.safetyNotice
|
var isNoticeVisible = Config.safetyNotice
|
||||||
set(value) = set(value, field, { field = it }, BR.noticeVisible)
|
set(value) = set(value, field, { field = it }, BR.noticeVisible)
|
||||||
|
|
||||||
val stateMagisk
|
val magiskState
|
||||||
get() = when {
|
get() = when {
|
||||||
!Info.env.isActive -> MagiskState.NOT_INSTALLED
|
!Info.env.isActive -> State.INVALID
|
||||||
Info.env.versionCode < BuildConfig.VERSION_CODE -> MagiskState.OBSOLETE
|
Info.env.versionCode < BuildConfig.VERSION_CODE -> State.OUTDATED
|
||||||
else -> MagiskState.UP_TO_DATE
|
else -> State.UP_TO_DATE
|
||||||
}
|
}
|
||||||
|
|
||||||
@get:Bindable
|
@get:Bindable
|
||||||
var stateManager = MagiskState.LOADING
|
var appState = State.LOADING
|
||||||
set(value) = set(value, field, { field = it }, BR.stateManager)
|
set(value) = set(value, field, { field = it }, BR.appState)
|
||||||
|
|
||||||
val magiskInstalledVersion
|
val magiskInstalledVersion
|
||||||
get() = Info.env.run {
|
get() = Info.env.run {
|
||||||
@ -84,13 +84,11 @@ class HomeViewModel(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun refresh() = viewModelScope.launch {
|
override fun refresh() = viewModelScope.launch {
|
||||||
state = State.LOADING
|
appState = State.LOADING
|
||||||
Info.getRemote(svc)?.apply {
|
Info.getRemote(svc)?.apply {
|
||||||
state = State.LOADED
|
appState = when {
|
||||||
|
BuildConfig.VERSION_CODE < magisk.versionCode -> State.OUTDATED
|
||||||
stateManager = when {
|
else -> State.UP_TO_DATE
|
||||||
BuildConfig.VERSION_CODE < magisk.versionCode -> MagiskState.OBSOLETE
|
|
||||||
else -> MagiskState.UP_TO_DATE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val isDebug = Config.updateChannel == Config.Value.DEBUG_CHANNEL
|
val isDebug = Config.updateChannel == Config.Value.DEBUG_CHANNEL
|
||||||
@ -98,7 +96,6 @@ class HomeViewModel(
|
|||||||
("${magisk.version} (${magisk.versionCode}) (${stub.versionCode})" +
|
("${magisk.version} (${magisk.versionCode}) (${stub.versionCode})" +
|
||||||
if (isDebug) " (D)" else "").asText()
|
if (isDebug) " (D)" else "").asText()
|
||||||
} ?: run {
|
} ?: run {
|
||||||
state = State.LOADING_FAILED
|
|
||||||
managerRemoteVersion = R.string.not_available.asText()
|
managerRemoteVersion = R.string.not_available.asText()
|
||||||
}
|
}
|
||||||
ensureEnv()
|
ensureEnv()
|
||||||
@ -119,14 +116,14 @@ class HomeViewModel(
|
|||||||
|
|
||||||
fun onDeletePressed() = UninstallDialog().publish()
|
fun onDeletePressed() = UninstallDialog().publish()
|
||||||
|
|
||||||
fun onManagerPressed() = when (state) {
|
fun onManagerPressed() = when (magiskState) {
|
||||||
State.LOADED -> withExternalRW {
|
State.LOADING -> SnackbarEvent(R.string.loading).publish()
|
||||||
|
State.INVALID -> SnackbarEvent(R.string.no_connection).publish()
|
||||||
|
else -> withExternalRW {
|
||||||
withInstallPermission {
|
withInstallPermission {
|
||||||
ManagerInstallDialog().publish()
|
ManagerInstallDialog().publish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
State.LOADING -> SnackbarEvent(R.string.loading).publish()
|
|
||||||
else -> SnackbarEvent(R.string.no_connection).publish()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onMagiskPressed() = withExternalRW {
|
fun onMagiskPressed() = withExternalRW {
|
||||||
@ -139,7 +136,7 @@ class HomeViewModel(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun ensureEnv() {
|
private suspend fun ensureEnv() {
|
||||||
if (MagiskState.NOT_INSTALLED == stateMagisk || checkedEnv) return
|
if (magiskState == State.INVALID || checkedEnv) return
|
||||||
val cmd = "env_check ${Info.env.versionString} ${Info.env.versionCode}"
|
val cmd = "env_check ${Info.env.versionString} ${Info.env.versionCode}"
|
||||||
if (!Shell.cmd(cmd).await().isSuccess) {
|
if (!Shell.cmd(cmd).await().isSuccess) {
|
||||||
EnvFixDialog(this).publish()
|
EnvFixDialog(this).publish()
|
||||||
|
@ -95,7 +95,6 @@ class InstallViewModel(
|
|||||||
R.id.method_inactive_slot -> FlashFragment.flash(true).navigate(true)
|
R.id.method_inactive_slot -> FlashFragment.flash(true).navigate(true)
|
||||||
else -> error("Unknown value")
|
else -> error("Unknown value")
|
||||||
}
|
}
|
||||||
state = State.LOADING
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSaveState(state: Bundle) {
|
override fun onSaveState(state: Bundle) {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.topjohnwu.magisk.ui.module
|
package com.topjohnwu.magisk.ui.module
|
||||||
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import androidx.databinding.Bindable
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.topjohnwu.magisk.BR
|
import com.topjohnwu.magisk.BR
|
||||||
@ -10,10 +11,7 @@ import com.topjohnwu.magisk.core.Info
|
|||||||
import com.topjohnwu.magisk.core.base.ContentResultCallback
|
import com.topjohnwu.magisk.core.base.ContentResultCallback
|
||||||
import com.topjohnwu.magisk.core.model.module.LocalModule
|
import com.topjohnwu.magisk.core.model.module.LocalModule
|
||||||
import com.topjohnwu.magisk.core.model.module.OnlineModule
|
import com.topjohnwu.magisk.core.model.module.OnlineModule
|
||||||
import com.topjohnwu.magisk.databinding.MergeObservableList
|
import com.topjohnwu.magisk.databinding.*
|
||||||
import com.topjohnwu.magisk.databinding.RvItem
|
|
||||||
import com.topjohnwu.magisk.databinding.bindExtra
|
|
||||||
import com.topjohnwu.magisk.databinding.diffListOf
|
|
||||||
import com.topjohnwu.magisk.events.GetContentEvent
|
import com.topjohnwu.magisk.events.GetContentEvent
|
||||||
import com.topjohnwu.magisk.events.SnackbarEvent
|
import com.topjohnwu.magisk.events.SnackbarEvent
|
||||||
import com.topjohnwu.magisk.events.dialog.ModuleInstallDialog
|
import com.topjohnwu.magisk.events.dialog.ModuleInstallDialog
|
||||||
@ -36,6 +34,10 @@ class ModuleViewModel : BaseViewModel() {
|
|||||||
|
|
||||||
val data get() = uri
|
val data get() = uri
|
||||||
|
|
||||||
|
@get:Bindable
|
||||||
|
var loading = true
|
||||||
|
private set(value) = set(value, field, { field = it }, BR.loading)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if (Info.env.isActive && LocalModule.loaded()) {
|
if (Info.env.isActive && LocalModule.loaded()) {
|
||||||
items.insertItem(InstallModule)
|
items.insertItem(InstallModule)
|
||||||
@ -45,9 +47,9 @@ class ModuleViewModel : BaseViewModel() {
|
|||||||
|
|
||||||
override fun refresh(): Job {
|
override fun refresh(): Job {
|
||||||
return viewModelScope.launch {
|
return viewModelScope.launch {
|
||||||
state = State.LOADING
|
loading = true
|
||||||
loadInstalled()
|
loadInstalled()
|
||||||
state = State.LOADED
|
loading = false
|
||||||
loadUpdateInfo()
|
loadUpdateInfo()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import android.annotation.SuppressLint
|
|||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES
|
import android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES
|
||||||
import android.os.Process
|
import android.os.Process
|
||||||
|
import androidx.databinding.Bindable
|
||||||
import androidx.databinding.ObservableArrayList
|
import androidx.databinding.ObservableArrayList
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.topjohnwu.magisk.BR
|
import com.topjohnwu.magisk.BR
|
||||||
@ -14,10 +15,7 @@ import com.topjohnwu.magisk.core.di.AppContext
|
|||||||
import com.topjohnwu.magisk.core.model.su.SuPolicy
|
import com.topjohnwu.magisk.core.model.su.SuPolicy
|
||||||
import com.topjohnwu.magisk.core.utils.BiometricHelper
|
import com.topjohnwu.magisk.core.utils.BiometricHelper
|
||||||
import com.topjohnwu.magisk.core.utils.currentLocale
|
import com.topjohnwu.magisk.core.utils.currentLocale
|
||||||
import com.topjohnwu.magisk.databinding.AnyDiffRvItem
|
import com.topjohnwu.magisk.databinding.*
|
||||||
import com.topjohnwu.magisk.databinding.MergeObservableList
|
|
||||||
import com.topjohnwu.magisk.databinding.bindExtra
|
|
||||||
import com.topjohnwu.magisk.databinding.diffListOf
|
|
||||||
import com.topjohnwu.magisk.events.SnackbarEvent
|
import com.topjohnwu.magisk.events.SnackbarEvent
|
||||||
import com.topjohnwu.magisk.events.dialog.BiometricEvent
|
import com.topjohnwu.magisk.events.dialog.BiometricEvent
|
||||||
import com.topjohnwu.magisk.events.dialog.SuperuserRevokeDialog
|
import com.topjohnwu.magisk.events.dialog.SuperuserRevokeDialog
|
||||||
@ -45,15 +43,17 @@ class SuperuserViewModel(
|
|||||||
it.put(BR.listener, this)
|
it.put(BR.listener, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---
|
@get:Bindable
|
||||||
|
var loading = true
|
||||||
|
private set(value) = set(value, field, { field = it }, BR.loading)
|
||||||
|
|
||||||
@SuppressLint("InlinedApi")
|
@SuppressLint("InlinedApi")
|
||||||
override fun refresh() = viewModelScope.launch {
|
override fun refresh() = viewModelScope.launch {
|
||||||
if (!Utils.showSuperUser()) {
|
if (!Utils.showSuperUser()) {
|
||||||
state = State.LOADING_FAILED
|
loading = false
|
||||||
return@launch
|
return@launch
|
||||||
}
|
}
|
||||||
state = State.LOADING
|
loading = true
|
||||||
val (policies, diff) = withContext(Dispatchers.IO) {
|
val (policies, diff) = withContext(Dispatchers.IO) {
|
||||||
db.deleteOutdated()
|
db.deleteOutdated()
|
||||||
db.delete(AppContext.applicationInfo.uid)
|
db.delete(AppContext.applicationInfo.uid)
|
||||||
@ -98,7 +98,7 @@ class SuperuserViewModel(
|
|||||||
itemsHelpers.clear()
|
itemsHelpers.clear()
|
||||||
else if (itemsHelpers.isEmpty())
|
else if (itemsHelpers.isEmpty())
|
||||||
itemsHelpers.add(itemNoData)
|
itemsHelpers.add(itemNoData)
|
||||||
state = State.LOADED
|
loading = false
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---
|
// ---
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
android:paddingTop="@dimen/internal_action_bar_size"
|
android:paddingTop="@dimen/internal_action_bar_size"
|
||||||
app:fitsSystemWindowsInsets="top|bottom"
|
app:fitsSystemWindowsInsets="top|bottom"
|
||||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||||
app:invisibleUnless="@{viewModel.loaded}"
|
app:invisible="@{viewModel.loading}"
|
||||||
app:items="@{viewModel.items}"
|
app:items="@{viewModel.items}"
|
||||||
app:extraBindings="@{viewModel.extraBindings}"
|
app:extraBindings="@{viewModel.extraBindings}"
|
||||||
tools:listitem="@layout/item_hide_md2"
|
tools:listitem="@layout/item_hide_md2"
|
||||||
@ -52,24 +52,6 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
goneUnless="@{viewModel.loadFailed}"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:gravity="center"
|
|
||||||
android:orientation="vertical"
|
|
||||||
tools:visibility="gone">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/not_available"
|
|
||||||
android:textAppearance="@style/AppearanceFoundation.Title"
|
|
||||||
android:textStyle="bold" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
</layout>
|
</layout>
|
||||||
|
@ -7,8 +7,6 @@
|
|||||||
|
|
||||||
<import type="com.topjohnwu.magisk.core.Info" />
|
<import type="com.topjohnwu.magisk.core.Info" />
|
||||||
|
|
||||||
<import type="com.topjohnwu.magisk.ui.home.MagiskState" />
|
|
||||||
|
|
||||||
<import type="com.topjohnwu.magisk.ui.home.DeveloperItem" />
|
<import type="com.topjohnwu.magisk.ui.home.DeveloperItem" />
|
||||||
|
|
||||||
<import type="com.topjohnwu.magisk.ui.home.IconLink" />
|
<import type="com.topjohnwu.magisk.ui.home.IconLink" />
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/superuser_list"
|
android:id="@+id/superuser_list"
|
||||||
goneUnless="@{viewModel.loaded || !viewModel.items.empty}"
|
gone="@{viewModel.loading}"
|
||||||
app:items="@{viewModel.items}"
|
app:items="@{viewModel.items}"
|
||||||
app:extraBindings="@{viewModel.extraBindings}"
|
app:extraBindings="@{viewModel.extraBindings}"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@ -33,7 +33,7 @@
|
|||||||
tools:listitem="@layout/item_policy_md2" />
|
tools:listitem="@layout/item_policy_md2" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
goneUnless="@{viewModel.loading && viewModel.items.empty}"
|
goneUnless="@{viewModel.loading}"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
@ -54,24 +54,6 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
goneUnless="@{viewModel.loadFailed}"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:gravity="center"
|
|
||||||
android:orientation="vertical"
|
|
||||||
tools:visibility="gone">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/not_available"
|
|
||||||
android:textAppearance="@style/AppearanceFoundation.Title"
|
|
||||||
android:textStyle="bold" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
</layout>
|
</layout>
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
<import type="com.topjohnwu.magisk.core.Info" />
|
<import type="com.topjohnwu.magisk.core.Info" />
|
||||||
|
|
||||||
<import type="com.topjohnwu.magisk.ui.home.MagiskState" />
|
<import type="com.topjohnwu.magisk.ui.home.HomeViewModel.State" />
|
||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="viewModel"
|
name="viewModel"
|
||||||
@ -63,7 +63,7 @@
|
|||||||
|
|
||||||
<Button
|
<Button
|
||||||
style="@style/WidgetFoundation.Button"
|
style="@style/WidgetFoundation.Button"
|
||||||
gone="@{viewModel.stateMagisk != MagiskState.OBSOLETE}"
|
gone="@{viewModel.magiskState != State.OUTDATED}"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:onClick="@{() -> viewModel.onMagiskPressed()}"
|
android:onClick="@{() -> viewModel.onMagiskPressed()}"
|
||||||
@ -74,7 +74,7 @@
|
|||||||
|
|
||||||
<Button
|
<Button
|
||||||
style="@style/WidgetFoundation.Button.Text"
|
style="@style/WidgetFoundation.Button.Text"
|
||||||
gone="@{viewModel.stateMagisk == MagiskState.OBSOLETE}"
|
gone="@{viewModel.magiskState == State.OUTDATED}"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="end"
|
android:layout_gravity="end"
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
<import type="com.topjohnwu.magisk.core.Info" />
|
<import type="com.topjohnwu.magisk.core.Info" />
|
||||||
|
|
||||||
<import type="com.topjohnwu.magisk.ui.home.MagiskState" />
|
<import type="com.topjohnwu.magisk.ui.home.HomeViewModel.State" />
|
||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="viewModel"
|
name="viewModel"
|
||||||
@ -64,7 +64,7 @@
|
|||||||
|
|
||||||
<Button
|
<Button
|
||||||
style="@style/WidgetFoundation.Button"
|
style="@style/WidgetFoundation.Button"
|
||||||
gone="@{viewModel.stateManager != MagiskState.OBSOLETE}"
|
gone="@{viewModel.appState != State.OUTDATED}"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:onClick="@{() -> viewModel.onManagerPressed()}"
|
android:onClick="@{() -> viewModel.onManagerPressed()}"
|
||||||
@ -75,7 +75,7 @@
|
|||||||
|
|
||||||
<Button
|
<Button
|
||||||
style="@style/WidgetFoundation.Button.Text"
|
style="@style/WidgetFoundation.Button.Text"
|
||||||
gone="@{viewModel.stateManager != MagiskState.UP_TO_DATE}"
|
gone="@{viewModel.appState != State.UP_TO_DATE}"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="end"
|
android:layout_gravity="end"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user