diff --git a/app/src/main/java/be/scri/helpers/ui/RatingHelper.kt b/app/src/main/java/be/scri/helpers/ui/RatingHelper.kt index 87823929..0f372b14 100644 --- a/app/src/main/java/be/scri/helpers/ui/RatingHelper.kt +++ b/app/src/main/java/be/scri/helpers/ui/RatingHelper.kt @@ -1,10 +1,12 @@ // SPDX-License-Identifier: GPL-3.0-or-later package be.scri.helpers.ui +import android.content.ActivityNotFoundException import android.content.Context import android.content.Intent import android.content.pm.PackageManager import android.net.Uri +import android.os.Build import android.util.Log import android.widget.Toast import androidx.activity.ComponentActivity @@ -20,6 +22,8 @@ import com.google.android.play.core.review.ReviewManagerFactory object RatingHelper { private const val INSTALLER_PLAY_STORE = "com.android.vending" private const val INSTALLER_FDROID = "org.fdroid.fdroid" + private const val INSTALLER_AMAZON = "com.amazon.venezia" + private const val INSTALLER_SAMSUNG = "com.sec.android.app.samsungapps" /** * Gets the package name of the app that installed this app. @@ -31,12 +35,32 @@ object RatingHelper { */ private fun getInstallSource(context: Context): String? = try { - context.packageManager.getInstallerPackageName(context.packageName) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + context.packageManager.getInstallSourceInfo(context.packageName).installingPackageName + } else { + @Suppress("DEPRECATION") + context.packageManager.getInstallerPackageName(context.packageName) + } } catch (e: PackageManager.NameNotFoundException) { Log.e("RatingHelper", "Failed to get install source", e) null } + /** + * Gets the store description text (e.g. "Rate us on Google Play Store"). + * + * @param context App context. + * @return String for the description. + */ + fun getStoreDesc(context: Context): String? = + when (getInstallSource(context)) { + INSTALLER_PLAY_STORE -> "Rate us on Google Play Store" + INSTALLER_FDROID -> "Rate us on F-Droid" + INSTALLER_AMAZON -> "Rate us on Amazon Appstore" + INSTALLER_SAMSUNG -> "Rate us on Galaxy Store" + else -> "Rate us on Google Play Store" + } + /** * Initiates the app rating process based on the installation source. * @@ -51,7 +75,8 @@ object RatingHelper { context: Context, activity: ComponentActivity, ) { - when (getInstallSource(context)) { + val installer = getInstallSource(context) + when (installer) { INSTALLER_PLAY_STORE -> { val reviewManager = ReviewManagerFactory.create(context) val request = reviewManager.requestReviewFlow() @@ -73,14 +98,43 @@ object RatingHelper { val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) try { context.startActivity(intent) - } catch (e: PackageManager.NameNotFoundException) { + } catch (e: ActivityNotFoundException) { Toast.makeText(context, "No browser found to open F-Droid page", Toast.LENGTH_SHORT).show() Log.e("RatingHelper", "Unable to open F-Droid link", e) } } + INSTALLER_AMAZON -> { + val url = "https://www.amazon.com/gp/mas/dl/android?p=${context.packageName}" + val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) + try { + context.startActivity(intent) + } catch (e: ActivityNotFoundException) { + Toast.makeText(context, "No browser found to open Amazon page", Toast.LENGTH_SHORT).show() + Log.e("RatingHelper", "Unable to open Amazon link", e) + } + } + + INSTALLER_SAMSUNG -> { + val url = "https://galaxystore.samsung.com/detail/${context.packageName}" + val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) + try { + context.startActivity(intent) + } catch (e: ActivityNotFoundException) { + Toast.makeText(context, "No browser found to open Galaxy Store page", Toast.LENGTH_SHORT).show() + Log.e("RatingHelper", "Unable to open Galaxy Store link", e) + } + } + else -> { - Toast.makeText(context, "Unknown installation source", Toast.LENGTH_SHORT).show() + val url = "https://play.google.com/store/apps/details?id=${context.packageName}" + val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) + try { + context.startActivity(intent) + } catch (e: ActivityNotFoundException) { + Toast.makeText(context, "No browser found to open Play Store page", Toast.LENGTH_SHORT).show() + Log.e("RatingHelper", "Unable to open Play Store link", e) + } } } } diff --git a/app/src/main/java/be/scri/ui/common/components/AboutPageItemComp.kt b/app/src/main/java/be/scri/ui/common/components/AboutPageItemComp.kt index 4bc29fc6..fa0aab14 100644 --- a/app/src/main/java/be/scri/ui/common/components/AboutPageItemComp.kt +++ b/app/src/main/java/be/scri/ui/common/components/AboutPageItemComp.kt @@ -36,6 +36,7 @@ fun AboutPageItemComp( trailingIcon: Int, onClick: () -> Unit, modifier: Modifier = Modifier, + descText: String? = null, altText: String? = null, ) { val semanticsModifier = @@ -72,12 +73,23 @@ fun AboutPageItemComp( contentDescription = "Leading Icon", ) Spacer(modifier = Modifier.width(8.dp)) - Text( - text = title, + androidx.compose.foundation.layout.Column( modifier = Modifier.weight(1f).padding(start = 4.dp), - color = MaterialTheme.colorScheme.onSurface, - style = MaterialTheme.typography.bodyMedium, - ) + ) { + Text( + text = title, + color = MaterialTheme.colorScheme.onSurface, + style = MaterialTheme.typography.bodyMedium, + ) + if (descText != null) { + Text( + text = descText, + color = Color.Gray, + style = MaterialTheme.typography.bodySmall, + modifier = Modifier.padding(top = 4.dp), + ) + } + } Icon( painter = painterResource(trailingIcon), modifier = diff --git a/app/src/main/java/be/scri/ui/common/components/ItemCardContainer.kt b/app/src/main/java/be/scri/ui/common/components/ItemCardContainer.kt index d92e4ab4..bfc948bb 100644 --- a/app/src/main/java/be/scri/ui/common/components/ItemCardContainer.kt +++ b/app/src/main/java/be/scri/ui/common/components/ItemCardContainer.kt @@ -64,6 +64,7 @@ fun ItemsCardContainer( is ScribeItem.ExternalLinkItem -> { AboutPageItemComp( title = stringResource(item.title), + descText = item.descText, altText = item.altText?.let { stringResource(it) }, leadingIcon = item.leadingIcon, trailingIcon = item.trailingIcon, diff --git a/app/src/main/java/be/scri/ui/models/ScribeItem.kt b/app/src/main/java/be/scri/ui/models/ScribeItem.kt index c52eaee9..1a56f28b 100644 --- a/app/src/main/java/be/scri/ui/models/ScribeItem.kt +++ b/app/src/main/java/be/scri/ui/models/ScribeItem.kt @@ -64,6 +64,7 @@ sealed class ScribeItem( data class ExternalLinkItem( override val title: Int, override val desc: Int? = null, + val descText: String? = null, override val altText: Int? = null, @DrawableRes val leadingIcon: Int, @DrawableRes val trailingIcon: Int, diff --git a/app/src/main/java/be/scri/ui/screens/about/AboutUtil.kt b/app/src/main/java/be/scri/ui/screens/about/AboutUtil.kt index 6eb6e342..5af84924 100644 --- a/app/src/main/java/be/scri/ui/screens/about/AboutUtil.kt +++ b/app/src/main/java/be/scri/ui/screens/about/AboutUtil.kt @@ -143,6 +143,7 @@ fun feedbackAndSupportList( } else { R.string.i18n_app_about_feedback_rate_scribe }, + descText = RatingHelper.getStoreDesc(context), trailingIcon = R.drawable.external_link, url = null, onClick = { onRateScribeClick() },