Commit c7cad7e4 authored by Viktor De Pasquale's avatar Viktor De Pasquale

Updated modules so they are properly arranged to respective sections

Small updates to module UI
parent 1c8988d3
package com.topjohnwu.magisk.model.entity.recycler package com.topjohnwu.magisk.model.entity.recycler
import android.content.res.Resources import android.content.res.Resources
import android.view.View
import android.view.ViewGroup
import androidx.annotation.StringRes import androidx.annotation.StringRes
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.databinding.ComparableRvItem import com.topjohnwu.magisk.databinding.ComparableRvItem
...@@ -13,8 +11,6 @@ import com.topjohnwu.magisk.model.entity.module.Module ...@@ -13,8 +11,6 @@ import com.topjohnwu.magisk.model.entity.module.Module
import com.topjohnwu.magisk.model.entity.module.Repo import com.topjohnwu.magisk.model.entity.module.Repo
import com.topjohnwu.magisk.redesign.module.ModuleViewModel import com.topjohnwu.magisk.redesign.module.ModuleViewModel
import com.topjohnwu.magisk.utils.KObservableField 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>() { class ModuleRvItem(val item: Module) : ComparableRvItem<ModuleRvItem>() {
...@@ -83,22 +79,29 @@ class ModuleItem(val item: Module) : ComparableRvItem<ModuleItem>() { ...@@ -83,22 +79,29 @@ class ModuleItem(val item: Module) : ComparableRvItem<ModuleItem>() {
override val layoutRes = R.layout.item_module_md2 override val layoutRes = R.layout.item_module_md2
val isExpanded = KObservableField(false)
val isEnabled = KObservableField(item.enable) 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) { fun toggle(viewModel: ModuleViewModel) {
isEnabled.toggle() isEnabled.toggle()
viewModel.moveToState(this) viewModel.updateState()
} }
fun toggle(view: View) { fun delete(viewModel: ModuleViewModel) {
isExpanded.toggle() isRemoved.toggle()
view.rotationTo(if (isExpanded.value) 225 else 180) viewModel.updateState()
(view.parent as ViewGroup)
.findViewById<View>(R.id.module_expand_container)
.setRevealed(isExpanded.value)
} }
override fun contentSameAs(other: ModuleItem): Boolean = item.version == other.item.version override fun contentSameAs(other: ModuleItem): Boolean = item.version == other.item.version
......
package com.topjohnwu.magisk.redesign.module package com.topjohnwu.magisk.redesign.module
import androidx.annotation.WorkerThread
import androidx.recyclerview.widget.DiffUtil
import com.topjohnwu.magisk.BR import com.topjohnwu.magisk.BR
import com.topjohnwu.magisk.extensions.subscribeK import com.topjohnwu.magisk.extensions.subscribeK
import com.topjohnwu.magisk.model.entity.module.Module import com.topjohnwu.magisk.model.entity.module.Module
...@@ -7,6 +9,8 @@ import com.topjohnwu.magisk.model.entity.recycler.ModuleItem ...@@ -7,6 +9,8 @@ import com.topjohnwu.magisk.model.entity.recycler.ModuleItem
import com.topjohnwu.magisk.redesign.compat.CompatViewModel import com.topjohnwu.magisk.redesign.compat.CompatViewModel
import com.topjohnwu.magisk.redesign.home.itemBindingOf import com.topjohnwu.magisk.redesign.home.itemBindingOf
import com.topjohnwu.magisk.redesign.superuser.diffListOf import com.topjohnwu.magisk.redesign.superuser.diffListOf
import com.topjohnwu.magisk.utils.DiffObservableList
import com.topjohnwu.magisk.utils.currentLocale
import io.reactivex.Single import io.reactivex.Single
class ModuleViewModel : CompatViewModel() { class ModuleViewModel : CompatViewModel() {
...@@ -19,31 +23,65 @@ class ModuleViewModel : CompatViewModel() { ...@@ -19,31 +23,65 @@ class ModuleViewModel : CompatViewModel() {
override fun refresh() = Single.fromCallable { Module.loadModules() } override fun refresh() = Single.fromCallable { Module.loadModules() }
.map { it.map { ModuleItem(it) } } .map { it.map { ModuleItem(it) } }
.map { it to items.calculateDiff(it) } .map { it.order() }
.subscribeK { .subscribeK { it.forEach { it.update() } }
items.update(it.first, it.second)
items.forEach { moveToState(it) }
}
fun moveToState(item: ModuleItem) {
val isActive = items.indexOfFirst { it.itemSameAs(item) } != -1
val isPending = itemsPending.indexOfFirst { it.itemSameAs(item) } != -1
when { @WorkerThread
isActive && isPending -> if (item.isModified) { private fun List<ModuleItem>.order() = sortedBy { it.item.name.toLowerCase(currentLocale) }
items.remove(item) .groupBy {
} else { when {
itemsPending.remove(item) it.isModified -> ModuleState.Modified
else -> ModuleState.Normal
} }
isActive && item.isModified -> { }
items.remove(item) .map {
itemsPending.add(item) val diff = when (it.key) {
} ModuleState.Modified -> itemsPending
isPending && !item.isModified -> { ModuleState.Normal -> items
itemsPending.remove(item) }.calculateDiff(it.value)
items.add(item) 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)
} }
} }
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_restart" android:state_selected="true" />
<item android:drawable="@drawable/ic_delete_md2" />
</selector>
\ No newline at end of file
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
<data> <data>
<import type="com.topjohnwu.magisk.R" />
<import type="com.topjohnwu.magisk.Config" /> <import type="com.topjohnwu.magisk.Config" />
<variable <variable
...@@ -19,7 +21,7 @@ ...@@ -19,7 +21,7 @@
<com.google.android.material.card.MaterialCardView <com.google.android.material.card.MaterialCardView
style="?styleCardVariant" style="?styleCardVariant"
isEnabled="@{!Config.coreOnly}" isEnabled="@{!Config.coreOnly &amp;&amp; !item.isRemoved()}"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:alpha="@{item.isEnabled() &amp;&amp; !Config.coreOnly ? 1f : .5f}" android:alpha="@{item.isEnabled() &amp;&amp; !Config.coreOnly ? 1f : .5f}"
...@@ -33,28 +35,41 @@ ...@@ -33,28 +35,41 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingBottom="@dimen/l1"> android:paddingBottom="@dimen/l1">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/module_state_icon"
style="?styleImageSmall"
gone="@{!item.isRemoved &amp;&amp; !item.updated}"
srcCompat="@{item.isRemoved ? R.drawable.ic_delete_md2 : R.drawable.ic_update_md2}"
android:layout_marginStart="@dimen/l1"
android:background="@null"
app:layout_constraintBottom_toBottomOf="@+id/module_version_author"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/module_title"
tools:srcCompat="@drawable/ic_update_md2" />
<androidx.appcompat.widget.AppCompatTextView <androidx.appcompat.widget.AppCompatTextView
android:id="@+id/module_title" android:id="@+id/module_title"
android:layout_width="match_parent" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/l1" android:layout_marginStart="@dimen/l1"
android:layout_marginTop="@dimen/l1" android:layout_marginTop="@dimen/l1"
android:layout_marginEnd="32dp"
android:text="@{item.item.name}" android:text="@{item.item.name}"
android:textAppearance="?appearanceTextBodyNormal" android:textAppearance="?appearanceTextBodyNormal"
android:textStyle="bold" android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toStartOf="@+id/module_remove"
app:layout_constraintStart_toEndOf="@+id/module_state_icon"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
tools:text="@tools:sample/lorem" /> tools:text="@tools:sample/lorem" />
<androidx.appcompat.widget.AppCompatTextView <androidx.appcompat.widget.AppCompatTextView
android:id="@+id/module_version_author" android:id="@+id/module_version_author"
android:layout_width="match_parent" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/l1" android:layout_marginStart="@dimen/l1"
android:layout_marginEnd="@dimen/l1"
android:text="@{@string/module_version_author(item.item.version, item.item.author)}" android:text="@{@string/module_version_author(item.item.version, item.item.author)}"
android:textAppearance="?appearanceTextCaptionVariant" android:textAppearance="?appearanceTextCaptionVariant"
app:layout_constraintEnd_toStartOf="@+id/module_remove"
app:layout_constraintStart_toEndOf="@+id/module_state_icon"
app:layout_constraintTop_toBottomOf="@+id/module_title" app:layout_constraintTop_toBottomOf="@+id/module_title"
tools:text="v1 by topjohnwu" /> tools:text="v1 by topjohnwu" />
...@@ -71,34 +86,17 @@ ...@@ -71,34 +86,17 @@
tools:lines="4" tools:lines="4"
tools:text="@tools:sample/lorem/random" /> tools:text="@tools:sample/lorem/random" />
</androidx.constraintlayout.widget.ConstraintLayout> <androidx.appcompat.widget.AppCompatImageView
android:id="@+id/module_remove"
<FrameLayout style="?styleIconNormal"
android:id="@+id/module_expand_container" isSelected="@{item.isRemoved}"
revealFix="@{item.isExpanded}" android:alpha=".5"
android:layout_width="match_parent" android:onClick="@{(v) -> item.delete(viewModel)}"
android:layout_height="match_parent" app:layout_constraintEnd_toEndOf="parent"
android:background="?colorSurfaceVariant" app:layout_constraintTop_toTopOf="parent"
android:visibility="gone"> app:srcCompat="@drawable/ic_delete_restore" />
<com.google.android.material.button.MaterialButton </androidx.constraintlayout.widget.ConstraintLayout>
style="?styleButtonError"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Remove"
android:textAllCaps="false"
app:icon="@drawable/ic_delete_md2" />
</FrameLayout>
<androidx.appcompat.widget.AppCompatImageView
style="?styleIconNormal"
isSelected="@{item.isExpanded}"
android:layout_gravity="top|end"
android:onClick="@{(v) -> item.toggle(v)}"
android:rotation="@{item.isExpanded ? 225 : 180}"
app:srcCompat="@drawable/ic_more_collapse" />
</com.google.android.material.card.MaterialCardView> </com.google.android.material.card.MaterialCardView>
......
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