Added empty states for all remaining screens
Fixed some issues in the process as the MergeObservableList doesn't support additions or deletions, duh...
This commit is contained in:
parent
7342509b2e
commit
904948dc7d
@ -10,6 +10,7 @@ import com.topjohnwu.magisk.extensions.subscribeK
|
||||
import com.topjohnwu.magisk.model.binding.BindingAdapter
|
||||
import com.topjohnwu.magisk.model.entity.recycler.ConsoleItem
|
||||
import com.topjohnwu.magisk.model.entity.recycler.LogItem
|
||||
import com.topjohnwu.magisk.model.entity.recycler.TextItem
|
||||
import com.topjohnwu.magisk.model.events.SnackbarEvent
|
||||
import com.topjohnwu.magisk.redesign.compat.CompatViewModel
|
||||
import com.topjohnwu.magisk.redesign.compat.diffListOf
|
||||
@ -27,6 +28,11 @@ class LogViewModel(
|
||||
private val repo: LogRepository
|
||||
) : CompatViewModel() {
|
||||
|
||||
// --- empty view
|
||||
|
||||
val itemEmpty = TextItem(R.string.log_data_none)
|
||||
val itemMagiskEmpty = TextItem(R.string.log_data_magisk_none)
|
||||
|
||||
// --- main view
|
||||
|
||||
val items = diffListOf<LogItem>()
|
||||
|
@ -2,6 +2,7 @@ package com.topjohnwu.magisk.redesign.module
|
||||
|
||||
import androidx.annotation.WorkerThread
|
||||
import androidx.databinding.Bindable
|
||||
import androidx.databinding.ObservableArrayList
|
||||
import com.topjohnwu.magisk.BR
|
||||
import com.topjohnwu.magisk.Config
|
||||
import com.topjohnwu.magisk.R
|
||||
@ -61,6 +62,13 @@ class ModuleViewModel(
|
||||
private val itemNoneInstalled = TextItem(R.string.module_install_none)
|
||||
private val itemNoneUpdatable = TextItem(R.string.module_update_none)
|
||||
|
||||
private val itemsInstalledHelpers = ObservableArrayList<TextItem>().also {
|
||||
it.add(itemNoneInstalled)
|
||||
}
|
||||
private val itemsUpdatableHelpers = ObservableArrayList<TextItem>().also {
|
||||
it.add(itemNoneUpdatable)
|
||||
}
|
||||
|
||||
private val itemsInstalled = diffListOf<ModuleItem>()
|
||||
private val itemsUpdatable = diffListOf<RepoItem.Update>()
|
||||
private val itemsRemote = diffListOf<RepoItem.Remote>()
|
||||
@ -68,11 +76,11 @@ class ModuleViewModel(
|
||||
val adapter = adapterOf<ComparableRvItem<*>>()
|
||||
val items = MergeObservableList<ComparableRvItem<*>>()
|
||||
.insertItem(sectionActive)
|
||||
.insertItem(itemNoneInstalled)
|
||||
.insertList(itemsInstalledHelpers)
|
||||
.insertList(itemsInstalled)
|
||||
.insertItem(InstallModule)
|
||||
.insertItem(sectionUpdate)
|
||||
.insertItem(itemNoneUpdatable)
|
||||
.insertList(itemsUpdatableHelpers)
|
||||
.insertList(itemsUpdatable)
|
||||
.insertItem(sectionRemote)
|
||||
.insertList(itemsRemote)!!
|
||||
@ -155,13 +163,17 @@ class ModuleViewModel(
|
||||
.applyViewModel(this)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.doOnSuccess { itemsInstalled.update(it.first, it.second) }
|
||||
.doOnSuccess { if (itemsInstalled.isNotEmpty()) items.remove(itemNoneInstalled) }
|
||||
.doOnSuccess {
|
||||
if (itemsInstalled.isNotEmpty()) itemsInstalledHelpers.remove(itemNoneInstalled)
|
||||
}
|
||||
.observeOn(Schedulers.io())
|
||||
.map { loadUpdates(it.first) }
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.map { it to itemsUpdatable.calculateDiff(it) }
|
||||
.doOnSuccess { itemsUpdatable.update(it.first, it.second) }
|
||||
.doOnSuccess { if (itemsUpdatable.isNotEmpty()) items.remove(itemNoneUpdatable) }
|
||||
.doOnSuccess {
|
||||
if (itemsUpdatable.isNotEmpty()) itemsUpdatableHelpers.remove(itemNoneUpdatable)
|
||||
}
|
||||
.ignoreElement()!!
|
||||
|
||||
fun loadRemoteImplicit() = let { itemsRemote.clear(); itemsSearch.clear() }
|
||||
|
@ -2,6 +2,7 @@ package com.topjohnwu.magisk.redesign.superuser
|
||||
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.res.Resources
|
||||
import androidx.databinding.ObservableArrayList
|
||||
import com.topjohnwu.magisk.BR
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.data.database.PolicyDao
|
||||
@ -12,17 +13,20 @@ import com.topjohnwu.magisk.extensions.toggle
|
||||
import com.topjohnwu.magisk.model.entity.MagiskPolicy
|
||||
import com.topjohnwu.magisk.model.entity.recycler.PolicyItem
|
||||
import com.topjohnwu.magisk.model.entity.recycler.TappableHeadlineItem
|
||||
import com.topjohnwu.magisk.model.entity.recycler.TextItem
|
||||
import com.topjohnwu.magisk.model.events.PolicyUpdateEvent
|
||||
import com.topjohnwu.magisk.model.events.SnackbarEvent
|
||||
import com.topjohnwu.magisk.model.events.dialog.BiometricDialog
|
||||
import com.topjohnwu.magisk.model.events.dialog.SuperuserRevokeDialog
|
||||
import com.topjohnwu.magisk.model.navigation.Navigation
|
||||
import com.topjohnwu.magisk.redesign.compat.CompatViewModel
|
||||
import com.topjohnwu.magisk.redesign.compat.adapterOf
|
||||
import com.topjohnwu.magisk.redesign.compat.diffListOf
|
||||
import com.topjohnwu.magisk.redesign.compat.itemBindingOf
|
||||
import com.topjohnwu.magisk.utils.BiometricHelper
|
||||
import com.topjohnwu.magisk.utils.currentLocale
|
||||
import io.reactivex.Single
|
||||
import me.tatarka.bindingcollectionadapter2.collections.MergeObservableList
|
||||
|
||||
class SuperuserViewModel(
|
||||
private val db: PolicyDao,
|
||||
@ -30,19 +34,24 @@ class SuperuserViewModel(
|
||||
private val resources: Resources
|
||||
) : CompatViewModel(), TappableHeadlineItem.Listener {
|
||||
|
||||
val items = diffListOf<ComparableRvItem<*>>()
|
||||
private val itemNoData = TextItem(R.string.superuser_policy_none)
|
||||
|
||||
private val itemsPolicies = diffListOf<PolicyItem>()
|
||||
private val itemsHelpers = ObservableArrayList<TextItem>().also {
|
||||
it.add(itemNoData)
|
||||
}
|
||||
|
||||
val adapter = adapterOf<ComparableRvItem<*>>()
|
||||
val items = MergeObservableList<ComparableRvItem<*>>()
|
||||
.insertItem(TappableHeadlineItem.Hide)
|
||||
.insertItem(TappableHeadlineItem.Safetynet)
|
||||
.insertList(itemsHelpers)
|
||||
.insertList(itemsPolicies)
|
||||
val itemBinding = itemBindingOf<ComparableRvItem<*>> {
|
||||
it.bindExtra(BR.viewModel, this)
|
||||
it.bindExtra(BR.listener, this)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val menuOptions = listOf(
|
||||
TappableHeadlineItem.Hide,
|
||||
TappableHeadlineItem.Safetynet
|
||||
)
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
override fun refresh() = db.fetchAll()
|
||||
@ -57,11 +66,15 @@ class SuperuserViewModel(
|
||||
).compare(o1, o2)
|
||||
}
|
||||
.toList()
|
||||
.map { menuOptions + it }
|
||||
.map { it to items.calculateDiff(it) }
|
||||
.map { it to itemsPolicies.calculateDiff(it) }
|
||||
.applySchedulers()
|
||||
.applyViewModel(this)
|
||||
.subscribeK { items.update(it.first, it.second) }
|
||||
.subscribeK {
|
||||
itemsPolicies.update(it.first, it.second)
|
||||
if (itemsPolicies.isNotEmpty()) {
|
||||
itemsHelpers.remove(itemNoData)
|
||||
}
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
@ -77,7 +90,12 @@ class SuperuserViewModel(
|
||||
|
||||
fun deletePressed(item: PolicyItem) {
|
||||
fun updateState() = deletePolicy(item.item)
|
||||
.subscribeK { items.removeAll { it.genericItemSameAs(item) } }
|
||||
.subscribeK {
|
||||
itemsPolicies.removeAll { it.genericItemSameAs(item) }
|
||||
if (itemsPolicies.isEmpty() && itemsHelpers.isEmpty()) {
|
||||
itemsHelpers.add(itemNoData)
|
||||
}
|
||||
}
|
||||
.add()
|
||||
|
||||
if (BiometricHelper.isEnabled) {
|
||||
|
@ -61,6 +61,20 @@
|
||||
|
||||
</com.google.android.material.circularreveal.cardview.CircularRevealCardView>
|
||||
|
||||
<FrameLayout
|
||||
gone="@{!viewModel.items.empty}"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center">
|
||||
|
||||
<include
|
||||
item="@{viewModel.itemEmpty}"
|
||||
layout="@layout/item_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</layout>
|
@ -18,6 +18,8 @@
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/superuser_list"
|
||||
adapter="@{viewModel.adapter}"
|
||||
dividerHorizontal="@{R.drawable.divider_l1}"
|
||||
dividerVertical="@{R.drawable.divider_l1}"
|
||||
goneUnless="@{viewModel.loaded || !viewModel.items.empty}"
|
||||
@ -25,7 +27,6 @@
|
||||
items="@{viewModel.items}"
|
||||
nestedScrollingEnabled="@{false}"
|
||||
android:layout_width="match_parent"
|
||||
android:id="@+id/superuser_list"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical"
|
||||
|
@ -11,24 +11,44 @@
|
||||
|
||||
</data>
|
||||
|
||||
<HorizontalScrollView
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
adapter="@{viewModel.consoleAdapter}"
|
||||
itemBinding="@{viewModel.itemConsoleBinding}"
|
||||
items="@{viewModel.itemsConsole}"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="@{viewModel.insets.top + (int) @dimen/internal_action_bar_size}"
|
||||
android:paddingBottom="@{viewModel.insets.bottom}"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
tools:listitem="@layout/item_console"
|
||||
tools:paddingTop="24dp" />
|
||||
<HorizontalScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
</HorizontalScrollView>
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
adapter="@{viewModel.consoleAdapter}"
|
||||
itemBinding="@{viewModel.itemConsoleBinding}"
|
||||
items="@{viewModel.itemsConsole}"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="@{viewModel.insets.top + (int) @dimen/internal_action_bar_size}"
|
||||
android:paddingBottom="@{viewModel.insets.bottom}"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
tools:listitem="@layout/item_console"
|
||||
tools:paddingTop="24dp" />
|
||||
|
||||
</HorizontalScrollView>
|
||||
|
||||
<FrameLayout
|
||||
gone="@{!viewModel.itemsConsole.empty}"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center">
|
||||
|
||||
<include
|
||||
item="@{viewModel.itemMagiskEmpty}"
|
||||
layout="@layout/item_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</layout>
|
@ -91,10 +91,14 @@
|
||||
<string name="superuser_toggle_log">Logs</string>
|
||||
<string name="superuser_toggle_notification">Notifications</string>
|
||||
<string name="superuser_toggle_revoke">Revoke</string>
|
||||
<string name="superuser_policy_none">No app has asked for superuser permission yet.</string>
|
||||
|
||||
<string name="hide_filter_hint">Filter by name</string>
|
||||
<string name="hide_scroll_up">Scroll up</string>
|
||||
<string name="hide_filters">Filters</string>
|
||||
<string name="hide_search">Search</string>
|
||||
|
||||
<string name="log_data_none">You\'re log-free, try using your SU enabled apps more.</string>
|
||||
<string name="log_data_magisk_none">Magisk logs are empty, that\'s weird.</string>
|
||||
|
||||
</resources>
|
Loading…
Reference in New Issue
Block a user