Add in app review
MODIFY
app/build.gradle
app/build.gradle
@@ -215,6 +215,7 @@ dependencies {
playImplementation 'com.google.firebase:firebase-analytics-ktx'
playImplementation 'com.google.firebase:firebase-messaging:'
playImplementation 'com.google.firebase:firebase-crashlytics:'
+ playImplementation 'com.google.android.play:core:1.10.0'
playImplementation 'com.google.android.play:core-ktx:1.8.1'
hmsImplementation 'com.huawei.hms:hianalytics:6.1.1.300'

ADD
app/src/fdroid/java/io/github/wulkanowy/utils/InAppReviewHelper.kt
+package io.github.wulkanowy.utils
+
+import android.content.Context
+import dagger.hilt.android.qualifiers.ApplicationContext
+import io.github.wulkanowy.ui.modules.main.MainActivity
+import javax.inject.Singleton
+import javax.inject.Inject
+
+@Singleton
+class InAppReviewHelper @Inject constructor(
+ @ApplicationContext private val context: Context
+) {
+
+ fun showInAppReview(activity: MainActivity) {
+ // do nothing
+ }
+}
\ No newline at end of file

ADD
app/src/hms/java/io/github/wulkanowy/utils/InAppReviewHelper.kt
+package io.github.wulkanowy.utils
+
+import android.content.Context
+import dagger.hilt.android.qualifiers.ApplicationContext
+import io.github.wulkanowy.ui.modules.main.MainActivity
+import javax.inject.Inject
+import javax.inject.Singleton
+
+@Singleton
+class InAppReviewHelper @Inject constructor(
+ @ApplicationContext private val context: Context
+) {
+
+ fun showInAppReview(activity: MainActivity) {
+ // do nothing
+ }
+}
\ No newline at end of file

MODIFY
app/src/main/java/io/github/wulkanowy/data/repositories/PreferencesRepository.kt
app/src/main/java/io/github/wulkanowy/data/repositories/PreferencesRepository.kt
@@ -10,14 +10,17 @@ import com.squareup.moshi.Moshi
import com.squareup.moshi.adapter
import dagger.hilt.android.qualifiers.ApplicationContext
import io.github.wulkanowy.R
+import io.github.wulkanowy.sdk.toLocalDate
import io.github.wulkanowy.ui.modules.dashboard.DashboardItem
import io.github.wulkanowy.ui.modules.grade.GradeAverageMode
import io.github.wulkanowy.ui.modules.grade.GradeSortingMode
+import io.github.wulkanowy.utils.toTimestamp
import io.github.wulkanowy.utils.toLocalDateTime
import io.github.wulkanowy.utils.toTimestamp
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
+import java.time.LocalDate
import java.time.LocalDateTime
import javax.inject.Inject
import javax.inject.Singleton
@@ -222,6 +225,18 @@ class PreferencesRepository @Inject constructor(
return flowSharedPref.getStringSet(prefKey, defaultSet)
}
+ var inAppReviewCount: Int
+ get() = sharedPref.getInt(PREF_KEY_IN_APP_REVIEW_COUNT, 0)
+ set(value) = sharedPref.edit().putInt(PREF_KEY_IN_APP_REVIEW_COUNT, value).apply()
+
+ var inAppReviewDate: LocalDate?
+ get() = sharedPref.getLong(PREF_KEY_IN_APP_REVIEW_DATE, 0).takeIf { it != 0L }?.toLocalDate()
+ set(value) = sharedPref.edit().putLong(PREF_KEY_IN_APP_REVIEW_DATE, value!!.toTimestamp()).apply()
+
+ var isAppReviewDone: Boolean
+ get() = sharedPref.getBoolean(PREF_KEY_IN_APP_REVIEW_DONE, false)
+ set(value) = sharedPref.edit().putBoolean(PREF_KEY_IN_APP_REVIEW_DONE, value).apply()
+
private fun getLong(id: Int, default: Int) = getLong(context.getString(id), default)
private fun getLong(id: String, default: Int) =
@@ -240,5 +255,11 @@ class PreferencesRepository @Inject constructor(
private companion object {
private const val PREF_KEY_DASHBOARD_ITEMS_POSITION = "dashboard_items_position"
+
+ private const val PREF_KEY_IN_APP_REVIEW_COUNT = "in_app_review_count"
+
+ private const val PREF_KEY_IN_APP_REVIEW_DATE = "in_app_review_date"
+
+ private const val PREF_KEY_IN_APP_REVIEW_DONE = "in_app_review_done"
}
}

MODIFY
app/src/main/java/io/github/wulkanowy/ui/modules/main/MainActivity.kt
app/src/main/java/io/github/wulkanowy/ui/modules/main/MainActivity.kt
@@ -45,6 +45,7 @@ import io.github.wulkanowy.ui.modules.schoolannouncement.SchoolAnnouncementFragm
import io.github.wulkanowy.ui.modules.timetable.TimetableFragment
import io.github.wulkanowy.utils.AnalyticsHelper
import io.github.wulkanowy.utils.AppInfo
+import io.github.wulkanowy.utils.InAppReviewHelper
import io.github.wulkanowy.utils.UpdateHelper
import io.github.wulkanowy.utils.createNameInitialsDrawable
import io.github.wulkanowy.utils.dpToPx
@@ -68,6 +69,9 @@ class MainActivity : BaseActivity<MainPresenter, ActivityMainBinding>(), MainVie
@Inject
lateinit var updateHelper: UpdateHelper
+ @Inject
+ lateinit var inAppReviewHelper: InAppReviewHelper
+
@Inject
lateinit var appInfo: AppInfo
@@ -362,6 +366,10 @@ class MainActivity : BaseActivity<MainPresenter, ActivityMainBinding>(), MainVie
}
}
+ override fun showInAppReview() {
+ inAppReviewHelper.showInAppReview(this)
+ }
+
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
navController.onSaveInstanceState(outState)

MODIFY
app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt
app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt
@@ -14,6 +14,7 @@ import io.github.wulkanowy.utils.AnalyticsHelper
import io.github.wulkanowy.utils.flowWithResource
import kotlinx.coroutines.flow.onEach
import timber.log.Timber
+import java.time.LocalDate
import javax.inject.Inject
class MainPresenter @Inject constructor(
@@ -106,11 +107,27 @@ class MainPresenter @Inject constructor(
} else {
notifyMenuViewChanged()
switchMenuView(index)
+ checkInAppReview()
true
}
} == true
}
+ private fun checkInAppReview() {
+ prefRepository.inAppReviewCount++
+
+ if (prefRepository.inAppReviewDate == null) {
+ prefRepository.inAppReviewDate = LocalDate.now()
+ }
+
+ if (!prefRepository.isAppReviewDone && prefRepository.inAppReviewCount >= 50 &&
+ LocalDate.now().minusDays(14).isAfter(prefRepository.inAppReviewDate)
+ ) {
+ view?.showInAppReview()
+ prefRepository.isAppReviewDone = true
+ }
+ }
+
private fun showCurrentStudentAvatar() {
val currentStudent =
studentsWitSemesters?.singleOrNull { it.student.isCurrent }?.student ?: return

MODIFY
app/src/main/java/io/github/wulkanowy/ui/modules/main/MainView.kt
app/src/main/java/io/github/wulkanowy/ui/modules/main/MainView.kt
@@ -40,6 +40,8 @@ interface MainView : BaseView {
fun showStudentAvatar(student: Student)
+ fun showInAppReview()
+
interface MainChildView {
fun onFragmentReselected()

ADD
app/src/play/java/io/github/wulkanowy/utils/InAppReviewHelper.kt
+package io.github.wulkanowy.utils
+
+import android.content.Context
+import com.google.android.play.core.review.ReviewManagerFactory
+import dagger.hilt.android.qualifiers.ApplicationContext
+import io.github.wulkanowy.ui.modules.main.MainActivity
+import timber.log.Timber
+import javax.inject.Inject
+import javax.inject.Singleton
+
+@Singleton
+class InAppReviewHelper @Inject constructor(
+ @ApplicationContext private val context: Context
+) {
+
+ fun showInAppReview(activity: MainActivity) {
+ val manager = ReviewManagerFactory.create(context)
+ val request = manager.requestReviewFlow()
+ request.addOnCompleteListener { task ->
+ if (task.isSuccessful) {
+ val reviewInfo = task.result
+ manager.launchReviewFlow(activity, reviewInfo)
+ } else {
+ Timber.e(task.exception)
+ }
+ }
+ }
+}
\ No newline at end of file

Add in app review (#1435)