mirror of
https://github.com/Michatec/michas-droid.git
synced 2026-05-30 18:02:43 +02:00
Display compatibility information
This commit is contained in:
@@ -218,9 +218,9 @@ class IndexHandler(private val repositoryId: Long, private val callback: Callbac
|
||||
"obbMainFileSha256" -> releaseBuilder.obbMainHash = content
|
||||
"obbPatchFile" -> releaseBuilder.obbPatch = content
|
||||
"obbPatchFileSha256" -> releaseBuilder.obbPatchHash = content
|
||||
"permissions" -> releaseBuilder.permissions += content.split(',')
|
||||
"features" -> releaseBuilder.features += content.split(',')
|
||||
"nativecode" -> releaseBuilder.platforms += content.split(',')
|
||||
"permissions" -> releaseBuilder.permissions += content.split(',').filter { it.isNotEmpty() }
|
||||
"features" -> releaseBuilder.features += content.split(',').filter { it.isNotEmpty() }
|
||||
"nativecode" -> releaseBuilder.platforms += content.split(',').filter { it.isNotEmpty() }
|
||||
}
|
||||
}
|
||||
productBuilder != null -> {
|
||||
@@ -239,9 +239,9 @@ class IndexHandler(private val repositoryId: Long, private val callback: Callbac
|
||||
"added" -> productBuilder.added = content.parseDate()
|
||||
"lastupdated" -> productBuilder.updated = content.parseDate()
|
||||
"marketvercode" -> productBuilder.suggestedVersionCode = content.toLongOrNull() ?: 0L
|
||||
"categories" -> productBuilder.categories += content.split(',')
|
||||
"antifeatures" -> productBuilder.antiFeatures += content.split(',')
|
||||
"license" -> productBuilder.licenses += content.split(',')
|
||||
"categories" -> productBuilder.categories += content.split(',').filter { it.isNotEmpty() }
|
||||
"antifeatures" -> productBuilder.antiFeatures += content.split(',').filter { it.isNotEmpty() }
|
||||
"license" -> productBuilder.licenses += content.split(',').filter { it.isNotEmpty() }
|
||||
"donate" -> productBuilder.donates += Product.Donate.Regular(content)
|
||||
"bitcoin" -> productBuilder.donates += Product.Donate.Bitcoin(content)
|
||||
"litecoin" -> productBuilder.donates += Product.Donate.Litecoin(content)
|
||||
|
||||
@@ -49,7 +49,7 @@ object IndexV1Parser {
|
||||
forEachKey {
|
||||
when {
|
||||
it.string("address") -> address = valueAsString
|
||||
it.array("mirrors") -> mirrors = collectNotNullStrings()
|
||||
it.array("mirrors") -> mirrors = collectDistinctNotEmptyStrings()
|
||||
it.string("name") -> name = valueAsString
|
||||
it.string("description") -> description = valueAsString
|
||||
it.number("version") -> version = valueAsInt
|
||||
@@ -117,9 +117,9 @@ object IndexV1Parser {
|
||||
it.number("added") -> added = valueAsLong
|
||||
it.number("lastUpdated") -> updated = valueAsLong
|
||||
it.string("suggestedVersionCode") -> suggestedVersionCode = valueAsString.toLongOrNull() ?: 0L
|
||||
it.array("categories") -> categories = collectNotNullStrings()
|
||||
it.array("antiFeatures") -> antiFeatures = collectNotNullStrings()
|
||||
it.string("license") -> licenses += valueAsString.split(',')
|
||||
it.array("categories") -> categories = collectDistinctNotEmptyStrings()
|
||||
it.array("antiFeatures") -> antiFeatures = collectDistinctNotEmptyStrings()
|
||||
it.string("license") -> licenses += valueAsString.split(',').filter { it.isNotEmpty() }
|
||||
it.string("donate") -> donates += Product.Donate.Regular(valueAsString)
|
||||
it.string("bitcoin") -> donates += Product.Donate.Bitcoin(valueAsString)
|
||||
it.string("flattrID") -> donates += Product.Donate.Flattr(valueAsString)
|
||||
@@ -140,9 +140,9 @@ object IndexV1Parser {
|
||||
it.string("summary") -> summary = valueAsString
|
||||
it.string("description") -> description = valueAsString
|
||||
it.string("whatsNew") -> whatsNew = valueAsString
|
||||
it.array("phoneScreenshots") -> phone = collectNotNullStrings()
|
||||
it.array("sevenInchScreenshots") -> smallTablet = collectNotNullStrings()
|
||||
it.array("tenInchScreenshots") -> largeTablet = collectNotNullStrings()
|
||||
it.array("phoneScreenshots") -> phone = collectDistinctNotEmptyStrings()
|
||||
it.array("sevenInchScreenshots") -> smallTablet = collectDistinctNotEmptyStrings()
|
||||
it.array("tenInchScreenshots") -> largeTablet = collectDistinctNotEmptyStrings()
|
||||
else -> skipChildren()
|
||||
}
|
||||
}
|
||||
@@ -215,8 +215,8 @@ object IndexV1Parser {
|
||||
it.string("obbPatchFileSha256") -> obbPatchHash = valueAsString
|
||||
it.array("uses-permission") -> collectPermissions(permissions, 0)
|
||||
it.array("uses-permission-sdk-23") -> collectPermissions(permissions, 23)
|
||||
it.array("features") -> features = collectNotNullStrings()
|
||||
it.array("nativecode") -> platforms = collectNotNullStrings()
|
||||
it.array("features") -> features = collectDistinctNotEmptyStrings()
|
||||
it.array("nativecode") -> platforms = collectDistinctNotEmptyStrings()
|
||||
else -> skipChildren()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -332,9 +332,31 @@ object RepositoryUpdater {
|
||||
|
||||
val predicate: (Release) -> Boolean = { unstable || product.suggestedVersionCode <= 0 ||
|
||||
it.versionCode <= product.suggestedVersionCode }
|
||||
val compatibleReleaseIndex = releasePairs.indexOfFirst { it.second.isEmpty() && predicate(it.first) }
|
||||
val releaseIndex = if (compatibleReleaseIndex >= 0) compatibleReleaseIndex else
|
||||
val firstCompatibleReleaseIndex = releasePairs.indexOfFirst { it.second.isEmpty() && predicate(it.first) }
|
||||
val releaseIndex = if (firstCompatibleReleaseIndex >= 0) {
|
||||
val versionCode = releasePairs[firstCompatibleReleaseIndex].first.versionCode
|
||||
val candidates = releasePairs.mapIndexedNotNull { index, (product, incompatibilities) ->
|
||||
if (product.versionCode == versionCode && incompatibilities.isEmpty()) index else null
|
||||
}
|
||||
if (product.packageName == "org.telegram.messenger") {
|
||||
val x = candidates
|
||||
.filter { releasePairs[it].first.platforms.contains(Android.primaryPlatform) }
|
||||
.minBy { releasePairs[it].first.platforms.size }
|
||||
val y = candidates.minBy { releasePairs[it].first.platforms.size }
|
||||
debug("telegram $firstCompatibleReleaseIndex $candidates $x $y")
|
||||
}
|
||||
if (candidates.size <= 1) {
|
||||
firstCompatibleReleaseIndex
|
||||
} else {
|
||||
candidates
|
||||
.filter { releasePairs[it].first.platforms.contains(Android.primaryPlatform) }
|
||||
.minBy { releasePairs[it].first.platforms.size }
|
||||
?: candidates.minBy { releasePairs[it].first.platforms.size }
|
||||
?: firstCompatibleReleaseIndex
|
||||
}
|
||||
} else {
|
||||
releasePairs.indexOfFirst { predicate(it.first) }
|
||||
}
|
||||
|
||||
val releases = releasePairs.mapIndexed { index, (release, incompatibilities) -> release
|
||||
.copy(incompatibilities = incompatibilities, selected = index == releaseIndex) }
|
||||
|
||||
@@ -250,8 +250,7 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int)
|
||||
get() = ViewType.SCREENSHOT
|
||||
}
|
||||
|
||||
class ReleaseItem(val repository: Repository, val release: Release,
|
||||
val selectedRepository: Boolean): Item() {
|
||||
class ReleaseItem(val repository: Repository, val release: Release, val selectedRepository: Boolean): Item() {
|
||||
override val descriptor: String
|
||||
get() = "release.${repository.id}.${release.identifier}"
|
||||
|
||||
@@ -456,10 +455,10 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int)
|
||||
val source = itemView.findViewById<TextView>(R.id.source)!!
|
||||
val added = itemView.findViewById<TextView>(R.id.added)!!
|
||||
val size = itemView.findViewById<TextView>(R.id.size)!!
|
||||
val error = itemView.findViewById<TextView>(R.id.error)!!
|
||||
val compatibility = itemView.findViewById<TextView>(R.id.compatibility)!!
|
||||
|
||||
val statefulViews: Sequence<View>
|
||||
get() = sequenceOf(itemView, version, status, source, added, size, error)
|
||||
get() = sequenceOf(itemView, version, status, source, added, size, compatibility)
|
||||
|
||||
val setStatusActive: (Boolean) -> Unit
|
||||
|
||||
@@ -748,18 +747,20 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int)
|
||||
}
|
||||
|
||||
val incompatible = Preferences[Preferences.Key.IncompatibleVersions]
|
||||
val releases = products.flatMap { (product, repository) -> product.releases
|
||||
.map { Item.ReleaseItem(repository, it, repository.id == productRepository?.second?.id) } }
|
||||
.filter { incompatible || it.release.incompatibilities.isEmpty() }
|
||||
val releaseItems = products.asSequence()
|
||||
.flatMap { (product, repository) -> product.releases.asSequence()
|
||||
.filter { incompatible || it.incompatibilities.isEmpty() }
|
||||
.map { Item.ReleaseItem(repository, it, repository.id == productRepository?.second?.id) } }
|
||||
.sortedByDescending { it.release.versionCode }
|
||||
if (releases.isNotEmpty()) {
|
||||
.toList()
|
||||
if (releaseItems.isNotEmpty()) {
|
||||
items += Item.SectionItem(SectionType.RELEASES)
|
||||
val maxReleases = 5
|
||||
if (releases.size > maxReleases && ExpandType.RELEASES !in expanded) {
|
||||
items += releases.take(maxReleases)
|
||||
items += Item.ExpandItem(ExpandType.RELEASES, false, releases.takeLast(releases.size - maxReleases))
|
||||
if (releaseItems.size > maxReleases && ExpandType.RELEASES !in expanded) {
|
||||
items += releaseItems.take(maxReleases)
|
||||
items += Item.ExpandItem(ExpandType.RELEASES, false, releaseItems.takeLast(releaseItems.size - maxReleases))
|
||||
} else {
|
||||
items += releases
|
||||
items += releaseItems
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1129,6 +1130,7 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int)
|
||||
holder as ReleaseViewHolder
|
||||
item as Item.ReleaseItem
|
||||
val incompatibility = item.release.incompatibilities.firstOrNull()
|
||||
val singlePlatform = if (item.release.platforms.size == 1) item.release.platforms.first() else null
|
||||
val installed = installedItem?.versionCode == item.release.versionCode &&
|
||||
installedItem?.signature == item.release.signature
|
||||
val suggested = incompatibility == null && item.release.selected && item.selectedRepository
|
||||
@@ -1150,15 +1152,20 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int)
|
||||
holder.added.text = holder.dateFormat.format(item.release.added)
|
||||
holder.added.setTextColor(primarySecondaryColor)
|
||||
holder.size.text = item.release.size.formatSize()
|
||||
holder.error.visibility = if (incompatibility != null) View.VISIBLE else View.GONE
|
||||
holder.compatibility.visibility = if (incompatibility != null || singlePlatform != null)
|
||||
View.VISIBLE else View.GONE
|
||||
if (incompatibility != null) {
|
||||
holder.error.text = when (incompatibility) {
|
||||
holder.compatibility.setTextColor(context.getColorFromAttr(R.attr.colorError))
|
||||
holder.compatibility.text = when (incompatibility) {
|
||||
is Release.Incompatibility.MinSdk,
|
||||
is Release.Incompatibility.MaxSdk -> context.getString(R.string.is_not_supported_format, Android.name)
|
||||
is Release.Incompatibility.Platform -> context.getString(R.string.is_not_supported_format,
|
||||
is Release.Incompatibility.MaxSdk -> context.getString(R.string.incompatible_with_format, Android.name)
|
||||
is Release.Incompatibility.Platform -> context.getString(R.string.incompatible_with_format,
|
||||
Android.primaryPlatform ?: context.getString(R.string.unknown))
|
||||
is Release.Incompatibility.Feature -> context.getString(R.string.requires_format, incompatibility.feature)
|
||||
}
|
||||
} else if (singlePlatform != null) {
|
||||
holder.compatibility.setTextColor(context.getColorFromAttr(android.R.attr.textColorSecondary))
|
||||
holder.compatibility.text = context.getString(R.string.compatible_with_only_format, singlePlatform)
|
||||
}
|
||||
val enabled = status == null
|
||||
holder.statefulViews.forEach { it.isEnabled = enabled }
|
||||
|
||||
@@ -77,6 +77,10 @@ fun JsonParser.collectNotNullStrings(): List<String> {
|
||||
return collectNotNull(JsonToken.VALUE_STRING) { valueAsString }
|
||||
}
|
||||
|
||||
fun JsonParser.collectDistinctNotEmptyStrings(): List<String> {
|
||||
return collectNotNullStrings().asSequence().filter { it.isNotEmpty() }.distinct().toList()
|
||||
}
|
||||
|
||||
inline fun <T> JsonParser.parseDictionary(callback: JsonParser.() -> T): T {
|
||||
if (nextToken() == JsonToken.START_OBJECT) {
|
||||
val result = callback()
|
||||
|
||||
@@ -96,10 +96,10 @@
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/error"
|
||||
android:id="@+id/compatibility"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?attr/colorError"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textSize="14sp"
|
||||
android:singleLine="true" />
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
<string name="cant_edit_sync_description">Cannot edit repository since it\'s syncing right now.</string>
|
||||
<string name="changelog">Changelog</string>
|
||||
<string name="checking_repository">Checking repository</string>
|
||||
<string name="compatible_with_only_format">Compatible with %s only</string>
|
||||
<string name="confirm_action">Confirm action</string>
|
||||
<string name="connecting">Connecting</string>
|
||||
<string name="dark">Dark</string>
|
||||
@@ -65,13 +66,13 @@
|
||||
<string name="incompatible_version">Incompatible version</string>
|
||||
<string name="incompatible_versions">Incompatible versions</string>
|
||||
<string name="incompatible_versions_summary">Show application versions incompatible with the device</string>
|
||||
<string name="incompatible_with_format">Incompatible with %s</string>
|
||||
<string name="install">Install</string>
|
||||
<string name="installed">Installed</string>
|
||||
<string name="installed_empty_summary">No applications installed</string>
|
||||
<string name="invalid_address">Invalid address</string>
|
||||
<string name="invalid_fingerprint_format">Invalid fingerprint format</string>
|
||||
<string name="invalid_username_format">Invalid username format</string>
|
||||
<string name="is_not_supported_format">%s is not supported</string>
|
||||
<string name="last_update">Last update</string>
|
||||
<string name="launch">Launch</string>
|
||||
<string name="license">License</string>
|
||||
|
||||
Reference in New Issue
Block a user