From d29bfe8acbdc237dcdc02276fd4002171dfb9738 Mon Sep 17 00:00:00 2001 From: Rohan Date: Mon, 9 Mar 2026 19:42:16 +0530 Subject: [PATCH 1/2] fix: added incompatible version disclaimer for such apps --- .../droidify/ui/appDetail/AppDetailAdapter.kt | 13 ++++++++ .../ui/appDetail/AppDetailFragment.kt | 3 ++ app/src/main/res/layout/install_button.xml | 32 +++++++++++++++---- 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/app/src/main/kotlin/com/looker/droidify/ui/appDetail/AppDetailAdapter.kt b/app/src/main/kotlin/com/looker/droidify/ui/appDetail/AppDetailAdapter.kt index daad5916e..520bf6a38 100644 --- a/app/src/main/kotlin/com/looker/droidify/ui/appDetail/AppDetailAdapter.kt +++ b/app/src/main/kotlin/com/looker/droidify/ui/appDetail/AppDetailAdapter.kt @@ -446,6 +446,7 @@ class AppDetailAdapter(private val callbacks: Callbacks) : private class InstallButtonViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val button = itemView.findViewById(R.id.action)!! + val incompatibleText = itemView.findViewById(R.id.incompatible_text)!! val actionTintNormal = button.context.getColorFromAttr(android.R.attr.colorPrimary) val actionTintOnNormal = button.context.getColorFromAttr(MaterialR.attr.colorOnPrimary) @@ -1120,6 +1121,15 @@ class AppDetailAdapter(private val callbacks: Callbacks) : field = value } + var isIncompatible: Boolean = false + set(value) { + if (field != value) { + field = value + val index = items.indexOf(Item.InstallButtonItem) + if (index > 0) notifyItemChanged(index) + } + } + var status: Status = Status.Idle set(value) { if (field != value) { @@ -1437,6 +1447,9 @@ class AppDetailAdapter(private val callbacks: Callbacks) : ViewType.INSTALL_BUTTON -> { holder as InstallButtonViewHolder item as Item.InstallButtonItem + + holder.incompatibleText.isVisible = isIncompatible + val action = action holder.button.apply { isEnabled = action != null diff --git a/app/src/main/kotlin/com/looker/droidify/ui/appDetail/AppDetailFragment.kt b/app/src/main/kotlin/com/looker/droidify/ui/appDetail/AppDetailFragment.kt index 0bc804de8..34f3d2cd3 100644 --- a/app/src/main/kotlin/com/looker/droidify/ui/appDetail/AppDetailFragment.kt +++ b/app/src/main/kotlin/com/looker/droidify/ui/appDetail/AppDetailFragment.kt @@ -249,6 +249,9 @@ class AppDetailFragment() : ScreenFragment(), AppDetailAdapter.Callbacks { val canLaunch = product != null && installed != null && installed.launcherActivities.isNotEmpty() + val isIncompatible = product != null && installed == null && !compatible + (recyclerView?.adapter as? AppDetailAdapter)?.isIncompatible = isIncompatible + val actions = buildSet { if (canInstall) add(Action.INSTALL) if (canUpdate) add(Action.UPDATE) diff --git a/app/src/main/res/layout/install_button.xml b/app/src/main/res/layout/install_button.xml index ba392681d..791f1250a 100644 --- a/app/src/main/res/layout/install_button.xml +++ b/app/src/main/res/layout/install_button.xml @@ -1,8 +1,28 @@ - \ No newline at end of file + android:layout_height="wrap_content" + android:orientation="vertical" + android:paddingHorizontal="16dp" + android:paddingVertical="8dp"> + + + + + + From 1bc9ef6b101fa1f945f36fba7bca5611d87605ac Mon Sep 17 00:00:00 2001 From: Rohan Date: Tue, 10 Mar 2026 18:48:31 +0530 Subject: [PATCH 2/2] fix: shows the reason for incompatiblity --- .../droidify/ui/appDetail/AppDetailAdapter.kt | 5 ++- .../ui/appDetail/AppDetailFragment.kt | 37 ++++++++++++++++++- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/app/src/main/kotlin/com/looker/droidify/ui/appDetail/AppDetailAdapter.kt b/app/src/main/kotlin/com/looker/droidify/ui/appDetail/AppDetailAdapter.kt index 520bf6a38..d61eb2584 100644 --- a/app/src/main/kotlin/com/looker/droidify/ui/appDetail/AppDetailAdapter.kt +++ b/app/src/main/kotlin/com/looker/droidify/ui/appDetail/AppDetailAdapter.kt @@ -1121,7 +1121,7 @@ class AppDetailAdapter(private val callbacks: Callbacks) : field = value } - var isIncompatible: Boolean = false + var incompatibilityReason: CharSequence? = null set(value) { if (field != value) { field = value @@ -1448,7 +1448,8 @@ class AppDetailAdapter(private val callbacks: Callbacks) : holder as InstallButtonViewHolder item as Item.InstallButtonItem - holder.incompatibleText.isVisible = isIncompatible + holder.incompatibleText.isVisible = incompatibilityReason != null + holder.incompatibleText.text = incompatibilityReason ?: "" val action = action holder.button.apply { diff --git a/app/src/main/kotlin/com/looker/droidify/ui/appDetail/AppDetailFragment.kt b/app/src/main/kotlin/com/looker/droidify/ui/appDetail/AppDetailFragment.kt index 34f3d2cd3..14135688a 100644 --- a/app/src/main/kotlin/com/looker/droidify/ui/appDetail/AppDetailFragment.kt +++ b/app/src/main/kotlin/com/looker/droidify/ui/appDetail/AppDetailFragment.kt @@ -48,6 +48,8 @@ import com.looker.droidify.utility.common.extension.isSystemApplication import com.looker.droidify.utility.common.extension.systemBarsPadding import com.looker.droidify.utility.common.extension.updateAsMutable import com.looker.droidify.utility.common.shareUrl +import com.looker.droidify.utility.extension.android.Android.name +import com.looker.droidify.utility.extension.android.Android.primaryPlatform import com.looker.droidify.utility.extension.mainActivity import com.looker.droidify.utility.extension.startUpdate import com.stfalcon.imageviewer.StfalconImageViewer @@ -249,8 +251,39 @@ class AppDetailFragment() : ScreenFragment(), AppDetailAdapter.Callbacks { val canLaunch = product != null && installed != null && installed.launcherActivities.isNotEmpty() - val isIncompatible = product != null && installed == null && !compatible - (recyclerView?.adapter as? AppDetailAdapter)?.isIncompatible = isIncompatible + val incompatibilityReason = if (product != null) { + val selectedRelease = product.selectedReleases.firstOrNull() + val incompatibility = selectedRelease?.incompatibilities?.firstOrNull() + val installedItem = installed?.installedItem + + when { + incompatibility != null -> { + when (incompatibility) { + is Release.Incompatibility.MinSdk, + is Release.Incompatibility.MaxSdk -> getString( + stringRes.incompatible_with_FORMAT, + name + ) + is Release.Incompatibility.Platform -> getString( + stringRes.incompatible_with_FORMAT, + primaryPlatform ?: getString(stringRes.unknown) + ) + is Release.Incompatibility.Feature -> getString( + stringRes.requires_FORMAT, + incompatibility.feature + ) + } + } + installedItem != null && selectedRelease != null && installedItem.signature != selectedRelease.signature -> { + getString(stringRes.incompatible_signature_DESC) + } + else -> null + } + } else { + null + } + + (recyclerView?.adapter as? AppDetailAdapter)?.incompatibilityReason = incompatibilityReason val actions = buildSet { if (canInstall) add(Action.INSTALL)