diff options
Diffstat (limited to 'app/src/main/kotlin/com/pitchedapps/frost/utils')
6 files changed, 11 insertions, 353 deletions
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/L.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/L.kt index a108745c..4f31f5f5 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/utils/L.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/L.kt @@ -2,7 +2,7 @@ package com.pitchedapps.frost.utils import android.util.Log import ca.allanwang.kau.logging.KauLogger -import com.crashlytics.android.Crashlytics +import com.bugsnag.android.Bugsnag import com.pitchedapps.frost.BuildConfig @@ -34,9 +34,9 @@ object L : KauLogger("Frost", { super.logImpl(priority, message, t) else { if (message != null) - Crashlytics.log(priority, tag, message) + Bugsnag.leaveBreadcrumb(message) if (t != null) - Crashlytics.logException(t) + Bugsnag.notify(t) } } 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 26d7894e..95a5f39b 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt @@ -135,19 +135,9 @@ object Prefs : KPref() { var enablePip: Boolean by kpref("enable_pip", true) - /** - * Cache like value to determine if user has or had pro - * In most cases, [com.pitchedapps.frost.utils.iab.IS_FROST_PRO] should be looked at instead - * This has been renamed to pro for short, but keep in mind that it only reflects the value - * of when it was previously verified - */ - var pro: Boolean by kpref("previously_pro", false) - - var debugPro: Boolean by kpref("debug_pro", false) - var verboseLogging: Boolean by kpref("verbose_logging", false) - var analytics: Boolean by kpref("analytics", true) + var analytics: Boolean by kpref("analytics", false) var overlayEnabled: Boolean by kpref("overlay_enabled", true) diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt index d73f29e9..b1b129fb 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt @@ -23,15 +23,12 @@ import ca.allanwang.kau.mediapicker.createPrivateMediaFile import ca.allanwang.kau.utils.* import ca.allanwang.kau.xml.showChangelog import com.afollestad.materialdialogs.MaterialDialog -import com.crashlytics.android.answers.Answers -import com.crashlytics.android.answers.CustomEvent import com.pitchedapps.frost.BuildConfig import com.pitchedapps.frost.R import com.pitchedapps.frost.activities.* import com.pitchedapps.frost.dbflow.CookieModel import com.pitchedapps.frost.facebook.* import com.pitchedapps.frost.facebook.FbUrlFormatter.Companion.VIDEO_REDIRECT -import com.pitchedapps.frost.utils.iab.IS_FROST_PRO import org.apache.commons.text.StringEscapeUtils import org.jsoup.Jsoup import org.jsoup.nodes.Element @@ -175,29 +172,19 @@ inline fun Activity.setFrostColors(builder: ActivityThemeUtils.() -> Unit) { themer.theme(this) } -fun frostAnswers(action: Answers.() -> Unit) { - if (BuildConfig.DEBUG || !Prefs.analytics) return - Answers.getInstance().action() -} -fun frostAnswersCustom(name: String, vararg events: Pair<String, Any>) { - frostAnswers { - logCustom(CustomEvent("Frost $name").apply { - events.forEach { (key, value) -> - if (value is Number) putCustomAttribute(key, value) - else putCustomAttribute(key, value.toString()) - } - }) - } +fun frostEvent(name: String, vararg events: Pair<String, Any>) { + // todo bind + L.v { "Event: $name ${events.joinToString(", ")}" } } /** * Helper method to quietly keep track of throwable issues */ -fun Throwable?.logFrostAnswers(text: String) { +fun Throwable?.logFrostEvent(text: String) { val msg = if (this == null) text else "$text: $message" L.e { msg } - frostAnswersCustom("Errors", "text" to text, "message" to (this?.message ?: "NA")) + frostEvent("Errors", "text" to text, "message" to (this?.message ?: "NA")) } fun Activity.frostSnackbar(@StringRes text: Int, builder: Snackbar.() -> Unit = {}) = snackbar(text, Snackbar.LENGTH_LONG, frostSnackbar(builder)) @@ -291,10 +278,6 @@ inline val String?.isExplicitIntent fun Context.frostChangelog() = showChangelog(R.xml.frost_changelog, Prefs.textColor) { theme() - if (System.currentTimeMillis() - Prefs.installDate > 2592000000) { //show after 1 month - neutralText(R.string.kau_rate) - onNeutral { _, _ -> startPlayStoreLink(R.string.play_store_package_id) } - } } fun Context.frostUriFromFile(file: File): Uri = @@ -311,7 +294,8 @@ inline fun Context.sendFrostEmail(subjectId: String, crossinline builder: EmailB fun EmailBuilder.addFrostDetails() { addItem("Prev version", Prefs.prevVersionCode.toString()) - val proTag = if (IS_FROST_PRO) "TY" else "FP" + val proTag = "FO" +// if (IS_FROST_PRO) "TY" else "FP" addItem("Random Frost ID", "${Prefs.frostId}-$proTag") addItem("Locale", Locale.getDefault().displayName) } 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 deleted file mode 100644 index 15d707a9..00000000 --- a/app/src/main/kotlin/com/pitchedapps/frost/utils/iab/IABDialogs.kt +++ /dev/null @@ -1,95 +0,0 @@ -package com.pitchedapps.frost.utils.iab - -import android.app.Activity -import ca.allanwang.kau.utils.restart -import ca.allanwang.kau.utils.startLink -import ca.allanwang.kau.utils.startPlayStoreLink -import ca.allanwang.kau.utils.string -import com.crashlytics.android.answers.PurchaseEvent -import com.pitchedapps.frost.R -import com.pitchedapps.frost.activities.SettingsActivity -import com.pitchedapps.frost.utils.* - -/** - * Created by Allan Wang on 2017-06-30. - */ - -private fun playStoreLog(text: String) { - L.e(Throwable(text)) { "IAB Play Store Exception" } -} - -/** - * Properly restart an activity - */ -private fun Activity.playRestart() { - if (this is SettingsActivity) { - setResult(REQUEST_RESTART) - finish() - } else restart() -} - -fun Activity?.playStoreNoLongerPro() { - Prefs.pro = false - L.d { "IAB No longer pro" } - frostAnswers { - logPurchase(PurchaseEvent() - .putCustomAttribute("result", "no longer pro") - .putSuccess(false)) - } - if (this == null) return - materialDialogThemed { - title(R.string.uh_oh) - content(R.string.play_store_not_pro) - positiveText(R.string.reload) - dismissListener { - this@playStoreNoLongerPro.playRestart() - } - } -} - -fun Activity?.playStoreFoundPro() { - Prefs.pro = true - L.d { "Found pro" } - if (this == null) return - materialDialogThemed { - title(R.string.found_pro) - content(R.string.found_pro_desc) - positiveText(R.string.reload) - dismissListener { - this@playStoreFoundPro.playRestart() - } - } -} - -fun Activity.playStorePurchaseUnsupported() { - L.d { "Play store not found" } - materialDialogThemed { - title(R.string.uh_oh) - content(R.string.play_store_unsupported) - negativeText(R.string.kau_close) - positiveText(R.string.kau_play_store) - neutralText(R.string.paypal) - onPositive { _, _ -> startPlayStoreLink(R.string.play_store_package_id) } - onNeutral { _, _ -> startLink(string(R.string.dev_paypal)) } - } -} - -fun Activity.playStorePurchasedSuccessfully(key: String) { - L.d { "Play store purchased $key successfully" } - materialDialogThemed { - title(R.string.play_thank_you) - content(R.string.play_purchased_pro) - positiveText(R.string.kau_ok) - neutralText(R.string.kau_rate) - onNeutral { _, _ -> startPlayStoreLink(R.string.play_store_package_id) } - } -} - -fun Activity.purchaseRestored() { - L.d { "Purchase restored" } - materialDialogThemed { - title(R.string.play_thank_you) - content(R.string.purchases_restored_with_pro) - positiveText(R.string.kau_ok) - } -}
\ No newline at end of file diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/iab/IabBinder.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/iab/IabBinder.kt deleted file mode 100644 index 568127a2..00000000 --- a/app/src/main/kotlin/com/pitchedapps/frost/utils/iab/IabBinder.kt +++ /dev/null @@ -1,188 +0,0 @@ -package com.pitchedapps.frost.utils.iab - -import android.app.Activity -import android.content.Intent -import com.anjlab.android.iab.v3.BillingProcessor -import com.anjlab.android.iab.v3.TransactionDetails -import com.crashlytics.android.answers.PurchaseEvent -import com.pitchedapps.frost.BuildConfig -import com.pitchedapps.frost.utils.L -import com.pitchedapps.frost.utils.Prefs -import com.pitchedapps.frost.utils.frostAnswers -import com.pitchedapps.frost.utils.logFrostAnswers -import org.jetbrains.anko.doAsync -import org.jetbrains.anko.onComplete -import org.jetbrains.anko.uiThread -import java.lang.ref.WeakReference -import java.math.BigDecimal -import java.util.* - -/** - * Created by Allan Wang on 2017-07-22. - */ -private const val FROST_PRO = "frost_pro" - -/** - * Implemented pro checker with a hook for debug builds - * Use this when checking if the pro feature is enabled - */ -inline val IS_FROST_PRO: Boolean - get() = Prefs.pro || (BuildConfig.DEBUG && Prefs.debugPro) - -interface FrostBilling : BillingProcessor.IBillingHandler { - fun Activity.onCreateBilling() - fun onDestroyBilling() - fun purchasePro() - fun restorePurchases() - fun onActivityResultBilling(requestCode: Int, resultCode: Int, data: Intent?): Boolean -} - -abstract class IabBinder : FrostBilling { - - var bp: BillingProcessor? = null - lateinit var activityRef: WeakReference<Activity> - val activity - get() = activityRef.get() - - final override fun Activity.onCreateBilling() { - activityRef = WeakReference(this) - doAsync { - bp = BillingProcessor.newBillingProcessor(this@onCreateBilling, PUBLIC_BILLING_KEY, this@IabBinder) - bp?.initialize() - } - } - - override fun onDestroyBilling() { - activityRef.clear() - bp?.release() - bp = null - } - - override fun onBillingInitialized() = L.i { "IAB initialized" } - - override fun onPurchaseHistoryRestored() = L.d { "IAB restored" } - - override fun onProductPurchased(productId: String, details: TransactionDetails?) { - bp.doAsync { - L.i { "IAB $productId purchased" } - val listing = weakRef.get()?.getPurchaseListingDetails(productId) ?: return@doAsync - val currency = try { - Currency.getInstance(listing.currency) - } catch (e: Exception) { - null - } - frostAnswers { - logPurchase(PurchaseEvent().apply { - putItemId(productId) - putSuccess(true) - if (currency != null) { - putCurrency(currency) - putItemType(productId) - putItemPrice(BigDecimal.valueOf(listing.priceValue)) - } - }) - } - } - } - - override fun onBillingError(errorCode: Int, error: Throwable?) { - frostAnswers { - logPurchase(PurchaseEvent() - .putCustomAttribute("result", errorCode.toString()) - .putSuccess(false)) - } - error.logFrostAnswers("IAB error $errorCode") - } - - override fun onActivityResultBilling(requestCode: Int, resultCode: Int, data: Intent?): Boolean = bp?.handleActivityResult(requestCode, resultCode, data) - ?: false - - override fun purchasePro() { - val bp = this.bp - if (bp == null) { - frostAnswers { - logPurchase(PurchaseEvent() - .putCustomAttribute("result", "null bp") - .putSuccess(false)) - } - L.eThrow("IAB null bp on purchase attempt") - return - } - val a = activity ?: return - - if (!BillingProcessor.isIabServiceAvailable(a) || !bp.isInitialized || !bp.isOneTimePurchaseSupported) - a.playStorePurchaseUnsupported() - else - bp.purchase(a, FROST_PRO) - } - -} - -class IabSettings : IabBinder() { - - override fun onProductPurchased(productId: String, details: TransactionDetails?) { - super.onProductPurchased(productId, details) - activity?.playStorePurchasedSuccessfully(productId) - } - - override fun onBillingError(errorCode: Int, error: Throwable?) { - super.onBillingError(errorCode, error) - L.e { "Billing error $errorCode ${error?.message}" } - } - - /** - * Attempts to get pro, or launch purchase flow if user doesn't have it - */ - override fun restorePurchases() { - bp.doAsync { - val load = weakRef.get()?.loadOwnedPurchasesFromGoogle() ?: return@doAsync - L.d { "IAB settings load from google $load" } - uiThread { - if (!(weakRef.get()?.isPurchased(FROST_PRO) ?: return@uiThread)) { - if (Prefs.pro) activity.playStoreNoLongerPro() - else purchasePro() - } else { - if (!Prefs.pro) activity.playStoreFoundPro() - else activity?.purchaseRestored() - } - } - } - } -} - -class IabMain : IabBinder() { - - override fun onBillingInitialized() { - super.onBillingInitialized() - restorePurchases() - } - - override fun onPurchaseHistoryRestored() { - super.onPurchaseHistoryRestored() - restorePurchases() - } - - private var restored = false - - /** - * Checks for pro and only does so once - * A null check is added but it should never happen - * given that this is only called with bp is ready - */ - override fun restorePurchases() { - if (restored || bp == null) return - restored = true - bp.doAsync { - val load = weakRef.get()?.loadOwnedPurchasesFromGoogle() ?: false - L.d { "IAB main load from google $load" } - onComplete { - if (weakRef.get()?.isPurchased(FROST_PRO) != true) { - if (Prefs.pro) activity.playStoreNoLongerPro() - } else { - if (!Prefs.pro) activity.playStoreFoundPro() - } - onDestroyBilling() - } - } - } -}
\ No newline at end of file diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/iab/Key.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/iab/Key.kt deleted file mode 100644 index a21d8670..00000000 --- a/app/src/main/kotlin/com/pitchedapps/frost/utils/iab/Key.kt +++ /dev/null @@ -1,33 +0,0 @@ -package com.pitchedapps.frost.utils.iab - -/** - * Created by Allan Wang on 2017-06-23. - * - * NOTE - * - * Since this is an open source project and all other components are essentially public, - * I have decided to add the keys here too; - * they can be reverse engineered relatively easily since they are constants anyways. - * This is the public billing key from the play store - */ -private const val play_key_1 = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgyTZS" -private const val play_key_2 = "K9Bd3ALpr9KJUsVGczP9CcPelWkdnJfNrrzu1EztJyrHRsGQ4" -private const val play_key_3 = "QVWY9NZwc6Nrk9qdJlEdr8AJAxJ+JiwUqsj3/TxxUYm/G7q8Z" -private const val play_key_4 = "7zo8jSkYZyzqwoAl2PDx2kleI4sZLkhCRLyE6dGQEZQmvJ6kk" -private const val play_key_5 = "W12Gz3FagAM5luRGsoWZj40pJItUrGJA9euMWq4rMhVZv4mVk" -private const val play_key_6 = "KFJB9/vhF/XGz7txpYlFxMESzXuKsbEDKmKCHzvySLq8Ki4N9" -private const val play_key_7 = "DzbgUiw+VzA2KpSVp66JH3GEU8egO8i9SvAWeCPikuolooRVh" -private const val play_key_8 = "jwfBV7gDxZztoLuvmQU6kXvCwRnRa+mkfUnBKKLkH1QIDAQAB" - -internal val PUBLIC_BILLING_KEY: String by lazy { - StringBuilder() - .append(play_key_1) - .append(play_key_2) - .append(play_key_3) - .append(play_key_4) - .append(play_key_5) - .append(play_key_6) - .append(play_key_7) - .append(play_key_8) - .toString() -}
\ No newline at end of file |