diff --git a/app/src/main/java/com/topjohnwu/magisk/databinding/DiffObservableList.kt b/app/src/main/java/com/topjohnwu/magisk/databinding/DiffObservableList.kt index 2e260f209..441e0f5c5 100644 --- a/app/src/main/java/com/topjohnwu/magisk/databinding/DiffObservableList.kt +++ b/app/src/main/java/com/topjohnwu/magisk/databinding/DiffObservableList.kt @@ -1,31 +1,26 @@ package com.topjohnwu.magisk.databinding import androidx.annotation.MainThread +import androidx.annotation.WorkerThread import androidx.databinding.ListChangeRegistry import androidx.databinding.ObservableList import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListUpdateCallback +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext import java.util.AbstractList -open class DiffObservableList( - private val callback: Callback -) : AbstractList(), ObservableList { +open class DiffObservableList> + : AbstractList(), ObservableList, ListUpdateCallback { protected var list: List = emptyList() + private set private val listeners = ListChangeRegistry() - protected val listCallback = ObservableListUpdateCallback() override val size: Int get() = list.size override fun get(index: Int) = list[index] - /** - * Calculates the list of update operations that can convert this list into the given one. - * - * @param newItems The items that this list will be set to. - * @return A DiffResult that contains the information about the edit sequence to covert this - * list into the given one. - */ fun calculateDiff(newItems: List): DiffUtil.DiffResult { return doCalculateDiff(list, newItems) } @@ -36,31 +31,34 @@ open class DiffObservableList( override fun getNewListSize() = newItems.size + @Suppress("UNCHECKED_CAST") override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { val oldItem = oldItems[oldItemPosition] val newItem = newItems[newItemPosition] - return callback.areItemsTheSame(oldItem, newItem) + return (oldItem as DiffItem).itemSameAs(newItem) } + @Suppress("UNCHECKED_CAST") override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { val oldItem = oldItems[oldItemPosition] val newItem = newItems[newItemPosition] - return callback.areContentsTheSame(oldItem, newItem) + return (oldItem as DiffItem).contentSameAs(newItem) } }, true) } - /** - * Updates the contents of this list to the given one using the DiffResults to dispatch change - * notifications. - * - * @param newItems The items to set this list to. - * @param diffResult The diff results to dispatch change notifications. - */ @MainThread fun update(newItems: List, diffResult: DiffUtil.DiffResult) { list = ArrayList(newItems) - diffResult.dispatchUpdatesTo(listCallback) + diffResult.dispatchUpdatesTo(this) + } + + @WorkerThread + suspend fun update(newItems: List) { + val diffResult = calculateDiff(newItems) + withContext(Dispatchers.Main) { + update(newItems, diffResult) + } } override fun addOnListChangedCallback(listener: ObservableList.OnListChangedCallback>) { @@ -71,36 +69,21 @@ open class DiffObservableList( listeners.remove(listener) } - private fun notifyAdd(start: Int, count: Int) { - listeners.notifyInserted(this, start, count) + override fun onChanged(position: Int, count: Int, payload: Any?) { + listeners.notifyChanged(this, position, count) } - private fun notifyRemove(start: Int, count: Int) { - listeners.notifyRemoved(this, start, count) + override fun onMoved(fromPosition: Int, toPosition: Int) { + listeners.notifyMoved(this, fromPosition, toPosition, 1) } - interface Callback { - fun areItemsTheSame(oldItem: T, newItem: T): Boolean - fun areContentsTheSame(oldItem: T, newItem: T): Boolean + override fun onInserted(position: Int, count: Int) { + modCount += 1 + listeners.notifyInserted(this, position, count) } - inner class ObservableListUpdateCallback : ListUpdateCallback { - override fun onChanged(position: Int, count: Int, payload: Any?) { - listeners.notifyChanged(this@DiffObservableList, position, count) - } - - override fun onMoved(fromPosition: Int, toPosition: Int) { - listeners.notifyMoved(this@DiffObservableList, fromPosition, toPosition, 1) - } - - override fun onInserted(position: Int, count: Int) { - modCount += 1 - listeners.notifyInserted(this@DiffObservableList, position, count) - } - - override fun onRemoved(position: Int, count: Int) { - modCount += 1 - listeners.notifyRemoved(this@DiffObservableList, position, count) - } + override fun onRemoved(position: Int, count: Int) { + modCount += 1 + listeners.notifyRemoved(this, position, count) } } diff --git a/app/src/main/java/com/topjohnwu/magisk/databinding/FilterableDiffObservableList.kt b/app/src/main/java/com/topjohnwu/magisk/databinding/FilterableDiffObservableList.kt index 7cfbd6ce9..786769bda 100644 --- a/app/src/main/java/com/topjohnwu/magisk/databinding/FilterableDiffObservableList.kt +++ b/app/src/main/java/com/topjohnwu/magisk/databinding/FilterableDiffObservableList.kt @@ -6,10 +6,9 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -open class FilterableDiffObservableList( - callback: Callback, +open class FilterableDiffObservableList>( private val scope: CoroutineScope -) : DiffObservableList(callback) { +) : DiffObservableList() { private var sublist: List = emptyList() private var job: Job? = null @@ -24,7 +23,7 @@ open class FilterableDiffObservableList( val diff = doCalculateDiff(oldList, newList) withContext(Dispatchers.Main) { sublist = newList - diff.dispatchUpdatesTo(listCallback) + diff.dispatchUpdatesTo(this@FilterableDiffObservableList) } } } diff --git a/app/src/main/java/com/topjohnwu/magisk/databinding/RecyclerViewItems.kt b/app/src/main/java/com/topjohnwu/magisk/databinding/RecyclerViewItems.kt index 0f007866a..7b26f832d 100644 --- a/app/src/main/java/com/topjohnwu/magisk/databinding/RecyclerViewItems.kt +++ b/app/src/main/java/com/topjohnwu/magisk/databinding/RecyclerViewItems.kt @@ -3,69 +3,33 @@ package com.topjohnwu.magisk.databinding import androidx.databinding.PropertyChangeRegistry import androidx.databinding.ViewDataBinding import androidx.recyclerview.widget.RecyclerView -import kotlinx.coroutines.CoroutineScope abstract class RvItem { abstract val layoutRes: Int } -interface RvContainer { - val item: E -} - -interface ViewAwareRvItem { - fun onBind(binding: ViewDataBinding, recyclerView: RecyclerView) -} - -interface ComparableRv : Comparable { - @Suppress("UNCHECKED_CAST") - fun comparableEqual(o: Any?) = - o != null && o::class == this::class && compareTo(o as T) == 0 -} - -abstract class DiffRvItem : RvItem() { - - // Defer to contentSameAs by default - open fun itemSameAs(other: T) = true - - open fun contentSameAs(other: T) = - when (this) { - is RvContainer<*> -> item == (other as RvContainer<*>).item - is ComparableRv<*> -> comparableEqual(other) - else -> this == other - } -} - -typealias AnyDiffRvItem = DiffRvItem<*> - -abstract class ObservableDiffRvItem : DiffRvItem(), ObservableHost { - override var callbacks: PropertyChangeRegistry? = null -} - abstract class ObservableRvItem : RvItem(), ObservableHost { override var callbacks: PropertyChangeRegistry? = null } -private object DiffRvItemCallback : DiffObservableList.Callback> { - override fun areItemsTheSame( - oldItem: DiffRvItem, - newItem: DiffRvItem - ): Boolean { - return oldItem::class == newItem::class && oldItem.itemSameAs(newItem) - } - - override fun areContentsTheSame( - oldItem: DiffRvItem, - newItem: DiffRvItem - ): Boolean { - return oldItem.contentSameAs(newItem) - } +interface ItemWrapper { + val item: E } -@Suppress("UNCHECKED_CAST") -class DiffRvItemList : DiffObservableList(DiffRvItemCallback as Callback) +interface ViewAwareItem { + fun onBind(binding: ViewDataBinding, recyclerView: RecyclerView) +} -@Suppress("UNCHECKED_CAST") -class DiffRvItemFilterList( - scope: CoroutineScope -) : FilterableDiffObservableList(DiffRvItemCallback as Callback, scope) +interface DiffItem { + + fun itemSameAs(other: T): Boolean { + if (this === other) return true + return when (this) { + is ItemWrapper<*> -> item == (other as ItemWrapper<*>).item + is Comparable<*> -> compareValues(this, other as Comparable<*>) == 0 + else -> this == other + } + } + + fun contentSameAs(other: T) = true +} diff --git a/app/src/main/java/com/topjohnwu/magisk/databinding/RvItemAdapter.kt b/app/src/main/java/com/topjohnwu/magisk/databinding/RvItemAdapter.kt index 8ca0b2d12..97ad66892 100644 --- a/app/src/main/java/com/topjohnwu/magisk/databinding/RvItemAdapter.kt +++ b/app/src/main/java/com/topjohnwu/magisk/databinding/RvItemAdapter.kt @@ -53,7 +53,7 @@ class RvItemAdapter( holder.binding.lifecycleOwner = lifecycleOwner holder.binding.executePendingBindings() recyclerView?.let { - if (item is ViewAwareRvItem) + if (item is ViewAwareItem) item.onBind(holder.binding, it) } } diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/deny/DenyListRvItem.kt b/app/src/main/java/com/topjohnwu/magisk/ui/deny/DenyListRvItem.kt index 512ff6d02..6b2d311d3 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/deny/DenyListRvItem.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/deny/DenyListRvItem.kt @@ -5,8 +5,8 @@ import android.view.ViewGroup import androidx.databinding.Bindable import com.topjohnwu.magisk.BR import com.topjohnwu.magisk.R -import com.topjohnwu.magisk.databinding.ComparableRv -import com.topjohnwu.magisk.databinding.ObservableDiffRvItem +import com.topjohnwu.magisk.databinding.DiffItem +import com.topjohnwu.magisk.databinding.ObservableRvItem import com.topjohnwu.magisk.databinding.addOnPropertyChangedCallback import com.topjohnwu.magisk.databinding.set import com.topjohnwu.magisk.ktx.startAnimations @@ -15,7 +15,7 @@ import kotlin.math.roundToInt class DenyListRvItem( val info: AppProcessInfo -) : ObservableDiffRvItem(), ComparableRv { +) : ObservableRvItem(), DiffItem, Comparable { override val layoutRes get() = R.layout.item_hide_md2 @@ -100,7 +100,7 @@ class DenyListRvItem( class ProcessRvItem( val process: ProcessInfo -) : ObservableDiffRvItem() { +) : ObservableRvItem(), DiffItem { override val layoutRes get() = R.layout.item_hide_process_md2 @@ -122,10 +122,9 @@ class ProcessRvItem( val defaultSelection get() = process.isIsolated || process.isAppZygote || process.name == process.packageName - override fun contentSameAs(other: ProcessRvItem) = - process.isEnabled == other.process.isEnabled - override fun itemSameAs(other: ProcessRvItem) = process.name == other.process.name && process.packageName == other.process.packageName + override fun contentSameAs(other: ProcessRvItem) = + process.isEnabled == other.process.isEnabled } diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/deny/DenyListViewModel.kt b/app/src/main/java/com/topjohnwu/magisk/ui/deny/DenyListViewModel.kt index da505ae9c..85e71f920 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/deny/DenyListViewModel.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/deny/DenyListViewModel.kt @@ -7,7 +7,7 @@ import androidx.lifecycle.viewModelScope import com.topjohnwu.magisk.BR import com.topjohnwu.magisk.arch.AsyncLoadViewModel import com.topjohnwu.magisk.core.di.AppContext -import com.topjohnwu.magisk.databinding.DiffRvItemFilterList +import com.topjohnwu.magisk.databinding.FilterableDiffObservableList import com.topjohnwu.magisk.databinding.bindExtra import com.topjohnwu.magisk.databinding.set import com.topjohnwu.magisk.ktx.concurrentMap @@ -38,7 +38,7 @@ class DenyListViewModel : AsyncLoadViewModel() { query() } - val items = DiffRvItemFilterList(viewModelScope) + val items = FilterableDiffObservableList(viewModelScope) val extraBindings = bindExtra { it.put(BR.viewModel, this) } @@ -50,7 +50,7 @@ class DenyListViewModel : AsyncLoadViewModel() { @SuppressLint("InlinedApi") override suspend fun doLoadWork() { loading = true - val (apps, diff) = withContext(Dispatchers.Default) { + withContext(Dispatchers.Default) { val pm = AppContext.packageManager val denyList = Shell.cmd("magisk --denylist ls").exec().out .map { CmdlineListItem(it) } @@ -63,9 +63,8 @@ class DenyListViewModel : AsyncLoadViewModel() { .toCollection(ArrayList(size)) } apps.sort() - apps to items.calculateDiff(apps) + items.update(apps) } - items.update(apps, diff) query() } diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/flash/ConsoleItem.kt b/app/src/main/java/com/topjohnwu/magisk/ui/flash/ConsoleItem.kt index 36d038bdc..d0639d2d4 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/flash/ConsoleItem.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/flash/ConsoleItem.kt @@ -6,14 +6,15 @@ import androidx.core.view.updateLayoutParams import androidx.databinding.ViewDataBinding import androidx.recyclerview.widget.RecyclerView import com.topjohnwu.magisk.R -import com.topjohnwu.magisk.databinding.DiffRvItem -import com.topjohnwu.magisk.databinding.RvContainer -import com.topjohnwu.magisk.databinding.ViewAwareRvItem +import com.topjohnwu.magisk.databinding.DiffItem +import com.topjohnwu.magisk.databinding.ItemWrapper +import com.topjohnwu.magisk.databinding.RvItem +import com.topjohnwu.magisk.databinding.ViewAwareItem import kotlin.math.max class ConsoleItem( override val item: String -) : DiffRvItem(), ViewAwareRvItem, RvContainer { +) : RvItem(), ViewAwareItem, DiffItem, ItemWrapper { override val layoutRes = R.layout.item_console_md2 private var parentWidth = -1 diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/log/LogRvItem.kt b/app/src/main/java/com/topjohnwu/magisk/ui/log/LogRvItem.kt index 8f818e9fd..21bffb382 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/log/LogRvItem.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/log/LogRvItem.kt @@ -4,18 +4,17 @@ import androidx.databinding.ViewDataBinding import androidx.recyclerview.widget.RecyclerView import com.google.android.material.textview.MaterialTextView import com.topjohnwu.magisk.R -import com.topjohnwu.magisk.databinding.ObservableDiffRvItem -import com.topjohnwu.magisk.databinding.RvContainer -import com.topjohnwu.magisk.databinding.ViewAwareRvItem +import com.topjohnwu.magisk.databinding.DiffItem +import com.topjohnwu.magisk.databinding.ItemWrapper +import com.topjohnwu.magisk.databinding.ObservableRvItem +import com.topjohnwu.magisk.databinding.ViewAwareItem class LogRvItem( override val item: String -) : ObservableDiffRvItem(), RvContainer, ViewAwareRvItem { +) : ObservableRvItem(), DiffItem, ItemWrapper, ViewAwareItem { override val layoutRes = R.layout.item_log_textview - override fun itemSameAs(other: LogRvItem) = item == other.item - override fun onBind(binding: ViewDataBinding, recyclerView: RecyclerView) { val view = binding.root as MaterialTextView view.measure(0, 0) diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/log/LogViewModel.kt b/app/src/main/java/com/topjohnwu/magisk/ui/log/LogViewModel.kt index 87eb20dcc..d1b63b666 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/log/LogViewModel.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/log/LogViewModel.kt @@ -11,7 +11,7 @@ import com.topjohnwu.magisk.core.Info import com.topjohnwu.magisk.core.repository.LogRepository import com.topjohnwu.magisk.core.utils.MediaStoreUtils import com.topjohnwu.magisk.core.utils.MediaStoreUtils.outputStream -import com.topjohnwu.magisk.databinding.DiffRvItemList +import com.topjohnwu.magisk.databinding.DiffObservableList import com.topjohnwu.magisk.databinding.bindExtra import com.topjohnwu.magisk.databinding.set import com.topjohnwu.magisk.events.SnackbarEvent @@ -37,28 +37,26 @@ class LogViewModel( // --- su log - val items = DiffRvItemList() + val items = DiffObservableList() val extraBindings = bindExtra { it.put(BR.viewModel, this) } // --- magisk log - val logs = DiffRvItemList() + val logs = DiffObservableList() var magiskLogRaw = " " override suspend fun doLoadWork() { loading = true - val (logs, logDiff) = withContext(Dispatchers.Default) { - magiskLogRaw = repo.fetchMagiskLogs() - val logs = magiskLogRaw.split('\n').map { LogRvItem(it) } - logs to this@LogViewModel.logs.calculateDiff(logs) - } - this.logs.update(logs, logDiff) val (suLogs, suDiff) = withContext(Dispatchers.Default) { + magiskLogRaw = repo.fetchMagiskLogs() + val newLogs = magiskLogRaw.split('\n').map { LogRvItem(it) } + logs.update(newLogs) val suLogs = repo.fetchSuLogs().map { SuLogRvItem(it) } suLogs to items.calculateDiff(suLogs) } + items.firstOrNull()?.isTop = false items.lastOrNull()?.isBottom = false items.update(suLogs, suDiff) diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/log/SuLogRvItem.kt b/app/src/main/java/com/topjohnwu/magisk/ui/log/SuLogRvItem.kt index 05a85f9a3..59dc7871e 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/log/SuLogRvItem.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/log/SuLogRvItem.kt @@ -4,19 +4,17 @@ import androidx.databinding.Bindable import com.topjohnwu.magisk.BR import com.topjohnwu.magisk.R import com.topjohnwu.magisk.core.model.su.SuLog -import com.topjohnwu.magisk.databinding.ObservableDiffRvItem -import com.topjohnwu.magisk.databinding.RvContainer +import com.topjohnwu.magisk.databinding.DiffItem +import com.topjohnwu.magisk.databinding.ObservableRvItem import com.topjohnwu.magisk.databinding.set import com.topjohnwu.magisk.ktx.timeDateFormat import com.topjohnwu.magisk.ktx.toTime -class SuLogRvItem( - override val item: SuLog -) : ObservableDiffRvItem(), RvContainer { +class SuLogRvItem(val log: SuLog) : ObservableRvItem(), DiffItem { override val layoutRes = R.layout.item_log_access_md2 - val date = item.time.toTime(timeDateFormat) + val date = log.time.toTime(timeDateFormat) @get:Bindable var isTop = false @@ -26,5 +24,5 @@ class SuLogRvItem( var isBottom = false set(value) = set(value, field, { field = it }, BR.bottom) - override fun itemSameAs(other: SuLogRvItem) = item.appName == other.item.appName + override fun itemSameAs(other: SuLogRvItem) = log.appName == other.log.appName } diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/module/ModuleRvItem.kt b/app/src/main/java/com/topjohnwu/magisk/ui/module/ModuleRvItem.kt index cbbaaabad..95d3d5ecc 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/module/ModuleRvItem.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/module/ModuleRvItem.kt @@ -5,20 +5,21 @@ import com.topjohnwu.magisk.BR import com.topjohnwu.magisk.R import com.topjohnwu.magisk.core.Info import com.topjohnwu.magisk.core.model.module.LocalModule -import com.topjohnwu.magisk.databinding.DiffRvItem -import com.topjohnwu.magisk.databinding.ObservableDiffRvItem -import com.topjohnwu.magisk.databinding.RvContainer +import com.topjohnwu.magisk.databinding.DiffItem +import com.topjohnwu.magisk.databinding.ItemWrapper +import com.topjohnwu.magisk.databinding.ObservableRvItem +import com.topjohnwu.magisk.databinding.RvItem import com.topjohnwu.magisk.databinding.set import com.topjohnwu.magisk.utils.TextHolder import com.topjohnwu.magisk.utils.asText -object InstallModule : DiffRvItem() { +object InstallModule : RvItem(), DiffItem { override val layoutRes = R.layout.item_module_download } class LocalModuleRvItem( override val item: LocalModule -) : ObservableDiffRvItem(), RvContainer { +) : ObservableRvItem(), DiffItem, ItemWrapper { override val layoutRes = R.layout.item_module_md2 diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/module/ModuleViewModel.kt b/app/src/main/java/com/topjohnwu/magisk/ui/module/ModuleViewModel.kt index d7dc0a6e2..7464a732a 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/module/ModuleViewModel.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/module/ModuleViewModel.kt @@ -10,7 +10,7 @@ import com.topjohnwu.magisk.core.Info import com.topjohnwu.magisk.core.base.ContentResultCallback import com.topjohnwu.magisk.core.model.module.LocalModule import com.topjohnwu.magisk.core.model.module.OnlineModule -import com.topjohnwu.magisk.databinding.DiffRvItemList +import com.topjohnwu.magisk.databinding.DiffObservableList import com.topjohnwu.magisk.databinding.MergeObservableList import com.topjohnwu.magisk.databinding.RvItem import com.topjohnwu.magisk.databinding.bindExtra @@ -26,7 +26,7 @@ class ModuleViewModel : AsyncLoadViewModel() { val bottomBarBarrierIds = intArrayOf(R.id.module_update, R.id.module_remove) - private val itemsInstalled = DiffRvItemList() + private val itemsInstalled = DiffObservableList() val items = MergeObservableList() val extraBindings = bindExtra { @@ -57,11 +57,10 @@ class ModuleViewModel : AsyncLoadViewModel() { override fun onNetworkChanged(network: Boolean) = startLoading() private suspend fun loadInstalled() { - val installed = LocalModule.installed().map { LocalModuleRvItem(it) } - val diff = withContext(Dispatchers.Default) { - itemsInstalled.calculateDiff(installed) + withContext(Dispatchers.Default) { + val installed = LocalModule.installed().map { LocalModuleRvItem(it) } + itemsInstalled.update(installed) } - itemsInstalled.update(installed, diff) } private suspend fun loadUpdateInfo() { diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/superuser/PolicyRvItem.kt b/app/src/main/java/com/topjohnwu/magisk/ui/superuser/PolicyRvItem.kt index 124665cb8..e3ca1f57d 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/superuser/PolicyRvItem.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/superuser/PolicyRvItem.kt @@ -5,8 +5,9 @@ import androidx.databinding.Bindable import com.topjohnwu.magisk.BR import com.topjohnwu.magisk.R import com.topjohnwu.magisk.core.model.su.SuPolicy -import com.topjohnwu.magisk.databinding.ObservableDiffRvItem -import com.topjohnwu.magisk.databinding.RvContainer +import com.topjohnwu.magisk.databinding.DiffItem +import com.topjohnwu.magisk.databinding.ItemWrapper +import com.topjohnwu.magisk.databinding.ObservableRvItem import com.topjohnwu.magisk.databinding.set class PolicyRvItem( @@ -16,7 +17,7 @@ class PolicyRvItem( private val isSharedUid: Boolean, val icon: Drawable, val appName: String -) : ObservableDiffRvItem(), RvContainer { +) : ObservableRvItem(), DiffItem, ItemWrapper { override val layoutRes = R.layout.item_policy_md2 diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/superuser/SuperuserViewModel.kt b/app/src/main/java/com/topjohnwu/magisk/ui/superuser/SuperuserViewModel.kt index d4e0a62db..19da7bf46 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/superuser/SuperuserViewModel.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/superuser/SuperuserViewModel.kt @@ -34,9 +34,9 @@ class SuperuserViewModel( private val itemNoData = TextItem(R.string.superuser_policy_none) private val itemsHelpers = ObservableArrayList() - private val itemsPolicies = DiffRvItemList() + private val itemsPolicies = DiffObservableList() - val items = MergeObservableList() + val items = MergeObservableList() .insertList(itemsHelpers) .insertList(itemsPolicies) val extraBindings = bindExtra { @@ -54,7 +54,7 @@ class SuperuserViewModel( return } loading = true - val (policies, diff) = withContext(Dispatchers.IO) { + withContext(Dispatchers.IO) { db.deleteOutdated() db.delete(AppContext.applicationInfo.uid) val policies = ArrayList() @@ -91,9 +91,8 @@ class SuperuserViewModel( { it.appName.lowercase(currentLocale) }, { it.packageName } )) - policies to itemsPolicies.calculateDiff(policies) + itemsPolicies.update(policies) } - itemsPolicies.update(policies, diff) if (itemsPolicies.isNotEmpty()) itemsHelpers.clear() else if (itemsHelpers.isEmpty()) diff --git a/app/src/main/java/com/topjohnwu/magisk/view/MagiskDialog.kt b/app/src/main/java/com/topjohnwu/magisk/view/MagiskDialog.kt index fafebb7e8..8317d04b9 100644 --- a/app/src/main/java/com/topjohnwu/magisk/view/MagiskDialog.kt +++ b/app/src/main/java/com/topjohnwu/magisk/view/MagiskDialog.kt @@ -22,7 +22,14 @@ import com.google.android.material.shape.MaterialShapeDrawable import com.topjohnwu.magisk.BR import com.topjohnwu.magisk.R import com.topjohnwu.magisk.core.base.BaseActivity -import com.topjohnwu.magisk.databinding.* +import com.topjohnwu.magisk.databinding.DialogMagiskBaseBinding +import com.topjohnwu.magisk.databinding.DiffItem +import com.topjohnwu.magisk.databinding.ItemWrapper +import com.topjohnwu.magisk.databinding.ObservableHost +import com.topjohnwu.magisk.databinding.RvItem +import com.topjohnwu.magisk.databinding.bindExtra +import com.topjohnwu.magisk.databinding.set +import com.topjohnwu.magisk.databinding.setAdapter import com.topjohnwu.magisk.view.MagiskDialog.DialogClickListener typealias DialogButtonClickListener = (DialogInterface) -> Unit @@ -166,7 +173,7 @@ class MagiskDialog( class DialogItem( override val item: CharSequence, val position: Int - ) : DiffRvItem(), RvContainer { + ) : RvItem(), DiffItem, ItemWrapper { override val layoutRes = R.layout.item_list_single_line } diff --git a/app/src/main/java/com/topjohnwu/magisk/view/TappableHeadlineItem.kt b/app/src/main/java/com/topjohnwu/magisk/view/TappableHeadlineItem.kt index 06618659e..bf8aab393 100644 --- a/app/src/main/java/com/topjohnwu/magisk/view/TappableHeadlineItem.kt +++ b/app/src/main/java/com/topjohnwu/magisk/view/TappableHeadlineItem.kt @@ -1,9 +1,10 @@ package com.topjohnwu.magisk.view import com.topjohnwu.magisk.R -import com.topjohnwu.magisk.databinding.DiffRvItem +import com.topjohnwu.magisk.databinding.DiffItem +import com.topjohnwu.magisk.databinding.RvItem -sealed class TappableHeadlineItem : DiffRvItem() { +sealed class TappableHeadlineItem : RvItem(), DiffItem { abstract val title: Int abstract val icon: Int diff --git a/app/src/main/java/com/topjohnwu/magisk/view/TextItem.kt b/app/src/main/java/com/topjohnwu/magisk/view/TextItem.kt index fbb017829..6056e466b 100644 --- a/app/src/main/java/com/topjohnwu/magisk/view/TextItem.kt +++ b/app/src/main/java/com/topjohnwu/magisk/view/TextItem.kt @@ -1,10 +1,10 @@ package com.topjohnwu.magisk.view import com.topjohnwu.magisk.R -import com.topjohnwu.magisk.databinding.DiffRvItem +import com.topjohnwu.magisk.databinding.DiffItem +import com.topjohnwu.magisk.databinding.ItemWrapper +import com.topjohnwu.magisk.databinding.RvItem -class TextItem(val text: Int) : DiffRvItem() { +class TextItem(override val item: Int) : RvItem(), DiffItem, ItemWrapper { override val layoutRes = R.layout.item_text - - override fun contentSameAs(other: TextItem) = text == other.text } diff --git a/app/src/main/res/layout/item_log_access_md2.xml b/app/src/main/res/layout/item_log_access_md2.xml index 0c7f43c85..aefa30ca3 100644 --- a/app/src/main/res/layout/item_log_access_md2.xml +++ b/app/src/main/res/layout/item_log_access_md2.xml @@ -25,9 +25,9 @@