diff --git a/src/main/kotlin/com/looker/droidify/index/IndexHandler.kt b/src/main/kotlin/com/looker/droidify/index/IndexHandler.kt index a354d39f..d14c7cd2 100644 --- a/src/main/kotlin/com/looker/droidify/index/IndexHandler.kt +++ b/src/main/kotlin/com/looker/droidify/index/IndexHandler.kt @@ -1,9 +1,9 @@ package com.looker.droidify.index +import com.looker.droidify.database.entity.Product import com.looker.droidify.database.entity.Release import com.looker.droidify.entity.Author import com.looker.droidify.entity.Donate -import com.looker.droidify.entity.Product import com.looker.droidify.utility.extension.android.Android import org.xml.sax.Attributes import org.xml.sax.helpers.DefaultHandler @@ -89,32 +89,30 @@ class IndexHandler(private val repositoryId: Long, private val callback: Callbac val donates = mutableListOf() val releases = mutableListOf() - fun build(): Product { - return Product( - repositoryId, - packageName, - name, - summary, - description, - "", - icon, - "", - Author(authorName, authorEmail, ""), - source, - changelog, - web, - tracker, - added, - updated, - suggestedVersionCode, - categories.toList(), - antiFeatures.toList(), - licenses, - donates.sortedWith(DonateComparator), - emptyList(), - releases - ) - } + fun build(): Product = Product( + repositoryId = repositoryId, + packageName = packageName, + name = name, + summary = summary, + description = description, + added = added, + updated = updated, + icon = icon, + metadataIcon = "", + releases = releases, + categories = categories.toList(), + antiFeatures = antiFeatures.toList(), + licenses = licenses, + donates = donates.sortedWith(DonateComparator), + screenshots = emptyList(), + suggestedVersionCode = suggestedVersionCode, + author = Author(authorName, authorEmail, ""), + source = source, + web = web, + tracker = tracker, + changelog = changelog, + whatsNew = "" + ) } private class ReleaseBuilder { diff --git a/src/main/kotlin/com/looker/droidify/index/IndexMerger.kt b/src/main/kotlin/com/looker/droidify/index/IndexMerger.kt index 5528d763..08ed7604 100644 --- a/src/main/kotlin/com/looker/droidify/index/IndexMerger.kt +++ b/src/main/kotlin/com/looker/droidify/index/IndexMerger.kt @@ -4,8 +4,8 @@ import android.content.ContentValues import android.database.sqlite.SQLiteDatabase import com.looker.droidify.database.Converters.toByteArray import com.looker.droidify.database.Converters.toReleases +import com.looker.droidify.database.entity.Product import com.looker.droidify.database.entity.Release -import com.looker.droidify.entity.Product import com.looker.droidify.utility.extension.android.asSequence import com.looker.droidify.utility.extension.android.execWithResult import java.io.ByteArrayOutputStream @@ -67,8 +67,11 @@ class IndexMerger(file: File) : Closeable { this.repositoryId = repositoryId this.description = description } - val releases = it.getBlob(2)?.let { toReleases(it) }.orEmpty() - product.copy(releases = releases) + val releases = it.getBlob(2)?.let(::toReleases).orEmpty() + product.apply { + this.releases = releases + refreshVariables() + } }.windowed(windowSize, windowSize, true) .forEach { products -> callback(products, it.count) } } diff --git a/src/main/kotlin/com/looker/droidify/index/IndexV1Parser.kt b/src/main/kotlin/com/looker/droidify/index/IndexV1Parser.kt index 56b76059..838439d1 100644 --- a/src/main/kotlin/com/looker/droidify/index/IndexV1Parser.kt +++ b/src/main/kotlin/com/looker/droidify/index/IndexV1Parser.kt @@ -2,10 +2,10 @@ package com.looker.droidify.index import com.fasterxml.jackson.core.JsonParser import com.fasterxml.jackson.core.JsonToken +import com.looker.droidify.database.entity.Product import com.looker.droidify.database.entity.Release import com.looker.droidify.entity.Author import com.looker.droidify.entity.Donate -import com.looker.droidify.entity.Product import com.looker.droidify.entity.Screenshot import com.looker.droidify.utility.extension.android.Android import com.looker.droidify.utility.extension.json.* @@ -217,28 +217,28 @@ object IndexV1Parser { } .orEmpty().toList() return Product( - repositoryId, - packageName, - name, - summary, - description, - whatsNew, - icon, - metadataIcon, - Author(authorName, authorEmail, authorWeb), - source, - changelog, - web, - tracker, - added, - updated, - suggestedVersionCode, - categories, - antiFeatures, - licenses, - donates.sortedWith(IndexHandler.DonateComparator), - screenshots, - emptyList() + repositoryId = repositoryId, + packageName = packageName, + name = name, + summary = summary, + description = description, + added = added, + updated = updated, + icon = icon, + metadataIcon = metadataIcon, + releases = emptyList(), + categories = categories, + antiFeatures = antiFeatures, + licenses = licenses, + donates = donates.sortedWith(IndexHandler.DonateComparator), + screenshots = screenshots, + suggestedVersionCode = suggestedVersionCode, + author = Author(authorName, authorEmail, authorWeb), + source = source, + web = web, + tracker = tracker, + changelog = changelog, + whatsNew = whatsNew ) } diff --git a/src/main/kotlin/com/looker/droidify/index/RepositoryUpdater.kt b/src/main/kotlin/com/looker/droidify/index/RepositoryUpdater.kt index ac090f01..b05c1888 100644 --- a/src/main/kotlin/com/looker/droidify/index/RepositoryUpdater.kt +++ b/src/main/kotlin/com/looker/droidify/index/RepositoryUpdater.kt @@ -4,9 +4,9 @@ import android.content.Context import android.net.Uri import com.looker.droidify.content.Cache import com.looker.droidify.database.DatabaseX +import com.looker.droidify.database.entity.Product import com.looker.droidify.database.entity.Release import com.looker.droidify.database.entity.Repository -import com.looker.droidify.entity.Product import com.looker.droidify.network.Downloader import com.looker.droidify.utility.ProgressInputStream import com.looker.droidify.utility.RxUtils @@ -469,6 +469,9 @@ object RepositoryUpdater { .copy(incompatibilities = incompatibilities, selected = firstSelected ?.let { it.first.versionCode == release.versionCode && it.second == incompatibilities } == true) } - return product.copy(releases = releases) + return product.apply { + this.releases = releases + refreshVariables() + } } } diff --git a/src/main/kotlin/com/looker/droidify/screen/ScreenshotsFragment.kt b/src/main/kotlin/com/looker/droidify/screen/ScreenshotsFragment.kt index 4ba15933..328d4988 100644 --- a/src/main/kotlin/com/looker/droidify/screen/ScreenshotsFragment.kt +++ b/src/main/kotlin/com/looker/droidify/screen/ScreenshotsFragment.kt @@ -136,7 +136,7 @@ class ScreenshotsFragment() : DialogFragment() { .observeOn(Schedulers.io()) .flatMapSingle { RxUtils.querySingle { - db.productDao.get(packageName).mapNotNull { it?.data } + db.productDao.get(packageName).filterNotNull() } } .map { it -> diff --git a/src/main/kotlin/com/looker/droidify/service/SyncService.kt b/src/main/kotlin/com/looker/droidify/service/SyncService.kt index bfc38386..7ce28ab4 100644 --- a/src/main/kotlin/com/looker/droidify/service/SyncService.kt +++ b/src/main/kotlin/com/looker/droidify/service/SyncService.kt @@ -458,8 +458,9 @@ class SyncService : ConnectionService() { val repository = installedRepository.third!! val productRepository = db.productDao.get(packageName) - .map { product -> Pair(product?.data!!, repository) } + .filterNotNull() .filter { product -> product.repositoryId == repository.id } + .map { product -> Pair(product, repository) } scope.launch { Utils.startUpdate( diff --git a/src/main/kotlin/com/looker/droidify/ui/adapters/AppDetailAdapter.kt b/src/main/kotlin/com/looker/droidify/ui/adapters/AppDetailAdapter.kt index 9200654f..19ef3288 100644 --- a/src/main/kotlin/com/looker/droidify/ui/adapters/AppDetailAdapter.kt +++ b/src/main/kotlin/com/looker/droidify/ui/adapters/AppDetailAdapter.kt @@ -44,9 +44,9 @@ import com.looker.droidify.R import com.looker.droidify.content.Preferences import com.looker.droidify.content.ProductPreferences import com.looker.droidify.database.entity.Installed +import com.looker.droidify.database.entity.Product import com.looker.droidify.database.entity.Release import com.looker.droidify.database.entity.Repository -import com.looker.droidify.entity.Product import com.looker.droidify.entity.ProductPreference import com.looker.droidify.entity.Screenshot import com.looker.droidify.network.CoilDownloader @@ -60,6 +60,7 @@ import com.looker.droidify.utility.extension.text.formatSize import com.looker.droidify.utility.extension.text.nullIfEmpty import com.looker.droidify.utility.extension.text.trimAfter import com.looker.droidify.utility.extension.text.trimBefore +import com.looker.droidify.utility.findSuggestedProduct import com.looker.droidify.widget.StableRecyclerAdapter import org.intellij.markdown.flavours.commonmark.CommonMarkFlavourDescriptor import org.intellij.markdown.html.HtmlGenerator @@ -554,7 +555,7 @@ class AppDetailAdapter(private val callbacks: Callbacks) : context: Context, packageName: String, products: List>, installed: Installed?, ) { - val productRepository = Product.findSuggested(products, installed) { it.first } + val productRepository = findSuggestedProduct(products, installed) { it.first } items.clear() if (productRepository != null) { diff --git a/src/main/kotlin/com/looker/droidify/ui/fragments/AppDetailFragment.kt b/src/main/kotlin/com/looker/droidify/ui/fragments/AppDetailFragment.kt index 19c3e791..cfc9b885 100644 --- a/src/main/kotlin/com/looker/droidify/ui/fragments/AppDetailFragment.kt +++ b/src/main/kotlin/com/looker/droidify/ui/fragments/AppDetailFragment.kt @@ -17,9 +17,9 @@ import androidx.recyclerview.widget.RecyclerView import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.looker.droidify.R import com.looker.droidify.content.ProductPreferences +import com.looker.droidify.database.entity.Product import com.looker.droidify.database.entity.Release import com.looker.droidify.database.entity.Repository -import com.looker.droidify.entity.Product import com.looker.droidify.entity.ProductPreference import com.looker.droidify.entity.Screenshot import com.looker.droidify.installer.AppInstaller @@ -36,6 +36,7 @@ import com.looker.droidify.utility.Utils.rootInstallerEnabled import com.looker.droidify.utility.Utils.startUpdate import com.looker.droidify.utility.extension.android.Android import com.looker.droidify.utility.extension.text.trimAfter +import com.looker.droidify.utility.findSuggestedProduct import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.core.Observable import io.reactivex.rxjava3.disposables.Disposable @@ -142,7 +143,7 @@ class AppDetailFragment() : ScreenFragment(), AppDetailAdapter.Callbacks { .observeOn(Schedulers.io()) .flatMapSingle { RxUtils.querySingle { - screenActivity.db.productDao.get(packageName).mapNotNull { it?.data } + screenActivity.db.productDao.get(packageName).filterNotNull() } } .flatMapSingle { products -> @@ -272,8 +273,7 @@ class AppDetailFragment() : ScreenFragment(), AppDetailAdapter.Callbacks { private suspend fun updateButtons(preference: ProductPreference) = withContext(Dispatchers.Default) { val installed = installed - val product = - Product.findSuggested(products, installed?.data) { it.first }?.first + val product = findSuggestedProduct(products, installed?.data) { it.first }?.first val compatible = product != null && product.selectedReleases.firstOrNull() .let { it != null && it.incompatibilities.isEmpty() } val canInstall = product != null && installed == null && compatible diff --git a/src/main/kotlin/com/looker/droidify/ui/fragments/AppSheetX.kt b/src/main/kotlin/com/looker/droidify/ui/fragments/AppSheetX.kt index 11b2e3a7..93ffc584 100644 --- a/src/main/kotlin/com/looker/droidify/ui/fragments/AppSheetX.kt +++ b/src/main/kotlin/com/looker/droidify/ui/fragments/AppSheetX.kt @@ -18,10 +18,10 @@ import androidx.recyclerview.widget.LinearLayoutManager import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.looker.droidify.R import com.looker.droidify.content.ProductPreferences +import com.looker.droidify.database.entity.Product import com.looker.droidify.database.entity.Release import com.looker.droidify.database.entity.Repository import com.looker.droidify.databinding.SheetAppXBinding -import com.looker.droidify.entity.Product import com.looker.droidify.entity.ProductPreference import com.looker.droidify.entity.Screenshot import com.looker.droidify.installer.AppInstaller @@ -34,6 +34,7 @@ import com.looker.droidify.ui.viewmodels.AppViewModelX import com.looker.droidify.utility.Utils.rootInstallerEnabled import com.looker.droidify.utility.Utils.startUpdate import com.looker.droidify.utility.extension.android.Android +import com.looker.droidify.utility.findSuggestedProduct import io.reactivex.rxjava3.disposables.Disposable import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.filter @@ -153,7 +154,7 @@ class AppSheetX() : FullscreenBottomSheetDialogFragment(), AppDetailAdapter.Call if (it.isNotEmpty() && products.isNotEmpty()) updateSheet() } viewModel.products.observe(viewLifecycleOwner) { - products = it.mapNotNull { it?.trueData } + products = it.filterNotNull() viewModel.repositories.value?.let { repos -> if (repos.isNotEmpty() && products.isNotEmpty()) updateSheet() } @@ -203,8 +204,7 @@ class AppSheetX() : FullscreenBottomSheetDialogFragment(), AppDetailAdapter.Call private suspend fun updateButtons(preference: ProductPreference) = withContext(Dispatchers.Default) { val installed = installed - val product = - Product.findSuggested(productRepos, installed?.data) { it.first }?.first + val product = findSuggestedProduct(productRepos, installed?.data) { it.first }?.first val compatible = product != null && product.selectedReleases.firstOrNull() .let { it != null && it.incompatibilities.isEmpty() } val canInstall = product != null && installed == null && compatible diff --git a/src/main/kotlin/com/looker/droidify/utility/Utils.kt b/src/main/kotlin/com/looker/droidify/utility/Utils.kt index 5f8f8482..40f17117 100644 --- a/src/main/kotlin/com/looker/droidify/utility/Utils.kt +++ b/src/main/kotlin/com/looker/droidify/utility/Utils.kt @@ -13,8 +13,8 @@ import com.looker.droidify.PREFS_LANGUAGE_DEFAULT import com.looker.droidify.R import com.looker.droidify.content.Preferences import com.looker.droidify.database.entity.Installed +import com.looker.droidify.database.entity.Product import com.looker.droidify.database.entity.Repository -import com.looker.droidify.entity.Product import com.looker.droidify.service.Connection import com.looker.droidify.service.DownloadService import com.looker.droidify.utility.extension.android.Android @@ -84,7 +84,7 @@ object Utils { products: List>, downloadConnection: Connection, ) { - val productRepository = Product.findSuggested(products, installed) { it.first } + val productRepository = findSuggestedProduct(products, installed) { it.first } val compatibleReleases = productRepository?.first?.selectedReleases.orEmpty() .filter { installed == null || installed.signature == it.signature } val releaseFlow = MutableStateFlow(compatibleReleases.firstOrNull()) @@ -169,6 +169,17 @@ object Utils { } +fun findSuggestedProduct( + products: List, + installed: Installed?, + extract: (T) -> Product, +): T? { + return products.maxWithOrNull(compareBy({ + extract(it).compatible && + (installed == null || installed.signature in extract(it).signatures) + }, { extract(it).versionCode })) +} + val isDarkTheme: Boolean get() = when (Preferences[Preferences.Key.Theme]) { is Preferences.Theme.Light -> false