Fixed inconsistent displaying of repos and improved their sorting

This commit is contained in:
Viktor De Pasquale 2019-05-25 18:09:45 +02:00
parent 8cd3b603df
commit 6a243ec7bc
3 changed files with 30 additions and 28 deletions

View File

@ -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 {

View File

@ -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>() {
&& 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
} }

View File

@ -1,11 +1,8 @@
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
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(
.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(
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) + companion object {
buildList(R.string.installed, resultInstalled) + protected const val MODULE_INSTALLED = 0
buildList(R.string.not_installed, resultRemote) protected const val MODULE_REMOTE = 1
} protected const val MODULE_UPDATABLE = 2
private fun <Result> Cursor.toList(transformer: (Cursor) -> Result): List<Result> {
val out = mutableListOf<Result>()
while (moveToNext()) out.add(transformer(this))
return out
} }
} }