Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Emojis for the following are chosen based on [gitmoji](https://gitmoji.dev/).
- The application and community's relationship to the Wikimedia movement is explained in app ([#52](https://github.com/scribe-org/Scribe-Android/issues/52)).
- Vibrate on keypress and key click functionalities are included ([#405](https://github.com/scribe-org/Scribe-Android/issues/405), [#406](https://github.com/scribe-org/Scribe-Android/issues/406)).
- An in-app tutorial is provided to detail functionalities of the application ([#602](https://github.com/scribe-org/Scribe-Android/issues/602), [#615](https://github.com/scribe-org/Scribe-Android/issues/615), [#616](https://github.com/scribe-org/Scribe-Android/issues/616)).
- The user is able to easily rate the application ([#165](https://github.com/scribe-org/Scribe-Android/issues/165), [#640](https://github.com/scribe-org/Scribe-Android/issues/640)).
- The user is able to easily rate the application, with installer-aware routing to the appropriate store ([#165](https://github.com/scribe-org/Scribe-Android/issues/165), [#640](https://github.com/scribe-org/Scribe-Android/issues/640)).

### 🗃️ Data

Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG_CONJUGATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Emojis for the following are chosen based on [gitmoji](https://gitmoji.dev/).
- The Settings tab for the Scribe keyboard application was migrated to allow base settings for the app interface ([#562](https://github.com/scribe-org/Scribe-Android/issues/562)).
- The About tab for the Scribe keyboard application was migrated to provide information on the application and community ([#561](https://github.com/scribe-org/Scribe-Android/issues/561)).
- The application and community's relationship to the Wikimedia movement is explained in app ([#52](https://github.com/scribe-org/Scribe-Android/issues/52)).
- The user is able to easily rate the application ([#165](https://github.com/scribe-org/Scribe-Android/issues/165), [#640](https://github.com/scribe-org/Scribe-Android/issues/640)).
- The user is able to easily rate the application, with installer-aware routing to the appropriate store ([#165](https://github.com/scribe-org/Scribe-Android/issues/165), [#640](https://github.com/scribe-org/Scribe-Android/issues/640)).

### 🗃️ Data

Expand Down
71 changes: 66 additions & 5 deletions app/src/main/java/be/scri/helpers/ui/RatingHelper.kt
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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.
Expand All @@ -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.
*
Expand All @@ -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()
Expand All @@ -63,7 +88,14 @@ object RatingHelper {
.launchReviewFlow(activity, reviewInfo)
.addOnCompleteListener { }
} else {
Toast.makeText(context, "Failed to launch review flow", 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)
}
}
}
}
Expand All @@ -73,14 +105,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)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ fun AboutPageItemComp(
trailingIcon: Int,
onClick: () -> Unit,
modifier: Modifier = Modifier,
descText: String? = null,
altText: String? = null,
) {
val semanticsModifier =
Expand Down Expand Up @@ -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 =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions app/src/main/java/be/scri/ui/models/ScribeItem.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions app/src/main/java/be/scri/ui/screens/about/AboutUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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() },
Expand Down
Loading