Commit 6a243ec7 authored by Viktor De Pasquale's avatar Viktor De Pasquale

Fixed inconsistent displaying of repos and improved their sorting

parent 8cd3b603
...@@ -35,6 +35,9 @@ class ModuleRepository( ...@@ -35,6 +35,9 @@ class ModuleRepository(
}.getOrNull() }.getOrNull()
} }
} }
//either github apparently returns repos incorrectly or ...
//either ways this fixes duplicates
.map { it.distinctBy { it.id } }
.doOnSuccess { repoDao.insert(it) } .doOnSuccess { repoDao.insert(it) }
private fun fetchCachedOrdered() = Single.fromCallable { private fun fetchCachedOrdered() = Single.fromCallable {
......
...@@ -50,8 +50,9 @@ class ModuleRvItem(val item: OldModule) : ComparableRvItem<ModuleRvItem>() { ...@@ -50,8 +50,9 @@ class ModuleRvItem(val item: OldModule) : ComparableRvItem<ModuleRvItem>() {
override fun contentSameAs(other: ModuleRvItem): Boolean = item.version == other.item.version override fun contentSameAs(other: ModuleRvItem): Boolean = item.version == other.item.version
&& item.versionCode == other.item.versionCode && item.versionCode == other.item.versionCode
&& item.description == other.item.description && item.description == other.item.description
&& item.name == other.item.name
override fun itemSameAs(other: ModuleRvItem): Boolean = item.name == other.item.name override fun itemSameAs(other: ModuleRvItem): Boolean = item.id == other.item.id
} }
class RepoRvItem(val item: Repo) : ComparableRvItem<RepoRvItem>() { class RepoRvItem(val item: Repo) : ComparableRvItem<RepoRvItem>() {
...@@ -64,6 +65,7 @@ class RepoRvItem(val item: Repo) : ComparableRvItem<RepoRvItem>() { ...@@ -64,6 +65,7 @@ class RepoRvItem(val item: Repo) : ComparableRvItem<RepoRvItem>() {
&& item.lastUpdate == other.item.lastUpdate && item.lastUpdate == other.item.lastUpdate
&& item.versionCode == other.item.versionCode && item.versionCode == other.item.versionCode
&& item.description == other.item.description && item.description == other.item.description
&& item.detailUrl == other.item.detailUrl
override fun itemSameAs(other: RepoRvItem): Boolean = item.detailUrl == other.item.detailUrl override fun itemSameAs(other: RepoRvItem): Boolean = item.id == other.item.id
} }
\ No newline at end of file
package com.topjohnwu.magisk.ui.module package com.topjohnwu.magisk.ui.module
import android.content.res.Resources import android.content.res.Resources
import android.database.Cursor
import androidx.annotation.StringRes
import com.skoumal.teanity.databinding.ComparableRvItem import com.skoumal.teanity.databinding.ComparableRvItem
import com.skoumal.teanity.extensions.addOnPropertyChangedCallback import com.skoumal.teanity.extensions.addOnPropertyChangedCallback
import com.skoumal.teanity.extensions.doOnSuccessUi
import com.skoumal.teanity.extensions.subscribeK import com.skoumal.teanity.extensions.subscribeK
import com.skoumal.teanity.util.DiffObservableList import com.skoumal.teanity.util.DiffObservableList
import com.skoumal.teanity.util.KObservableField import com.skoumal.teanity.util.KObservableField
...@@ -22,7 +19,9 @@ import com.topjohnwu.magisk.ui.base.MagiskViewModel ...@@ -22,7 +19,9 @@ import com.topjohnwu.magisk.ui.base.MagiskViewModel
import com.topjohnwu.magisk.utils.toSingle import com.topjohnwu.magisk.utils.toSingle
import com.topjohnwu.magisk.utils.update import com.topjohnwu.magisk.utils.update
import com.topjohnwu.magisk.utils.zip import com.topjohnwu.magisk.utils.zip
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import me.tatarka.bindingcollectionadapter2.OnItemBind import me.tatarka.bindingcollectionadapter2.OnItemBind
class ModuleViewModel( class ModuleViewModel(
...@@ -61,11 +60,16 @@ class ModuleViewModel( ...@@ -61,11 +60,16 @@ class ModuleViewModel(
.map { ModuleRvItem(it) } .map { ModuleRvItem(it) }
.toList() .toList()
.map { it to itemsInstalled.calculateDiff(it) } .map { it to itemsInstalled.calculateDiff(it) }
.doOnSuccessUi { itemsInstalled.update(it.first, it.second) }
val updateRemote = moduleRepo.fetchModules(forceReload) val updateRemote = moduleRepo.fetchModules(forceReload)
zip(updateInstalled, updateRemote) { _, remote -> remote } zip(updateInstalled, updateRemote) { installed, remote -> installed to remote }
.observeOn(AndroidSchedulers.mainThread())
.map {
itemsInstalled.update(it.first.first, it.first.second)
it.second
}
.observeOn(Schedulers.computation())
.flattenAsFlowable { it } .flattenAsFlowable { it }
.map { RepoRvItem(it) } .map { RepoRvItem(it) }
.toList() .toList()
...@@ -92,33 +96,26 @@ class ModuleViewModel( ...@@ -92,33 +96,26 @@ class ModuleViewModel(
private fun List<RepoRvItem>.divide(): List<ComparableRvItem<*>> { private fun List<RepoRvItem>.divide(): List<ComparableRvItem<*>> {
val installed = itemsInstalled.filterIsInstance<ModuleRvItem>() val installed = itemsInstalled.filterIsInstance<ModuleRvItem>()
val installedModules = filter { installed.any { item -> it.item.id == item.item.id } }
fun installedByID(id: String) = installed.firstOrNull { it.item.id == id } fun <T : ComparableRvItem<*>> List<T>.withTitle(text: Int) =
if (isEmpty()) this else listOf(SectionRvItem(resources.getString(text))) + this
fun List<RepoRvItem>.filterObsolete() = filter { val groupedItems = groupBy { repo ->
val module = installedByID(it.item.id) ?: return@filter false installed.firstOrNull { it.item.id == repo.item.id }?.let {
module.item.versionCode != it.item.versionCode if (it.item.versionCode < repo.item.versionCode) MODULE_UPDATABLE
else MODULE_INSTALLED
} ?: MODULE_REMOTE
} }
val resultObsolete = installedModules.filterObsolete() return groupedItems.getOrElse(MODULE_UPDATABLE) { listOf() }.withTitle(R.string.update_available) +
val resultInstalled = installedModules - resultObsolete groupedItems.getOrElse(MODULE_INSTALLED) { listOf() }.withTitle(R.string.installed) +
val resultRemote = toList() - installedModules groupedItems.getOrElse(MODULE_REMOTE) { listOf() }.withTitle(R.string.not_installed)
fun buildList(@StringRes text: Int, list: List<RepoRvItem>): List<ComparableRvItem<*>> {
return if (list.isEmpty()) list
else listOf(SectionRvItem(resources.getString(text))) + list
}
return buildList(R.string.update_available, resultObsolete) +
buildList(R.string.installed, resultInstalled) +
buildList(R.string.not_installed, resultRemote)
} }
private fun <Result> Cursor.toList(transformer: (Cursor) -> Result): List<Result> { companion object {
val out = mutableListOf<Result>() protected const val MODULE_INSTALLED = 0
while (moveToNext()) out.add(transformer(this)) protected const val MODULE_REMOTE = 1
return out protected const val MODULE_UPDATABLE = 2
} }
} }
\ 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