Skip to content

Commit

Permalink
✨ Add request for a review
Browse files Browse the repository at this point in the history
Closes #681

Signed-off-by: Leonardo Colman Lopes <[email protected]>
  • Loading branch information
LeoColman committed Jan 22, 2025
1 parent 05d6e2f commit 4a24165
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 2 deletions.
3 changes: 3 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,9 @@ dependencies {
// Google Billing
"playstoreImplementation"(libs.play.services.billing)

// Google Reviews
"playstoreImplementation"(libs.bundles.review)

// Glance
implementation(libs.bundles.glance)

Expand Down
3 changes: 3 additions & 0 deletions app/src/main/kotlin/br/com/colman/petals/KoinModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ import androidx.datastore.preferences.preferencesDataStore
import app.cash.sqldelight.db.SqlDriver
import app.cash.sqldelight.driver.android.AndroidSqliteDriver
import br.com.colman.petals.hittimer.HitTimerRepository
import br.com.colman.petals.review.ReviewAppRequester
import br.com.colman.petals.settings.SettingsMigrations
import br.com.colman.petals.settings.SettingsRepository
import br.com.colman.petals.use.io.UseIOModules
import br.com.colman.petals.use.pause.repository.PauseRepository
import br.com.colman.petals.use.repository.CensorshipRepository
import br.com.colman.petals.use.repository.UseRepository
import io.requery.android.database.sqlite.RequerySQLiteOpenHelperFactory
import org.koin.dsl.bind
import org.koin.dsl.module

private val Context.settingsDatastore by preferencesDataStore("settings")
Expand All @@ -51,6 +53,7 @@ val KoinModule = module {
includes(AndroidModule, SqlDelightModule)
includes(UseIOModules)

single { object : ReviewAppRequester {} } bind ReviewAppRequester::class
single { UseRepository(get<Database>().useQueries) }
single { PauseRepository(get<Database>().pauseQueries) }
single { HitTimerRepository(get()) }
Expand Down
6 changes: 4 additions & 2 deletions app/src/main/kotlin/br/com/colman/petals/navigation/Usage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import androidx.compose.ui.Alignment.Companion.CenterVertically
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.unit.dp
import br.com.colman.petals.review.ReviewAppRequester
import br.com.colman.petals.use.AddUseButton
import br.com.colman.petals.use.LastUseDateTimer
import br.com.colman.petals.use.PauseCards
Expand All @@ -53,7 +54,8 @@ import kotlin.time.Duration.Companion.seconds
@Composable
fun Usage(
useRepository: UseRepository = koinInject(),
pauseRepository: PauseRepository = koinInject()
pauseRepository: PauseRepository = koinInject(),
reviewAppRequester: ReviewAppRequester = koinInject()
) {
val lastUseDate by useRepository.getLastUseDate().collectAsState(null)
var currentTime by remember {
Expand All @@ -79,7 +81,7 @@ fun Usage(
lastUseDate?.let { LastUseDateTimer(it) }

Row(Modifier.padding(8.dp), spacedBy(8.dp), CenterVertically) {
AddUseButton(useRepository, isAnyPauseActive)
AddUseButton(reviewAppRequester, useRepository, isAnyPauseActive)
PauseButton(pauseRepository)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package br.com.colman.petals.review

import android.app.Activity
import timber.log.Timber

interface ReviewAppRequester {
fun requestReview(activity: Activity) {
Timber.d("Default RequestReview Behaviour (No-Op)")
}
}
18 changes: 18 additions & 0 deletions app/src/main/kotlin/br/com/colman/petals/use/AddUseButton.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package br.com.colman.petals.use

import android.app.Activity
import android.content.Context
import android.content.ContextWrapper
import android.content.Intent
import android.net.Uri
import androidx.compose.foundation.layout.Row
Expand Down Expand Up @@ -32,6 +34,7 @@ import br.com.colman.petals.R.string.support_now
import br.com.colman.petals.R.string.thank_your_for_using_message
import br.com.colman.petals.R.string.yes
import br.com.colman.petals.R.string.yes_timer
import br.com.colman.petals.review.ReviewAppRequester
import br.com.colman.petals.use.repository.Use
import br.com.colman.petals.use.repository.UseRepository
import compose.icons.TablerIcons
Expand All @@ -44,6 +47,7 @@ import java.time.LocalTime

@Composable
fun AddUseButton(
reviewAppRequester: ReviewAppRequester,
repository: UseRepository,
isAnyPauseActive: Boolean
) {
Expand All @@ -52,13 +56,16 @@ fun AddUseButton(
var openConfirmAddUseDialog by remember { mutableStateOf(false) }
val lastUse by repository.getLastUse().collectAsState(null)
val context = LocalContext.current
val activity = context.getActivity()
val totalUseCount by repository.countAll().collectAsState(0)

if (openAddUseDialog) {
AddUseDialog(lastUse, {
repository.upsert(it)
if (totalUseCount > 0 && totalUseCount % 42 == 0) {
openSupportDialog = true
} else if ((totalUseCount > 0 && totalUseCount % 100 == 0)) {
activity?.let { reviewAppRequester.requestReview(it) }
}
}) { openAddUseDialog = false }
}
Expand Down Expand Up @@ -211,3 +218,14 @@ private fun Context.launchKofi() {
startActivity(intent)
}
}

fun Context.getActivity(): Activity? {
var currentContext = this
while (currentContext is ContextWrapper) {
if (currentContext is Activity) {
return currentContext
}
currentContext = currentContext.baseContext
}
return null
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ package br.com.colman.petals.playstore
import android.content.Context
import androidx.datastore.preferences.preferencesDataStore
import br.com.colman.petals.playstore.inapp.InAppPurchase
import br.com.colman.petals.playstore.review.ReviewAppPlaystoreRequester
import br.com.colman.petals.playstore.settings.AdsSettingsRepository
import br.com.colman.petals.review.ReviewAppRequester
import org.koin.dsl.bind
import org.koin.dsl.module

private val Context.adsSettings by preferencesDataStore("ads_settings")
Expand All @@ -15,4 +18,7 @@ val KoinModule = module {
single {
AdsSettingsRepository(get<Context>().adsSettings)
}

single { ReviewAppPlaystoreRequester(get()) } bind ReviewAppRequester::class

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package br.com.colman.petals.playstore.review

import android.app.Activity
import android.content.Context
import br.com.colman.petals.review.ReviewAppRequester
import com.google.android.play.core.review.ReviewManagerFactory
import timber.log.Timber

class ReviewAppPlaystoreRequester(context: Context) : ReviewAppRequester {

private val reviewManager = ReviewManagerFactory.create(context)

override fun requestReview(activity: Activity) {
Timber.d("Requesting review")
reviewManager.requestReviewFlow().addOnSuccessListener { reviewManager.launchReviewFlow(activity, it) }
}
}
4 changes: 4 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ vanpra-material-dialogs = "0.9.0"
sqldelight = "2.0.2"
glance = "1.1.1"
mockk = "1.13.16"
review = "2.0.2"

[libraries]
android-desugar-jdk = "com.android.tools:desugar_jdk_libs:2.1.4"
Expand Down Expand Up @@ -67,8 +68,11 @@ glance-widgets = { module = "androidx.glance:glance-appwidget", version.ref = "g
fuel = "com.github.kittinunf.fuel:fuel:2.3.1"
androidx-test-core = "androidx.test:core:1.6.1"
androidx-test-ext-junit = "androidx.test.ext:junit:1.2.1"
review = { module = "com.google.android.play:review", version.ref = "review" }
review-ktx = { module = "com.google.android.play:review-ktx", version.ref = "review" }

[bundles]
review = ["review", "review-ktx"]
androidx-test = [
"androidx-test-rules",
"androidx-test-runner",
Expand Down

0 comments on commit 4a24165

Please sign in to comment.