Commit 904948dc authored by Viktor De Pasquale's avatar Viktor De Pasquale

Added empty states for all remaining screens

Fixed some issues in the process as the MergeObservableList doesn't support additions or deletions, duh...
parent 7342509b
...@@ -10,6 +10,7 @@ import com.topjohnwu.magisk.extensions.subscribeK ...@@ -10,6 +10,7 @@ import com.topjohnwu.magisk.extensions.subscribeK
import com.topjohnwu.magisk.model.binding.BindingAdapter import com.topjohnwu.magisk.model.binding.BindingAdapter
import com.topjohnwu.magisk.model.entity.recycler.ConsoleItem 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.events.SnackbarEvent import com.topjohnwu.magisk.model.events.SnackbarEvent
import com.topjohnwu.magisk.redesign.compat.CompatViewModel import com.topjohnwu.magisk.redesign.compat.CompatViewModel
import com.topjohnwu.magisk.redesign.compat.diffListOf import com.topjohnwu.magisk.redesign.compat.diffListOf
...@@ -27,6 +28,11 @@ class LogViewModel( ...@@ -27,6 +28,11 @@ class LogViewModel(
private val repo: LogRepository private val repo: LogRepository
) : CompatViewModel() { ) : CompatViewModel() {
// --- empty view
val itemEmpty = TextItem(R.string.log_data_none)
val itemMagiskEmpty = TextItem(R.string.log_data_magisk_none)
// --- main view // --- main view
val items = diffListOf<LogItem>() val items = diffListOf<LogItem>()
......
...@@ -2,6 +2,7 @@ package com.topjohnwu.magisk.redesign.module ...@@ -2,6 +2,7 @@ package com.topjohnwu.magisk.redesign.module
import androidx.annotation.WorkerThread import androidx.annotation.WorkerThread
import androidx.databinding.Bindable import androidx.databinding.Bindable
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
...@@ -61,6 +62,13 @@ class ModuleViewModel( ...@@ -61,6 +62,13 @@ class ModuleViewModel(
private val itemNoneInstalled = TextItem(R.string.module_install_none) private val itemNoneInstalled = TextItem(R.string.module_install_none)
private val itemNoneUpdatable = TextItem(R.string.module_update_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 itemsInstalled = diffListOf<ModuleItem>()
private val itemsUpdatable = diffListOf<RepoItem.Update>() private val itemsUpdatable = diffListOf<RepoItem.Update>()
private val itemsRemote = diffListOf<RepoItem.Remote>() private val itemsRemote = diffListOf<RepoItem.Remote>()
...@@ -68,11 +76,11 @@ class ModuleViewModel( ...@@ -68,11 +76,11 @@ class ModuleViewModel(
val adapter = adapterOf<ComparableRvItem<*>>() val adapter = adapterOf<ComparableRvItem<*>>()
val items = MergeObservableList<ComparableRvItem<*>>() val items = MergeObservableList<ComparableRvItem<*>>()
.insertItem(sectionActive) .insertItem(sectionActive)
.insertItem(itemNoneInstalled) .insertList(itemsInstalledHelpers)
.insertList(itemsInstalled) .insertList(itemsInstalled)
.insertItem(InstallModule) .insertItem(InstallModule)
.insertItem(sectionUpdate) .insertItem(sectionUpdate)
.insertItem(itemNoneUpdatable) .insertList(itemsUpdatableHelpers)
.insertList(itemsUpdatable) .insertList(itemsUpdatable)
.insertItem(sectionRemote) .insertItem(sectionRemote)
.insertList(itemsRemote)!! .insertList(itemsRemote)!!
...@@ -155,13 +163,17 @@ class ModuleViewModel( ...@@ -155,13 +163,17 @@ class ModuleViewModel(
.applyViewModel(this) .applyViewModel(this)
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.doOnSuccess { itemsInstalled.update(it.first, it.second) } .doOnSuccess { itemsInstalled.update(it.first, it.second) }
.doOnSuccess { if (itemsInstalled.isNotEmpty()) items.remove(itemNoneInstalled) } .doOnSuccess {
if (itemsInstalled.isNotEmpty()) itemsInstalledHelpers.remove(itemNoneInstalled)
}
.observeOn(Schedulers.io()) .observeOn(Schedulers.io())
.map { loadUpdates(it.first) } .map { loadUpdates(it.first) }
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.map { it to itemsUpdatable.calculateDiff(it) } .map { it to itemsUpdatable.calculateDiff(it) }
.doOnSuccess { itemsUpdatable.update(it.first, it.second) } .doOnSuccess { itemsUpdatable.update(it.first, it.second) }
.doOnSuccess { if (itemsUpdatable.isNotEmpty()) items.remove(itemNoneUpdatable) } .doOnSuccess {
if (itemsUpdatable.isNotEmpty()) itemsUpdatableHelpers.remove(itemNoneUpdatable)
}
.ignoreElement()!! .ignoreElement()!!
fun loadRemoteImplicit() = let { itemsRemote.clear(); itemsSearch.clear() } fun loadRemoteImplicit() = let { itemsRemote.clear(); itemsSearch.clear() }
......
...@@ -2,6 +2,7 @@ package com.topjohnwu.magisk.redesign.superuser ...@@ -2,6 +2,7 @@ package com.topjohnwu.magisk.redesign.superuser
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.content.res.Resources import android.content.res.Resources
import androidx.databinding.ObservableArrayList
import com.topjohnwu.magisk.BR import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.data.database.PolicyDao import com.topjohnwu.magisk.data.database.PolicyDao
...@@ -12,17 +13,20 @@ import com.topjohnwu.magisk.extensions.toggle ...@@ -12,17 +13,20 @@ import com.topjohnwu.magisk.extensions.toggle
import com.topjohnwu.magisk.model.entity.MagiskPolicy import com.topjohnwu.magisk.model.entity.MagiskPolicy
import com.topjohnwu.magisk.model.entity.recycler.PolicyItem import com.topjohnwu.magisk.model.entity.recycler.PolicyItem
import com.topjohnwu.magisk.model.entity.recycler.TappableHeadlineItem 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.PolicyUpdateEvent
import com.topjohnwu.magisk.model.events.SnackbarEvent 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.redesign.compat.CompatViewModel 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.diffListOf
import com.topjohnwu.magisk.redesign.compat.itemBindingOf import com.topjohnwu.magisk.redesign.compat.itemBindingOf
import com.topjohnwu.magisk.utils.BiometricHelper import com.topjohnwu.magisk.utils.BiometricHelper
import com.topjohnwu.magisk.utils.currentLocale import com.topjohnwu.magisk.utils.currentLocale
import io.reactivex.Single import io.reactivex.Single
import me.tatarka.bindingcollectionadapter2.collections.MergeObservableList
class SuperuserViewModel( class SuperuserViewModel(
private val db: PolicyDao, private val db: PolicyDao,
...@@ -30,19 +34,24 @@ class SuperuserViewModel( ...@@ -30,19 +34,24 @@ class SuperuserViewModel(
private val resources: Resources private val resources: Resources
) : CompatViewModel(), TappableHeadlineItem.Listener { ) : 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<*>> { val itemBinding = itemBindingOf<ComparableRvItem<*>> {
it.bindExtra(BR.viewModel, this) it.bindExtra(BR.viewModel, this)
it.bindExtra(BR.listener, this) it.bindExtra(BR.listener, this)
} }
companion object {
private val menuOptions = listOf(
TappableHeadlineItem.Hide,
TappableHeadlineItem.Safetynet
)
}
// --- // ---
override fun refresh() = db.fetchAll() override fun refresh() = db.fetchAll()
...@@ -57,11 +66,15 @@ class SuperuserViewModel( ...@@ -57,11 +66,15 @@ class SuperuserViewModel(
).compare(o1, o2) ).compare(o1, o2)
} }
.toList() .toList()
.map { menuOptions + it } .map { it to itemsPolicies.calculateDiff(it) }
.map { it to items.calculateDiff(it) }
.applySchedulers() .applySchedulers()
.applyViewModel(this) .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( ...@@ -77,7 +90,12 @@ class SuperuserViewModel(
fun deletePressed(item: PolicyItem) { fun deletePressed(item: PolicyItem) {
fun updateState() = deletePolicy(item.item) 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() .add()
if (BiometricHelper.isEnabled) { if (BiometricHelper.isEnabled) {
......
...@@ -61,6 +61,20 @@ ...@@ -61,6 +61,20 @@
</com.google.android.material.circularreveal.cardview.CircularRevealCardView> </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> </FrameLayout>
</layout> </layout>
\ No newline at end of file
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
android:layout_height="match_parent"> android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/superuser_list"
adapter="@{viewModel.adapter}"
dividerHorizontal="@{R.drawable.divider_l1}" dividerHorizontal="@{R.drawable.divider_l1}"
dividerVertical="@{R.drawable.divider_l1}" dividerVertical="@{R.drawable.divider_l1}"
goneUnless="@{viewModel.loaded || !viewModel.items.empty}" goneUnless="@{viewModel.loaded || !viewModel.items.empty}"
...@@ -25,7 +27,6 @@ ...@@ -25,7 +27,6 @@
items="@{viewModel.items}" items="@{viewModel.items}"
nestedScrollingEnabled="@{false}" nestedScrollingEnabled="@{false}"
android:layout_width="match_parent" android:layout_width="match_parent"
android:id="@+id/superuser_list"
android:layout_height="match_parent" android:layout_height="match_parent"
android:clipToPadding="false" android:clipToPadding="false"
android:orientation="vertical" android:orientation="vertical"
......
...@@ -11,24 +11,44 @@ ...@@ -11,24 +11,44 @@
</data> </data>
<HorizontalScrollView <FrameLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView <HorizontalScrollView
adapter="@{viewModel.consoleAdapter}" android:layout_width="match_parent"
itemBinding="@{viewModel.itemConsoleBinding}" android:layout_height="match_parent">
items="@{viewModel.itemsConsole}"
android:layout_width="wrap_content" <androidx.recyclerview.widget.RecyclerView
android:layout_height="match_parent" adapter="@{viewModel.consoleAdapter}"
android:clipToPadding="false" itemBinding="@{viewModel.itemConsoleBinding}"
android:orientation="vertical" items="@{viewModel.itemsConsole}"
android:paddingTop="@{viewModel.insets.top + (int) @dimen/internal_action_bar_size}" android:layout_width="wrap_content"
android:paddingBottom="@{viewModel.insets.bottom}" android:layout_height="match_parent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" android:clipToPadding="false"
tools:listitem="@layout/item_console" android:orientation="vertical"
tools:paddingTop="24dp" /> android:paddingTop="@{viewModel.insets.top + (int) @dimen/internal_action_bar_size}"
android:paddingBottom="@{viewModel.insets.bottom}"
</HorizontalScrollView> 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> </layout>
\ No newline at end of file
...@@ -91,10 +91,14 @@ ...@@ -91,10 +91,14 @@
<string name="superuser_toggle_log">Logs</string> <string name="superuser_toggle_log">Logs</string>
<string name="superuser_toggle_notification">Notifications</string> <string name="superuser_toggle_notification">Notifications</string>
<string name="superuser_toggle_revoke">Revoke</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_filter_hint">Filter by name</string>
<string name="hide_scroll_up">Scroll up</string> <string name="hide_scroll_up">Scroll up</string>
<string name="hide_filters">Filters</string> <string name="hide_filters">Filters</string>
<string name="hide_search">Search</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> </resources>
\ No newline at end of file
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