Skip to content

Commit

Permalink
Update the app menu
Browse files Browse the repository at this point in the history
- Include app feedback and privacy policy
- Update the email structure
  • Loading branch information
fibelatti committed Nov 26, 2024
1 parent b725977 commit fcae002
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 35 deletions.
4 changes: 0 additions & 4 deletions app/src/main/kotlin/com/fibelatti/pinboard/core/AppConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ package com.fibelatti.pinboard.core

object AppConfig {

const val MAIN_PACKAGE_NAME = "com.fibelatti.pinboard"

const val API_ENCODING = "UTF-8"

const val API_BASE_URL_LENGTH = 90
Expand All @@ -17,8 +15,6 @@ object AppConfig {

const val PINBOARD_USER_URL = "https://pinboard.in/u:"

const val PLAY_STORE_BASE_URL = "https://play.google.com/store/apps/details?id="

val LOGIN_FAILED_CODES: List<Int> = listOf(401, 500)

object PinboardApiLiterals {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package com.fibelatti.pinboard.core.android.composable

import android.content.Intent
import android.net.Uri
import android.os.Build
import android.widget.Toast
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
Expand All @@ -17,9 +18,14 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import com.fibelatti.pinboard.BuildConfig
import com.fibelatti.pinboard.R
import com.fibelatti.pinboard.core.AppModeProvider
import com.fibelatti.pinboard.core.extension.isServerException
import com.fibelatti.ui.preview.ThemePreviews
import com.fibelatti.ui.theme.ExtendedTheme
import dagger.hilt.EntryPoint
import dagger.hilt.InstallIn
import dagger.hilt.android.EntryPointAccessors
import dagger.hilt.components.SingletonComponent
import java.io.PrintWriter
import java.io.StringWriter

Expand Down Expand Up @@ -67,17 +73,28 @@ fun ErrorReportDialog(

Button(
onClick = {
val entryPoint = EntryPointAccessors.fromApplication(
context.applicationContext,
ErrorReportEntryPoint::class.java,
)
val appModeProvider = entryPoint.appModeProvider()

val sw = StringWriter()
throwable.printStackTrace(PrintWriter(sw))

val emailBody = "Hi, can you please look into this report?" +
"\n\nMy app version is ${BuildConfig.VERSION_NAME}" +
"\n\n$sw"
val emailIntent = Intent(Intent.ACTION_SENDTO).apply {
data = Uri.parse("mailto:")
putExtra(Intent.EXTRA_EMAIL, arrayOf("[email protected]"))
putExtra(Intent.EXTRA_SUBJECT, "Pinkt - Error Report")
putExtra(Intent.EXTRA_TEXT, emailBody)
val emailBody = StringBuilder().apply {
appendLine("Android Version: ${Build.VERSION.RELEASE} (SDK ${Build.VERSION.SDK_INT})")
appendLine("Current Service: ${appModeProvider.appMode.value}")
appendLine("---")
appendLine("This error just happened to me:")
appendLine()
append(sw.toString())
}

val emailIntent = Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:")).apply {
putExtra(Intent.EXTRA_EMAIL, arrayOf("[email protected]"))
putExtra(Intent.EXTRA_SUBJECT, "Pinkt (${BuildConfig.VERSION_NAME}) — Error Report")
putExtra(Intent.EXTRA_TEXT, emailBody.toString())
}

context.startActivity(Intent.createChooser(emailIntent, chooserTitle))
Expand All @@ -100,6 +117,13 @@ fun ErrorReportDialog(
)
}

@EntryPoint
@InstallIn(SingletonComponent::class)
interface ErrorReportEntryPoint {

fun appModeProvider(): AppModeProvider
}

@Composable
@ThemePreviews
private fun ErrorReportDialogPreview() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,70 @@ package com.fibelatti.pinboard.features.navigation

import android.content.Intent
import android.net.Uri
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import com.fibelatti.core.android.extension.shareText
import com.fibelatti.pinboard.BuildConfig
import com.fibelatti.pinboard.R
import com.fibelatti.pinboard.core.AppConfig
import com.fibelatti.pinboard.core.android.ComposeBottomSheetDialog
import com.fibelatti.pinboard.core.android.composable.ErrorReportEntryPoint
import com.fibelatti.pinboard.features.licenses.OssLicensesActivity
import dagger.hilt.android.EntryPointAccessors

object NavigationMenu {

private const val APP_URL = "https://play.google.com/store/apps/details?id=com.fibelatti.pinboard"
private const val PRIVACY_POLICY_URL = "https://fibelatti.github.io/pinboard-kotlin/"

fun show(activity: AppCompatActivity) {
ComposeBottomSheetDialog(activity) {
NavigationMenuScreen(
onSendFeedbackClicked = {
sendFeedback(activity)
},
onWriteReviewClicked = {
activity.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(APP_URL)))
},
onShareClicked = {
activity.shareText(
R.string.share_title,
context.getString(
R.string.share_text,
"${AppConfig.PLAY_STORE_BASE_URL}${AppConfig.MAIN_PACKAGE_NAME}",
),
title = R.string.share_title,
text = context.getString(R.string.share_text, APP_URL),
)
},
onRateClicked = {
val intent = Intent(Intent.ACTION_VIEW).apply {
data = Uri.parse("${AppConfig.PLAY_STORE_BASE_URL}${AppConfig.MAIN_PACKAGE_NAME}")
setPackage("com.android.vending")
}

activity.startActivity(intent)
onPrivacyPolicyClicked = {
activity.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(PRIVACY_POLICY_URL)))
},
onLicensesClicked = {
activity.startActivity(Intent(activity, OssLicensesActivity::class.java))
},
onOptionSelected = { dismiss() },
onOptionSelected = ::dismiss,
)
}.show()
}

private fun sendFeedback(activity: AppCompatActivity) {
val entryPoint = EntryPointAccessors.fromApplication(
activity.applicationContext,
ErrorReportEntryPoint::class.java,
)
val appModeProvider = entryPoint.appModeProvider()

val emailBody = StringBuilder().apply {
appendLine("Android Version: ${Build.VERSION.RELEASE} (SDK ${Build.VERSION.SDK_INT})")
appendLine("Current Service: ${appModeProvider.appMode.value}")
appendLine("---")
appendLine()
}

val emailIntent = Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:")).apply {
putExtra(Intent.EXTRA_EMAIL, arrayOf("[email protected]"))
putExtra(
Intent.EXTRA_SUBJECT,
"Pinkt (${BuildConfig.VERSION_NAME}) — Feature request / Bug report",
)
putExtra(Intent.EXTRA_TEXT, emailBody.toString())
}

activity.startActivity(Intent.createChooser(emailIntent, activity.getString(R.string.error_send_email)))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,10 @@ import com.fibelatti.ui.theme.ExtendedTheme
fun NavigationMenuScreen(
appStateViewModel: AppStateViewModel = hiltViewModel(),
authViewModel: AuthViewModel = hiltViewModel(),
onSendFeedbackClicked: () -> Unit,
onWriteReviewClicked: () -> Unit,
onShareClicked: () -> Unit,
onRateClicked: () -> Unit,
onPrivacyPolicyClicked: () -> Unit,
onLicensesClicked: () -> Unit,
onOptionSelected: () -> Unit,
) {
Expand Down Expand Up @@ -109,12 +111,20 @@ fun NavigationMenuScreen(
authViewModel.logout()
onOptionSelected()
},
onSendFeedbackClicked = {
onSendFeedbackClicked()
onOptionSelected()
},
onWriteReviewClicked = {
onWriteReviewClicked()
onOptionSelected()
},
onShareClicked = {
onShareClicked()
onOptionSelected()
},
onRateClicked = {
onRateClicked()
onPrivacyPolicyClicked = {
onPrivacyPolicyClicked()
onOptionSelected()
},
onLicensesClicked = {
Expand All @@ -139,8 +149,10 @@ private fun NavigationMenuScreen(
onPopularClicked: () -> Unit,
onPreferencesClicked: () -> Unit,
onLogoutClicked: () -> Unit,
onSendFeedbackClicked: () -> Unit,
onWriteReviewClicked: () -> Unit,
onShareClicked: () -> Unit,
onRateClicked: () -> Unit,
onPrivacyPolicyClicked: () -> Unit,
onLicensesClicked: () -> Unit,
) {
Column(
Expand Down Expand Up @@ -238,16 +250,32 @@ private fun NavigationMenuScreen(
color = MaterialTheme.colorScheme.onSurface,
)

MenuItem(
textRes = R.string.about_send_feedback,
onClick = onSendFeedbackClicked,
textStyle = MaterialTheme.typography.bodySmall,
iconRes = R.drawable.ic_feedback,
)

MenuItem(
textRes = R.string.about_rate,
onClick = onWriteReviewClicked,
textStyle = MaterialTheme.typography.bodySmall,
iconRes = R.drawable.ic_rate,
)

MenuItem(
textRes = R.string.about_share,
onClick = onShareClicked,
textStyle = MaterialTheme.typography.bodySmall,
iconRes = R.drawable.ic_share,
)

MenuItem(
textRes = R.string.about_rate,
onClick = onRateClicked,
textRes = R.string.about_privacy_policy,
onClick = onPrivacyPolicyClicked,
textStyle = MaterialTheme.typography.bodySmall,
iconRes = R.drawable.ic_privacy_policy,
)

AppVersionDetails(
Expand Down Expand Up @@ -340,8 +368,10 @@ private fun NavigationMenuScreenPreview() {
onPopularClicked = {},
onPreferencesClicked = {},
onLogoutClicked = {},
onSendFeedbackClicked = {},
onWriteReviewClicked = {},
onShareClicked = {},
onRateClicked = {},
onPrivacyPolicyClicked = {},
onLicensesClicked = {},
)
}
Expand Down
13 changes: 13 additions & 0 deletions app/src/main/res/drawable/ic_feedback.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#00000000"
android:pathData="M10,19H6.2C5.08,19 4.52,19 4.092,18.782C3.716,18.59 3.41,18.284 3.218,17.908C3,17.48 3,16.92 3,15.8V8.2C3,7.08 3,6.52 3.218,6.092C3.41,5.716 3.716,5.41 4.092,5.218C4.52,5 5.08,5 6.2,5H17.8C18.92,5 19.48,5 19.908,5.218C20.284,5.41 20.59,5.716 20.782,6.092C21,6.52 21,7.08 21,8.2V10M20.607,8.262L15.55,11.634C14.267,12.489 13.625,12.917 12.932,13.083C12.319,13.229 11.68,13.229 11.068,13.083C10.374,12.917 9.733,12.489 8.45,11.634L3.147,8.099M14,21L16.025,20.595C16.201,20.56 16.29,20.542 16.372,20.51C16.445,20.481 16.515,20.444 16.579,20.399C16.652,20.348 16.715,20.285 16.843,20.157L21,16C21.552,15.448 21.552,14.552 21,14C20.448,13.448 19.552,13.448 19,14L14.843,18.157C14.715,18.285 14.652,18.348 14.601,18.421C14.556,18.485 14.519,18.555 14.49,18.628C14.458,18.71 14.44,18.799 14.405,18.975L14,21Z"
android:strokeWidth="2"
android:strokeColor="@color/color_icon"
android:strokeLineCap="round"
android:strokeLineJoin="round" />
</vector>
13 changes: 13 additions & 0 deletions app/src/main/res/drawable/ic_privacy_policy.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#00000000"
android:pathData="M13,3H8.2C7.08,3 6.52,3 6.092,3.218C5.716,3.41 5.41,3.716 5.218,4.092C5,4.52 5,5.08 5,6.2V17.8C5,18.92 5,19.48 5.218,19.908C5.41,20.284 5.716,20.59 6.092,20.782C6.52,21 7.08,21 8.2,21H12M13,3L19,9M13,3V7.4C13,7.96 13,8.24 13.109,8.454C13.205,8.642 13.358,8.795 13.546,8.891C13.76,9 14.04,9 14.6,9H19M19,9V10M9,17H11M9,13H12M9,9H10M21,15.21C20.932,15.214 20.736,15.21 20.667,15.21C19.642,15.21 18.708,14.752 18,14C17.292,14.752 16.358,15.21 15.333,15.21C15.264,15.21 15.068,15.214 15,15.21C15,15.21 15,15.986 15,16.398C15,18.612 16.275,20.472 18,21C19.725,20.472 21,18.612 21,16.398C21,15.986 21,15.21 21,15.21Z"
android:strokeWidth="2"
android:strokeColor="@color/color_icon"
android:strokeLineCap="round"
android:strokeLineJoin="round" />
</vector>
13 changes: 13 additions & 0 deletions app/src/main/res/drawable/ic_rate.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="200dp"
android:height="200dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#00000000"
android:pathData="M11.245,4.174C11.476,3.508 11.592,3.175 11.763,3.083C11.911,3.003 12.09,3.003 12.238,3.083C12.409,3.175 12.525,3.508 12.756,4.174L14.287,8.576C14.352,8.766 14.385,8.861 14.445,8.931C14.497,8.994 14.564,9.042 14.64,9.073C14.725,9.107 14.825,9.109 15.026,9.114L19.686,9.209C20.391,9.223 20.743,9.23 20.884,9.364C21.005,9.481 21.06,9.65 21.03,9.816C20.996,10.007 20.715,10.22 20.153,10.646L16.439,13.462C16.279,13.583 16.199,13.644 16.15,13.722C16.107,13.791 16.081,13.87 16.076,13.951C16.069,14.043 16.098,14.139 16.156,14.331L17.506,18.792C17.71,19.467 17.812,19.804 17.728,19.979C17.655,20.131 17.511,20.236 17.344,20.258C17.151,20.284 16.862,20.083 16.283,19.68L12.458,17.018C12.293,16.903 12.211,16.846 12.121,16.824C12.042,16.804 11.959,16.804 11.88,16.824C11.791,16.846 11.708,16.903 11.544,17.018L7.718,19.68C7.139,20.083 6.85,20.284 6.657,20.258C6.491,20.236 6.346,20.131 6.273,19.979C6.189,19.804 6.291,19.467 6.495,18.792L7.845,14.331C7.903,14.139 7.932,14.043 7.926,13.951C7.92,13.87 7.894,13.791 7.851,13.722C7.802,13.644 7.723,13.583 7.563,13.462L3.849,10.646C3.287,10.22 3.006,10.007 2.971,9.816C2.941,9.65 2.996,9.481 3.118,9.364C3.258,9.23 3.611,9.223 4.316,9.209L8.975,9.114C9.176,9.109 9.276,9.107 9.362,9.073C9.437,9.042 9.504,8.994 9.557,8.931C9.616,8.861 9.649,8.766 9.715,8.576L11.245,4.174Z"
android:strokeWidth="2"
android:strokeColor="@color/color_icon"
android:strokeLineCap="round"
android:strokeLineJoin="round" />
</vector>
6 changes: 4 additions & 2 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,10 @@
<string name="user_preferences_edit_after_sharing_description">Controls when the bookmark editor should be displayed after choosing the \"Save bookmark\" share action. To skip the editor, choose \"Quick save bookmark\" when sharing instead</string>

<!-- About -->
<string name="about_share">Share Pinkt</string>
<string name="about_rate">Rate Pinkt on Google Play</string>
<string name="about_send_feedback">Send your feedback</string>
<string name="about_share">Share the app</string>
<string name="about_rate">Write a review</string>
<string name="about_privacy_policy">Privacy policy</string>
<string name="about_developer">Developed with ❤ by Filipe Belatti</string>
<string name="about_version">App version: %s</string>
<string name="about_oss_licenses">OSS Licenses</string>
Expand Down

0 comments on commit fcae002

Please sign in to comment.