Skip to content

Commit

Permalink
Merge pull request #17 from odaridavid/request-rating
Browse files Browse the repository at this point in the history
show prompt for rating
  • Loading branch information
odaridavid authored May 27, 2020
2 parents 424df87 + a8d3b00 commit 8e0c657
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 3 deletions.
Binary file added .idea/icon_dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 25 additions & 0 deletions .idea/jarRepositories.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
*
* Copyright 2020 David Odari
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*
**/
package com.github.odaridavid.designpatterns

import android.content.SharedPreferences

internal interface IRatingManager {
fun hasGivenRating(): Boolean
fun shouldPromptForRating(): Boolean
fun updatePromptForRatingCounter()
fun giveRating()
}

internal class RatingManager(private val sharedPreferences: SharedPreferences) :
IRatingManager {

override fun hasGivenRating(): Boolean = sharedPreferences.getBoolean(RATING_PREF_KEY, false)

override fun giveRating() {
with(sharedPreferences.edit()) {
putBoolean(RATING_PREF_KEY, true)
apply()
}
}

override fun shouldPromptForRating(): Boolean {
val counter = sharedPreferences.getInt(PROMPT_COUNTER_PREF_KEY, 0)
return counter % 5 == 0
}

override fun updatePromptForRatingCounter() {
val counter = sharedPreferences.getInt(PROMPT_COUNTER_PREF_KEY, 0) + 1
with(sharedPreferences.edit()) {
putInt(PROMPT_COUNTER_PREF_KEY, counter)
apply()
}
}

companion object {
private const val RATING_PREF_KEY = "rating"
private const val PROMPT_COUNTER_PREF_KEY = "rating_prompt"
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.github.odaridavid.designpatterns.base

import android.content.Context
import android.content.SharedPreferences
import android.content.res.Configuration
import android.os.Build
import android.os.PowerManager
Expand All @@ -9,6 +10,7 @@ import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import androidx.preference.PreferenceManager
import com.github.odaridavid.designpatterns.R
import com.github.odaridavid.designpatterns.helpers.InjectorUtils
import com.github.odaridavid.designpatterns.helpers.SdkUtils.versionFrom
import com.github.odaridavid.designpatterns.helpers.SdkUtils.versionUntil
import com.github.odaridavid.designpatterns.helpers.ThemeUtils
Expand All @@ -19,6 +21,10 @@ internal abstract class BaseActivity : AppCompatActivity(), ISystemThemeChangeLi
getSystemService(Context.POWER_SERVICE) as PowerManager
}

protected val sharedPref: SharedPreferences by lazy {
InjectorUtils.provideSharedPreferences(this)
}

override fun onResume() {
if (versionFrom(Build.VERSION_CODES.M))
matchSystemBarsWithBackground()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
*
* Copyright 2020 David Odari
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*
**/
package com.github.odaridavid.designpatterns.helpers

import android.content.Context
import android.content.SharedPreferences


internal object InjectorUtils {
private const val DESIGN_PATTERNS_SP_NAME = "design_patterns_pref"
fun provideSharedPreferences(context: Context): SharedPreferences {
return context.getSharedPreferences(DESIGN_PATTERNS_SP_NAME, Context.MODE_PRIVATE)
}

}
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
package com.github.odaridavid.designpatterns.ui

import android.app.Activity
import android.content.ComponentName
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import androidx.annotation.ColorRes
import androidx.appcompat.app.AlertDialog
import androidx.core.content.ContextCompat
import com.github.odaridavid.designpatterns.InAppUpdateManager
import com.github.odaridavid.designpatterns.R
import com.github.odaridavid.designpatterns.RatingManager
import com.github.odaridavid.designpatterns.base.BaseActivity
import com.github.odaridavid.designpatterns.databinding.ActivityMainBinding
import com.github.odaridavid.designpatterns.helpers.NavigationUtils
Expand All @@ -28,14 +34,74 @@ internal class MainActivity : BaseActivity() {
setupDesignPatternsAdapter()

InAppUpdateManager(baseContext, this).checkForUpdate()

with(RatingManager(sharedPref)) {
if (!hasGivenRating()) {
updatePromptForRatingCounter()
if (shouldPromptForRating()) {
showRatingAlertDialog(this)
}
}
}
}

private fun showRatingAlertDialog(ratingManager: RatingManager) {
val dialog = AlertDialog.Builder(this)
.setTitle(getString(R.string.title_rating_dialog))
.setMessage(getString(R.string.info_rating_message))
.setNegativeButton(getString(R.string.label_dialog_negative_button), null)
.setPositiveButton(getString(R.string.label_dialog_positive_button)) { dialog, _ ->
ratingManager.giveRating()
navigateToGooglePlayStore()
}
.setCancelable(true)
.create()
dialog.show()
dialog.apply {
fun loadColor(@ColorRes colorRes: Int): Int {
return ContextCompat.getColor(this@MainActivity, colorRes)
}
getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(loadColor(R.color.colorText))
getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(loadColor(R.color.colorText))
}
}

private fun navigateToGooglePlayStore() {
var gplayAvailable = false
val appUri = Uri.parse("market://details?id=$packageName")
val rateIntent = Intent(Intent.ACTION_VIEW, appUri)
val gplayAppInfo = packageManager.queryIntentActivities(rateIntent, 0)
.filter { it.activityInfo.applicationInfo.packageName == "com.android.vending" }
if (gplayAppInfo.isNotEmpty()) {
val gplayActivityInfo = gplayAppInfo.first().activityInfo
val gplayComponent = ComponentName(
gplayActivityInfo.applicationInfo.packageName,
gplayActivityInfo.name
)
with(rateIntent) {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
setComponent(gplayComponent)
}
gplayAvailable = true
startActivity(rateIntent)
}
if (!gplayAvailable) {
val webIntent = Intent(
Intent.ACTION_VIEW,
Uri.parse("https://play.google.com/store/apps/details?id=$packageName")
)
startActivity(webIntent)
}
}

private fun setupDesignPatternsAdapter() {
val designPatternsAdapter = DesignPatternsAdapter { designPattern ->
navigateTo<DesignPatternDetailActivity>() { intent ->
intent.putExtra(NavigationUtils.KEY_DESIGN_PATTERN, designPattern)
}
navigateTo<DesignPatternDetailActivity>() { intent ->
intent.putExtra(NavigationUtils.KEY_DESIGN_PATTERN, designPattern)
}
}
val designPatterns = generateDesignPatterns()
binding.designPatternsRecyclerView.addItemDecoration(GridSpaceItemDecoration(16))
binding.designPatternsRecyclerView.adapter =
Expand Down
9 changes: 9 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -172,5 +172,14 @@
the time of day.
</string>

<!--Rating-->
<string name="info_rating_message">
If you found the app helpful or see aspects that could be improved on,feel free to leave us
some feedback on playstore and rate the app.
</string>
<string name="title_rating_dialog">App Rating</string>
<string name="label_dialog_negative_button">Later</string>
<string name="label_dialog_positive_button">Rate</string>


</resources>

0 comments on commit 8e0c657

Please sign in to comment.