aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAllan Wang <me@allanwang.ca>2017-07-02 14:19:50 -0700
committerAllan Wang <me@allanwang.ca>2017-07-02 14:19:50 -0700
commitb9aab92aee334acdffc6c0fde32101bb72be9a5e (patch)
tree6d588844d7aed8de97c488fd0cd33d288a1913e8
parent8cc26f47b18bbc1944404d3378b885742a1d7586 (diff)
downloadfrost-1.1.tar.gz
frost-1.1.tar.bz2
frost-1.1.zip
Add restore functionv1.1
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/MainActivity.kt7
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/SettingsActivity.kt14
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt1
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/iab/IAB.kt91
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/iab/IABDialogs.kt8
-rw-r--r--app/src/main/res/values/strings.xml4
-rw-r--r--docs/Changelog.md2
-rw-r--r--gradle.properties2
8 files changed, 92 insertions, 37 deletions
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/MainActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/MainActivity.kt
index b4d7973e..f2fb9c29 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/MainActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/MainActivity.kt
@@ -44,6 +44,7 @@ import com.pitchedapps.frost.facebook.PROFILE_PICTURE_URL
import com.pitchedapps.frost.fragments.WebFragment
import com.pitchedapps.frost.utils.*
import com.pitchedapps.frost.utils.iab.IAB
+import com.pitchedapps.frost.utils.iab.validatePro
import com.pitchedapps.frost.views.BadgedIcon
import com.pitchedapps.frost.web.FrostWebViewSearch
import io.reactivex.android.schedulers.AndroidSchedulers
@@ -133,6 +134,7 @@ class MainActivity : BaseActivity(), FrostWebViewSearch.SearchContract {
.setAction("Action", null).show()
}
setFrostColors(toolbar, themeWindow = false, headers = arrayOf(tabs, appBar), backgrounds = arrayOf(viewPager))
+ validatePro()
}
fun tabsForEachView(action: (position: Int, view: BadgedIcon) -> Unit) {
@@ -393,11 +395,6 @@ class MainActivity : BaseActivity(), FrostWebViewSearch.SearchContract {
FbCookie.switchBackUser { }
}
- override fun onStart() {
- super.onStart()
- IAB.setupAsync(this)
- }
-
override fun onBackPressed() {
if (searchView?.onBackPressed() ?: false) return
if (currentFragment.onBackPressed()) return
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/SettingsActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/SettingsActivity.kt
index 0cdc5631..bf100895 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/SettingsActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/SettingsActivity.kt
@@ -2,6 +2,7 @@ package com.pitchedapps.frost
import android.content.Intent
import android.os.Bundle
+import android.support.design.widget.Snackbar
import android.view.Menu
import android.view.MenuItem
import ca.allanwang.kau.changelog.showChangelog
@@ -70,16 +71,12 @@ class SettingsActivity : KPrefActivity(), IabBroadcastReceiver.IabBroadcastListe
plainText(R.string.restore_purchases) {
descRes = R.string.restore_purchases
iicon = GoogleMaterial.Icon.gmd_refresh
- onClick = { _, _,_ -> this@SettingsActivity.restorePurchases(); true }
+ onClick = { _, _, _ -> this@SettingsActivity.restorePurchases(); true }
}
plainText(R.string.about_frost) {
iicon = GoogleMaterial.Icon.gmd_info
- onClick = {
- _, _, _ ->
- startActivity(AboutActivity::class.java, transition = true)
- true
- }
+ onClick = { _, _, _ -> startActivity(AboutActivity::class.java, transition = true); true }
}
if (BuildConfig.DEBUG) {
@@ -142,4 +139,9 @@ class SettingsActivity : KPrefActivity(), IabBroadcastReceiver.IabBroadcastListe
}
return true
}
+
+ override fun onDestroy() {
+ if (!IAB.isInProgress) IAB.dispose()
+ super.onDestroy()
+ }
} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt
index e51bb0cb..f8060d9d 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt
@@ -1,6 +1,5 @@
package com.pitchedapps.frost.utils
-import android.graphics.Color
import ca.allanwang.kau.kotlin.lazyResettable
import ca.allanwang.kau.kpref.KPref
import ca.allanwang.kau.kpref.StringSet
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/iab/IAB.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/iab/IAB.kt
index b9213ae7..d511f773 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/iab/IAB.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/iab/IAB.kt
@@ -3,13 +3,14 @@ package com.pitchedapps.frost.utils.iab
import android.app.Activity
import android.content.Context
import android.content.Intent
+import android.support.design.widget.Snackbar
import ca.allanwang.kau.utils.isFromGooglePlay
+import ca.allanwang.kau.utils.snackbar
import com.crashlytics.android.answers.PurchaseEvent
import com.pitchedapps.frost.BuildConfig
+import com.pitchedapps.frost.R
import com.pitchedapps.frost.SettingsActivity
-import com.pitchedapps.frost.utils.L
-import com.pitchedapps.frost.utils.Prefs
-import com.pitchedapps.frost.utils.frostAnswers
+import com.pitchedapps.frost.utils.*
/**
* Created by Allan Wang on 2017-06-23.
@@ -27,13 +28,14 @@ object IAB {
* and false otherwise
*
*/
- operator fun invoke(activity: Activity, mustHavePlayStore: Boolean = true, onStart: (helper: IabHelper) -> Boolean) {
+ operator fun invoke(activity: Activity, mustHavePlayStore: Boolean = true, onFailed: () -> Unit = {}, onStart: (helper: IabHelper) -> Boolean) {
with(activity) {
if (helper?.mDisposed ?: true) {
helper = null
L.d("IAB setup async")
if (!isFrostPlay) {
if (mustHavePlayStore) playStoreNotFound()
+ onFailed()
return
}
try {
@@ -44,13 +46,17 @@ object IAB {
if (result.isSuccess) {
if (onStart(helper!!))
helper!!.disposeWhenFinished()
- } else if (mustHavePlayStore)
- activity.playStoreGenericError("Setup error: ${result.response} ${result.message}")
+ } else {
+ if (mustHavePlayStore)
+ activity.playStoreGenericError("Setup error: ${result.response} ${result.message}")
+ onFailed()
+ }
}
} catch (e: Exception) {
L.e(e, "IAB error")
if (mustHavePlayStore)
playStoreGenericError(null)
+ onFailed()
}
} else if (onStart(helper!!))
helper!!.disposeWhenFinished()
@@ -60,14 +66,21 @@ object IAB {
fun handleActivityResult(requestCode: Int, resultCode: Int, data: Intent?): Boolean
= helper?.handleActivityResult(requestCode, resultCode, data) ?: false
+ fun cancel() {
+
+ }
/**
* Call this after any execution to dispose the helper
+ * Ensure that async calls have already finished beforehand
*/
fun dispose() {
- helper?.disposeWhenFinished()
+ helper?.dispose()
helper = null
}
+
+ val isInProgress: Boolean
+ get() = helper?.mAsyncInProgress ?: false
}
private const val FROST_PRO = "frost_pro"
@@ -79,30 +92,60 @@ private val Context.isFrostPlay: Boolean
get() = isFromGooglePlay || BuildConfig.DEBUG
fun SettingsActivity.restorePurchases() {
- validatePro(this)
+ //like validate, but with a snackbar and without other prompts
+ var restore: Snackbar? = null
+ restore = container.snackbar(R.string.restoring_purchases, Snackbar.LENGTH_INDEFINITE) {
+ setAction(R.string.kau_close) { restore?.dismiss() }
+ }
+ //called if inventory is not properly retrieved
+ val reset = {
+ if (Prefs.previouslyPro) {
+ Prefs.previouslyPro = false
+ Prefs.theme = Theme.DEFAULT.ordinal
+ }
+ finishRestore(restore)
+ }
+ getInventory(false, true, reset) {
+ val proSku = it.getSkuDetails(FROST_PRO)
+ Prefs.previouslyPro = proSku != null
+ finishRestore(restore)
+ }
+}
+
+private fun SettingsActivity.finishRestore(snackbar: Snackbar?) {
+ snackbar?.dismiss()
+ materialDialogThemed {
+ title(R.string.purchases_restored)
+ content(if (Prefs.previouslyPro) R.string.purchases_restored_with_pro else R.string.purchases_restored_without_pro)
+ positiveText(R.string.reload)
+ dismissListener { adapter.notifyAdapterDataSetChanged() }
+ }
}
/**
* If user has pro, check if it's valid and destroy the helper
*/
-fun Activity.validatePro(activity: Activity) {
- IAB(activity, Prefs.previouslyPro) { //if pro, ensure that it is in inventory; if not, check quietly if it exists
+fun Activity.validatePro() {
+ getInventory(Prefs.previouslyPro, true, { if (Prefs.previouslyPro) playStoreNoLongerPro() }) {
+ val proSku = it.getSkuDetails(FROST_PRO)
+ if (proSku == null && Prefs.previouslyPro) playStoreNoLongerPro()
+ else if (proSku != null && !Prefs.previouslyPro) playStoreFoundPro()
+ }
+}
+
+fun Activity.getInventory(
+ mustHavePlayStore: Boolean = true,
+ disposeOnFinish: Boolean = true,
+ onFailed: () -> Unit = {},
+ onSuccess: (inv: Inventory) -> Unit) {
+ IAB(this, mustHavePlayStore, onFailed) {
helper ->
- with(activity) {
- helper.queryInventoryAsync {
- res, inv ->
- if (res.isFailure) return@queryInventoryAsync playStoreGenericError("Query res error")
- if (inv?.getSkuDetails(FROST_PRO) != null) {
- //owns pro
- if (!Prefs.previouslyPro)
- playStoreFoundPro()
- } else if (Prefs.previouslyPro) {
- //doesn't own pro but has it
- playStoreNoLongerPro()
- }
- }
+ helper.queryInventoryAsync {
+ res, inv ->
+ if (res.isFailure || inv == null) onFailed()
+ else onSuccess(inv)
}
- true
+ disposeOnFinish
}
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/iab/IABDialogs.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/iab/IABDialogs.kt
index 330680f6..54355d3e 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/iab/IABDialogs.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/iab/IABDialogs.kt
@@ -103,4 +103,12 @@ fun Activity.playStorePurchasedSuccessfully(key: String) {
content(R.string.play_purchased_pro)
positiveText(R.string.kau_ok)
}
+}
+
+fun SettingsActivity.purchaseRestored() {
+ materialDialogThemed {
+ title(R.string.play_thank_you)
+ content(R.string.play_purchased_pro)
+ positiveText(R.string.kau_ok)
+ }
} \ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 58c879d2..b79c6823 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -60,6 +60,10 @@
<string name="play_already_purchased_content">Looks like you\'ve already purchased %s. Enjoy!</string>
<string name="found_pro">Found Frost Pro!</string>
<string name="found_pro_desc">Looks like you have frost pro! We\'ll reload the app so you can enjoy the awesome features!</string>
+ <string name="restoring_purchases">Restoring purchases…</string>
+ <string name="purchases_restored">Purchases Restored</string>
+ <string name="purchases_restored_with_pro">Frost Pro has been restored. Enjoy the features!</string>
+ <string name="purchases_restored_without_pro">It seems like you don\'t have pro. If this is a persistent issue, contact me and attach your purchase receipt.</string>
<string name="define_dbflow"></string>
<!-- Author section -->
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 96f5f1f5..6c000718 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -1,5 +1,7 @@
# Changelog
+## v1.1
+
## v1.0
* Added more global preferences
* Added fully customizable theme engine
diff --git a/gradle.properties b/gradle.properties
index 54baaf69..f0fa5e38 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -17,7 +17,7 @@ MIN_SDK=21
TARGET_SDK=26
BUILD_TOOLS=26.0.0
-KAU=e1e3b37000
+KAU=f4090285eb
KOTLIN=1.1.3
MATERIAL_DRAWER=5.9.3
MATERIAL_DRAWER_KT=1.0.4