diff --git a/app/build.gradle b/app/build.gradle index d5fccac6..c05aa034 100644 --- a/app/build.gradle +++ b/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' diff --git a/app/src/fdroid/java/io/github/wulkanowy/utils/InAppReviewHelper.kt b/app/src/fdroid/java/io/github/wulkanowy/utils/InAppReviewHelper.kt new file mode 100644 index 00000000..d052b54b --- /dev/null +++ b/app/src/fdroid/java/io/github/wulkanowy/utils/InAppReviewHelper.kt @@ -0,0 +1,17 @@ +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 diff --git a/app/src/hms/java/io/github/wulkanowy/utils/InAppReviewHelper.kt b/app/src/hms/java/io/github/wulkanowy/utils/InAppReviewHelper.kt new file mode 100644 index 00000000..fb9bcae6 --- /dev/null +++ b/app/src/hms/java/io/github/wulkanowy/utils/InAppReviewHelper.kt @@ -0,0 +1,17 @@ +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 diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/PreferencesRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/PreferencesRepository.kt index 7b3cd67b..bc8100f2 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/PreferencesRepository.kt +++ b/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" } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainActivity.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainActivity.kt index cf31040a..d758ac0d 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainActivity.kt +++ b/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(), MainVie @Inject lateinit var updateHelper: UpdateHelper + @Inject + lateinit var inAppReviewHelper: InAppReviewHelper + @Inject lateinit var appInfo: AppInfo @@ -362,6 +366,10 @@ class MainActivity : BaseActivity(), MainVie } } + override fun showInAppReview() { + inAppReviewHelper.showInAppReview(this) + } + override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) navController.onSaveInstanceState(outState) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt index a2fb07f6..4805b5a1 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt +++ b/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 diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainView.kt index 7402d37e..8851f587 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainView.kt +++ b/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() diff --git a/app/src/play/java/io/github/wulkanowy/utils/InAppReviewHelper.kt b/app/src/play/java/io/github/wulkanowy/utils/InAppReviewHelper.kt new file mode 100644 index 00000000..1dcece99 --- /dev/null +++ b/app/src/play/java/io/github/wulkanowy/utils/InAppReviewHelper.kt @@ -0,0 +1,28 @@ +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