Updated modules so they are properly arranged to respective sections

Small updates to module UI
This commit is contained in:
Viktor De Pasquale
2019-11-06 17:09:00 +01:00
parent 1c8988d3f7
commit c7cad7e4aa
4 changed files with 112 additions and 68 deletions

View File

@@ -1,8 +1,6 @@
package com.topjohnwu.magisk.model.entity.recycler
import android.content.res.Resources
import android.view.View
import android.view.ViewGroup
import androidx.annotation.StringRes
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.databinding.ComparableRvItem
@@ -13,8 +11,6 @@ import com.topjohnwu.magisk.model.entity.module.Module
import com.topjohnwu.magisk.model.entity.module.Repo
import com.topjohnwu.magisk.redesign.module.ModuleViewModel
import com.topjohnwu.magisk.utils.KObservableField
import com.topjohnwu.magisk.utils.rotationTo
import com.topjohnwu.magisk.utils.setRevealed
class ModuleRvItem(val item: Module) : ComparableRvItem<ModuleRvItem>() {
@@ -83,22 +79,29 @@ class ModuleItem(val item: Module) : ComparableRvItem<ModuleItem>() {
override val layoutRes = R.layout.item_module_md2
val isExpanded = KObservableField(false)
val isEnabled = KObservableField(item.enable)
val isRemoved = KObservableField(item.remove)
val isUpdated get() = item.updated
val isModified get() = item.enable != isEnabled.value
val isModified get() = item.remove || item.updated
init {
isEnabled.addOnPropertyChangedCallback {
item.enable = it ?: return@addOnPropertyChangedCallback
}
isRemoved.addOnPropertyChangedCallback {
item.remove = it ?: return@addOnPropertyChangedCallback
}
}
fun toggle(viewModel: ModuleViewModel) {
isEnabled.toggle()
viewModel.moveToState(this)
viewModel.updateState()
}
fun toggle(view: View) {
isExpanded.toggle()
view.rotationTo(if (isExpanded.value) 225 else 180)
(view.parent as ViewGroup)
.findViewById<View>(R.id.module_expand_container)
.setRevealed(isExpanded.value)
fun delete(viewModel: ModuleViewModel) {
isRemoved.toggle()
viewModel.updateState()
}
override fun contentSameAs(other: ModuleItem): Boolean = item.version == other.item.version

View File

@@ -1,5 +1,7 @@
package com.topjohnwu.magisk.redesign.module
import androidx.annotation.WorkerThread
import androidx.recyclerview.widget.DiffUtil
import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.extensions.subscribeK
import com.topjohnwu.magisk.model.entity.module.Module
@@ -7,6 +9,8 @@ import com.topjohnwu.magisk.model.entity.recycler.ModuleItem
import com.topjohnwu.magisk.redesign.compat.CompatViewModel
import com.topjohnwu.magisk.redesign.home.itemBindingOf
import com.topjohnwu.magisk.redesign.superuser.diffListOf
import com.topjohnwu.magisk.utils.DiffObservableList
import com.topjohnwu.magisk.utils.currentLocale
import io.reactivex.Single
class ModuleViewModel : CompatViewModel() {
@@ -19,31 +23,65 @@ class ModuleViewModel : CompatViewModel() {
override fun refresh() = Single.fromCallable { Module.loadModules() }
.map { it.map { ModuleItem(it) } }
.map { it to items.calculateDiff(it) }
.subscribeK {
items.update(it.first, it.second)
items.forEach { moveToState(it) }
}
.map { it.order() }
.subscribeK { it.forEach { it.update() } }
fun moveToState(item: ModuleItem) {
val isActive = items.indexOfFirst { it.itemSameAs(item) } != -1
val isPending = itemsPending.indexOfFirst { it.itemSameAs(item) } != -1
when {
isActive && isPending -> if (item.isModified) {
items.remove(item)
} else {
itemsPending.remove(item)
}
isActive && item.isModified -> {
items.remove(item)
itemsPending.add(item)
}
isPending && !item.isModified -> {
itemsPending.remove(item)
items.add(item)
@WorkerThread
private fun List<ModuleItem>.order() = sortedBy { it.item.name.toLowerCase(currentLocale) }
.groupBy {
when {
it.isModified -> ModuleState.Modified
else -> ModuleState.Normal
}
}
.map {
val diff = when (it.key) {
ModuleState.Modified -> itemsPending
ModuleState.Normal -> items
}.calculateDiff(it.value)
ResultEnclosure(it.key, it.value, diff)
}
.ensureAllStates()
private fun List<ResultEnclosure>.ensureAllStates(): List<ResultEnclosure> {
val me = this as? MutableList<ResultEnclosure> ?: this.toMutableList()
ModuleState.values().forEach {
if (me.none { rit -> it == rit.state }) {
me.add(ResultEnclosure(it, listOf(), null))
}
}
return me
}
fun updateState() {
// I don't feel like bothering with moving every single item to its updated state,
// so this kind of wasteful operation helps with that
Single.fromCallable { items + itemsPending }
.map { it.order() }
.subscribeK { it.forEach { it.update() } }
}
private enum class ModuleState {
Modified, Normal
}
private data class ResultEnclosure(
val state: ModuleState,
val list: List<ModuleItem>,
val diff: DiffUtil.DiffResult?
)
private fun ResultEnclosure.update() = when (state) {
ModuleState.Modified -> itemsPending
ModuleState.Normal -> items
}.update(list, diff)
private fun <T> DiffObservableList<T>.update(list: List<T>, diff: DiffUtil.DiffResult?) {
diff ?: let {
update(list)
return
}
update(list, diff)
}
}