aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/kotlin/com/pitchedapps
diff options
context:
space:
mode:
authorAllan Wang <me@allanwang.ca>2018-03-21 01:28:31 -0400
committerGitHub <noreply@github.com>2018-03-21 01:28:31 -0400
commitd36dfe98a52ced46c5106b28304ae5d245180a7f (patch)
treea20261ea953b7e29e8754cf641e9ed743511079d /app/src/main/kotlin/com/pitchedapps
parent6b85bc72a864e65d99ae65802ce03f977a98c906 (diff)
downloadfrost-d36dfe98a52ced46c5106b28304ae5d245180a7f.tar.gz
frost-d36dfe98a52ced46c5106b28304ae5d245180a7f.tar.bz2
frost-d36dfe98a52ced46c5106b28304ae5d245180a7f.zip
Feature/bugsnag (#807)
* Add bugsnag * Remove crashlytics * Remove pro features and iab * Make analytics opt in * Clean settings activity * Clean settings activity 2
Diffstat (limited to 'app/src/main/kotlin/com/pitchedapps')
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt11
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/AboutActivity.kt2
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt26
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/ImageActivity.kt4
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt9
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/SettingsActivity.kt30
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/dbflow/CookiesDb.kt4
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentBase.kt2
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/services/FrostNotifications.kt4
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/services/NotificationService.kt6
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/settings/Appearance.kt13
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/settings/Feed.kt5
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/L.kt6
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt12
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt30
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/iab/IABDialogs.kt95
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/iab/IabBinder.kt188
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/iab/Key.kt33
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/DebugWebView.kt5
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClients.kt7
20 files changed, 43 insertions, 449 deletions
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt b/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt
index 36b51753..16e23d53 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt
@@ -7,10 +7,9 @@ import android.net.Uri
import android.os.Bundle
import android.widget.ImageView
import ca.allanwang.kau.logging.KL
+import com.bugsnag.android.Bugsnag
import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.signature.ApplicationVersionSignature
-import com.crashlytics.android.Crashlytics
-import com.crashlytics.android.answers.Answers
import com.mikepenz.materialdrawer.util.AbstractDrawerImageLoader
import com.mikepenz.materialdrawer.util.DrawerImageLoader
import com.pitchedapps.frost.dbflow.CookiesDb
@@ -28,7 +27,6 @@ import com.raizlabs.android.dbflow.config.DatabaseConfig
import com.raizlabs.android.dbflow.config.FlowConfig
import com.raizlabs.android.dbflow.config.FlowManager
import com.raizlabs.android.dbflow.runtime.ContentResolverNotifier
-import io.fabric.sdk.android.Fabric
import io.reactivex.plugins.RxJavaPlugins
import java.net.SocketTimeoutException
import java.util.*
@@ -63,8 +61,11 @@ class FrostApp : Application() {
// if (LeakCanary.isInAnalyzerProcess(this)) return
// refWatcher = LeakCanary.install(this)
if (!BuildConfig.DEBUG) {
- Fabric.with(this, Crashlytics(), Answers())
- Crashlytics.setUserIdentifier(Prefs.frostId)
+ Bugsnag.init(this)
+ Bugsnag.setAutoCaptureSessions(true)
+ Bugsnag.getClient().setUserId(Prefs.frostId)
+
+// setUser("userId", "user@email.com", "User Name")
}
KL.shouldLog = { BuildConfig.DEBUG }
Prefs.verboseLogging = false
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/AboutActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/AboutActivity.kt
index 691f050e..8e6677f9 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/activities/AboutActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/AboutActivity.kt
@@ -136,7 +136,7 @@ class AboutActivity : AboutActivityBase(null, {
val c = itemView.context
val size = c.dimenPixelSize(R.dimen.kau_avatar_bounds)
images = arrayOf<Pair<IIcon, () -> Unit>>(
- GoogleMaterial.Icon.gmd_star to { c.startPlayStoreLink(R.string.play_store_package_id) },
+// GoogleMaterial.Icon.gmd_star to { c.startPlayStoreLink(R.string.play_store_package_id) },
CommunityMaterial.Icon.cmd_reddit to { c.startLink(R.string.reddit_url) },
CommunityMaterial.Icon.cmd_github_circle to { c.startLink(R.string.github_url) },
CommunityMaterial.Icon.cmd_xda to { c.startLink(R.string.xda_url) }
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt
index 809e8a56..8b584112 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt
@@ -38,7 +38,6 @@ import co.zsmb.materialdrawerkt.draweritems.badgeable.secondaryItem
import co.zsmb.materialdrawerkt.draweritems.divider
import co.zsmb.materialdrawerkt.draweritems.profile.profile
import co.zsmb.materialdrawerkt.draweritems.profile.profileSetting
-import com.crashlytics.android.answers.ContentViewEvent
import com.mikepenz.google_material_typeface_library.GoogleMaterial
import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.typeface.IIcon
@@ -54,7 +53,6 @@ import com.pitchedapps.frost.dbflow.TAB_COUNT
import com.pitchedapps.frost.dbflow.loadFbCookie
import com.pitchedapps.frost.dbflow.loadFbTabs
import com.pitchedapps.frost.enums.MainActivityLayout
-import com.pitchedapps.frost.enums.Theme
import com.pitchedapps.frost.facebook.FbCookie
import com.pitchedapps.frost.facebook.FbItem
import com.pitchedapps.frost.facebook.PROFILE_PICTURE_URL
@@ -63,9 +61,6 @@ import com.pitchedapps.frost.fragments.WebFragment
import com.pitchedapps.frost.parsers.FrostSearch
import com.pitchedapps.frost.parsers.SearchParser
import com.pitchedapps.frost.utils.*
-import com.pitchedapps.frost.utils.iab.FrostBilling
-import com.pitchedapps.frost.utils.iab.IS_FROST_PRO
-import com.pitchedapps.frost.utils.iab.IabMain
import com.pitchedapps.frost.views.BadgedIcon
import com.pitchedapps.frost.views.FrostVideoViewer
import com.pitchedapps.frost.views.FrostViewPager
@@ -77,8 +72,7 @@ import com.pitchedapps.frost.views.FrostViewPager
*/
abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
FileChooserContract by FileChooserDelegate(),
- VideoViewHolder, SearchViewHolder,
- FrostBilling by IabMain() {
+ VideoViewHolder, SearchViewHolder {
protected lateinit var adapter: SectionsPagerAdapter
override val frameWrapper: FrameLayout by bindView(R.id.frame_wrapper)
@@ -115,13 +109,12 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
onNestedCreate(savedInstanceState)
L.i { "Main finished loading UI in ${System.currentTimeMillis() - start} ms" }
controlWebview = WebView(this)
- onCreateBilling()
if (BuildConfig.VERSION_CODE > Prefs.versionCode) {
Prefs.prevVersionCode = Prefs.versionCode
Prefs.versionCode = BuildConfig.VERSION_CODE
if (!BuildConfig.DEBUG) {
frostChangelog()
- frostAnswersCustom("Version",
+ frostEvent("Version",
"Version code" to BuildConfig.VERSION_CODE,
"Prev version code" to Prefs.prevVersionCode,
"Version name" to BuildConfig.VERSION_NAME,
@@ -283,11 +276,7 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
selectedColor = 0x00000001.toLong()
identifier = item.titleId.toLong()
onClick { _ ->
- frostAnswers {
- logContentView(ContentViewEvent()
- .putContentName(item.name)
- .putContentType("drawer_item"))
- }
+ frostEvent("Drawer Tab", "name" to item.name)
launchWebOverlay(item.url)
false
}
@@ -419,16 +408,7 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
super.onPause()
}
- override fun onStart() {
- //validate some pro features
- if (!IS_FROST_PRO) {
- if (Prefs.theme == Theme.CUSTOM.ordinal) Prefs.theme = Theme.DEFAULT.ordinal
- }
- super.onStart()
- }
-
override fun onDestroy() {
- onDestroyBilling()
controlWebview?.destroy()
super.onDestroy()
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/ImageActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/ImageActivity.kt
index 1bc3334f..e9426beb 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/activities/ImageActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/ImageActivity.kt
@@ -121,7 +121,7 @@ class ImageActivity : KauBaseActivity() {
photo.setOnImageEventListener(object : SubsamplingScaleImageView.DefaultOnImageEventListener() {
override fun onImageLoadError(e: Exception?) {
errorRef = e
- e.logFrostAnswers("Image load error")
+ e.logFrostEvent("Image load error")
L.e { "Failed to load image $imageUrl" }
tempFile?.delete()
fabAction = FabStates.ERROR
@@ -307,7 +307,7 @@ internal enum class FabStates(val iicon: IIcon, val iconColor: Int = Prefs.iconC
activity.startActivity(intent)
} catch (e: Exception) {
activity.errorRef = e
- e.logFrostAnswers("Image share failed")
+ e.logFrostEvent("Image share failed")
activity.frostSnackbar(R.string.image_share_failed)
}
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt
index aa2e5871..9afca21e 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/LoginActivity.kt
@@ -15,7 +15,6 @@ import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.Target
-import com.crashlytics.android.answers.LoginEvent
import com.pitchedapps.frost.R
import com.pitchedapps.frost.dbflow.CookieModel
import com.pitchedapps.frost.dbflow.fetchUsername
@@ -90,11 +89,7 @@ class LoginActivity : BaseActivity() {
}
textview.text = String.format(getString(R.string.welcome), name)
textview.fadeIn()
- frostAnswers {
- logLogin(LoginEvent()
- .putMethod("frost_browser")
- .putSuccess(true))
- }
+ frostEvent("Login" , "success" to true )
/*
* The user may have logged into an account that is already in the database
* We will let the db handle duplicates and load it now after the new account has been saved
@@ -123,7 +118,7 @@ class LoginActivity : BaseActivity() {
}
override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Drawable>?, isFirstResource: Boolean): Boolean {
- e.logFrostAnswers("Profile loading exception")
+ e.logFrostEvent("Profile loading exception")
profileSubject.onSuccess(false)
return false
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/SettingsActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/SettingsActivity.kt
index 8d4e521f..97d82884 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/activities/SettingsActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/SettingsActivity.kt
@@ -11,25 +11,20 @@ import android.view.MenuItem
import ca.allanwang.kau.kpref.activity.CoreAttributeContract
import ca.allanwang.kau.kpref.activity.KPrefActivity
import ca.allanwang.kau.kpref.activity.KPrefAdapterBuilder
-import ca.allanwang.kau.kpref.activity.items.KPrefItemBase
import ca.allanwang.kau.ui.views.RippleCanvas
import ca.allanwang.kau.utils.*
import com.mikepenz.community_material_typeface_library.CommunityMaterial
import com.mikepenz.google_material_typeface_library.GoogleMaterial
-import com.pitchedapps.frost.BuildConfig
import com.pitchedapps.frost.R
import com.pitchedapps.frost.enums.Support
import com.pitchedapps.frost.settings.*
import com.pitchedapps.frost.utils.*
-import com.pitchedapps.frost.utils.iab.FrostBilling
-import com.pitchedapps.frost.utils.iab.IS_FROST_PRO
-import com.pitchedapps.frost.utils.iab.IabSettings
/**
* Created by Allan Wang on 2017-06-06.
*/
-class SettingsActivity : KPrefActivity(), FrostBilling by IabSettings() {
+class SettingsActivity : KPrefActivity() {
var resultFlag = Activity.RESULT_CANCELED
@@ -56,8 +51,6 @@ class SettingsActivity : KPrefActivity(), FrostBilling by IabSettings() {
return
}
}
- if (!onActivityResultBilling(requestCode, resultCode, data))
- super.onActivityResult(requestCode, resultCode, data)
reloadList()
}
@@ -125,12 +118,7 @@ class SettingsActivity : KPrefActivity(), FrostBilling by IabSettings() {
iicon = CommunityMaterial.Icon.cmd_flask_outline
}
- plainText(R.string.get_pro) {
- descRes = R.string.get_pro_desc
- iicon = GoogleMaterial.Icon.gmd_star
- visible = { !IS_FROST_PRO }
- onClick = { restorePurchases() }
- }
+ // todo add donation?
plainText(R.string.about_frost) {
descRes = R.string.about_frost_desc
@@ -159,14 +147,6 @@ class SettingsActivity : KPrefActivity(), FrostBilling by IabSettings() {
visible = { Prefs.debugSettings }
}
- if (BuildConfig.DEBUG) {
- checkbox(R.string.custom_pro, { Prefs.debugPro }, { Prefs.debugPro = it })
- }
- }
-
- fun KPrefItemBase.BaseContract<*>.dependsOnPro() {
- onDisabledClick = { purchasePro() }
- enabler = { IS_FROST_PRO }
}
fun shouldRestartMain() {
@@ -179,7 +159,6 @@ class SettingsActivity : KPrefActivity(), FrostBilling by IabSettings() {
super.onCreate(savedInstanceState)
animate = Prefs.animate
themeExterior(false)
- onCreateBilling()
}
fun themeExterior(animate: Boolean = true) {
@@ -222,9 +201,4 @@ class SettingsActivity : KPrefActivity(), FrostBilling by IabSettings() {
fun setFrostResult(flag: Int) {
resultFlag = resultFlag or flag
}
-
- override fun onDestroy() {
- onDestroyBilling()
- super.onDestroy()
- }
} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/dbflow/CookiesDb.kt b/app/src/main/kotlin/com/pitchedapps/frost/dbflow/CookiesDb.kt
index e98020d4..69cf32b7 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/dbflow/CookiesDb.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/dbflow/CookiesDb.kt
@@ -6,7 +6,7 @@ import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
import com.pitchedapps.frost.facebook.FbItem
import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.utils.frostJsoup
-import com.pitchedapps.frost.utils.logFrostAnswers
+import com.pitchedapps.frost.utils.logFrostEvent
import com.raizlabs.android.dbflow.annotation.ConflictAction
import com.raizlabs.android.dbflow.annotation.Database
import com.raizlabs.android.dbflow.annotation.PrimaryKey
@@ -76,7 +76,7 @@ inline fun CookieModel.fetchUsername(crossinline callback: (String) -> Unit) {
L.d { "Fetch username found" }
} catch (e: Exception) {
if (e !is UnknownHostException)
- e.logFrostAnswers("Fetch username failed")
+ e.logFrostEvent("Fetch username failed")
} finally {
if (result.isBlank() && (name?.isNotBlank() == true)) {
callback(name!!)
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentBase.kt b/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentBase.kt
index a644e966..cf48893c 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentBase.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/fragments/FragmentBase.kt
@@ -55,7 +55,7 @@ abstract class BaseFragment : Fragment(), FragmentContract, DynamicUiContract {
if (value || this is WebFragment) return
arguments!!.putBoolean(ARG_VALID, value)
L.e { "Invalidating position $position" }
- frostAnswersCustom("Native Fallback",
+ frostEvent("Native Fallback",
"Item" to baseEnum.name)
(context as MainActivityContract).reloadFragment(this)
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/services/FrostNotifications.kt b/app/src/main/kotlin/com/pitchedapps/frost/services/FrostNotifications.kt
index 30c94744..ab61b37d 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/services/FrostNotifications.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/services/FrostNotifications.kt
@@ -36,7 +36,7 @@ import com.pitchedapps.frost.parsers.ParseNotification
import com.pitchedapps.frost.utils.ARG_USER_ID
import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.utils.Prefs
-import com.pitchedapps.frost.utils.frostAnswersCustom
+import com.pitchedapps.frost.utils.frostEvent
import java.util.*
/**
@@ -190,7 +190,7 @@ enum class NotificationType(
if (newLatestEpoch > prevLatestEpoch)
putTime(prevNotifTime, newLatestEpoch).save()
L.d { "Notif $name new epoch ${getTime(lastNotificationTime(userId))}" }
- frostAnswersCustom("Notifications", "Type" to name, "Count" to notifs.size)
+ frostEvent("Notifications", "Type" to name, "Count" to notifs.size)
if (notifs.size > 1)
summaryNotification(context, userId, notifs.size).notify(context)
val ringtone = ringtone()
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationService.kt b/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationService.kt
index 6ba968e7..22477eab 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationService.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationService.kt
@@ -10,7 +10,7 @@ import com.pitchedapps.frost.dbflow.CookieModel
import com.pitchedapps.frost.dbflow.loadFbCookiesSync
import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.utils.Prefs
-import com.pitchedapps.frost.utils.frostAnswersCustom
+import com.pitchedapps.frost.utils.frostEvent
import org.jetbrains.anko.doAsync
import java.util.concurrent.Future
@@ -31,7 +31,7 @@ class NotificationService : JobService() {
override fun onStopJob(params: JobParameters?): Boolean {
val time = System.currentTimeMillis() - startTime
L.d { "Notification service has finished abruptly in $time ms" }
- frostAnswersCustom("NotificationTime",
+ frostEvent("NotificationTime",
"Type" to "Service force stop",
"IM Included" to Prefs.notificationsInstantMessages,
"Duration" to time)
@@ -43,7 +43,7 @@ class NotificationService : JobService() {
fun finish(params: JobParameters?) {
val time = System.currentTimeMillis() - startTime
L.i { "Notification service has finished in $time ms" }
- frostAnswersCustom("NotificationTime",
+ frostEvent("NotificationTime",
"Type" to "Service",
"IM Included" to Prefs.notificationsInstantMessages,
"Duration" to time)
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/settings/Appearance.kt b/app/src/main/kotlin/com/pitchedapps/frost/settings/Appearance.kt
index eeeca01f..314590e2 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/settings/Appearance.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/Appearance.kt
@@ -11,7 +11,6 @@ import com.pitchedapps.frost.enums.MainActivityLayout
import com.pitchedapps.frost.enums.Theme
import com.pitchedapps.frost.injectors.CssAssets
import com.pitchedapps.frost.utils.*
-import com.pitchedapps.frost.utils.iab.IS_FROST_PRO
import com.pitchedapps.frost.views.KPrefTextSeekbar
/**
@@ -25,22 +24,16 @@ fun SettingsActivity.getAppearancePrefs(): KPrefAdapterBuilder.() -> Unit = {
onClick = {
materialDialogThemed {
title(R.string.theme)
- items(Theme.values()
- .map { if (it == Theme.CUSTOM && !IS_FROST_PRO) R.string.custom_pro else it.textRes }
- .map { string(it) })
+ items(Theme.values().map { string(it.textRes) })
itemsCallbackSingleChoice(item.pref) { _, _, which, _ ->
if (item.pref != which) {
- if (which == Theme.CUSTOM.ordinal && !IS_FROST_PRO) {
- purchasePro()
- return@itemsCallbackSingleChoice true
- }
item.pref = which
shouldRestartMain()
reload()
setFrostTheme(true)
themeExterior()
invalidateOptionsMenu()
- frostAnswersCustom("Theme", "Count" to Theme(which).name)
+ frostEvent("Theme", "Count" to Theme(which).name)
}
true
}
@@ -125,7 +118,7 @@ fun SettingsActivity.getAppearancePrefs(): KPrefAdapterBuilder.() -> Unit = {
if (item.pref != which) {
item.pref = which
shouldRestartMain()
- frostAnswersCustom("Main Layout", "Type" to MainActivityLayout(which).name)
+ frostEvent("Main Layout", "Type" to MainActivityLayout(which).name)
}
true
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/settings/Feed.kt b/app/src/main/kotlin/com/pitchedapps/frost/settings/Feed.kt
index 78898eeb..5de68e21 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/settings/Feed.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/Feed.kt
@@ -46,14 +46,11 @@ fun SettingsActivity.getFeedPrefs(): KPrefAdapterBuilder.() -> Unit = {
descRes = R.string.composer_desc
}
- header(R.string.pro_features)
-
checkbox(R.string.suggested_friends, Prefs::showSuggestedFriends, {
Prefs.showSuggestedFriends = it
setFrostResult(REQUEST_REFRESH)
}) {
descRes = R.string.suggested_friends_desc
- dependsOnPro()
}
checkbox(R.string.suggested_groups, Prefs::showSuggestedGroups, {
@@ -61,7 +58,6 @@ fun SettingsActivity.getFeedPrefs(): KPrefAdapterBuilder.() -> Unit = {
setFrostResult(REQUEST_REFRESH)
}) {
descRes = R.string.suggested_groups_desc
- dependsOnPro()
}
checkbox(R.string.facebook_ads, Prefs::showFacebookAds, {
@@ -69,6 +65,5 @@ fun SettingsActivity.getFeedPrefs(): KPrefAdapterBuilder.() -> Unit = {
setFrostResult(REQUEST_REFRESH)
}) {
descRes = R.string.facebook_ads_desc
- dependsOnPro()
}
} \ No newline at end of file
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
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/DebugWebView.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/DebugWebView.kt
index 4ac9e600..4c4e5525 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/DebugWebView.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/DebugWebView.kt
@@ -15,7 +15,6 @@ import com.pitchedapps.frost.injectors.jsInject
import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.utils.Prefs
import com.pitchedapps.frost.utils.createFreshFile
-import com.pitchedapps.frost.utils.iab.IS_FROST_PRO
import com.pitchedapps.frost.utils.isFacebookUrl
import org.jetbrains.anko.withAlpha
import java.io.File
@@ -85,8 +84,8 @@ class DebugWebView @JvmOverloads constructor(
CssAssets.ROUND_ICONS.maybe(Prefs.showRoundedIcons),
CssHider.CORE,
CssHider.COMPOSER.maybe(!Prefs.showComposer),
- CssHider.PEOPLE_YOU_MAY_KNOW.maybe(!Prefs.showSuggestedFriends && IS_FROST_PRO),
- CssHider.SUGGESTED_GROUPS.maybe(!Prefs.showSuggestedGroups && IS_FROST_PRO),
+ CssHider.PEOPLE_YOU_MAY_KNOW.maybe(!Prefs.showSuggestedFriends),
+ CssHider.SUGGESTED_GROUPS.maybe(!Prefs.showSuggestedGroups),
Prefs.themeInjector,
CssHider.NON_RECENT.maybe((url?.contains("?sk=h_chr") ?: false)
&& Prefs.aggressiveRecents))
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClients.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClients.kt
index d4e1c103..f1d03f35 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClients.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClients.kt
@@ -10,7 +10,6 @@ import com.pitchedapps.frost.facebook.FB_URL_BASE
import com.pitchedapps.frost.facebook.FbItem
import com.pitchedapps.frost.injectors.*
import com.pitchedapps.frost.utils.*
-import com.pitchedapps.frost.utils.iab.IS_FROST_PRO
import com.pitchedapps.frost.views.FrostWebView
import io.reactivex.subjects.Subject
import org.jetbrains.anko.withAlpha
@@ -67,14 +66,14 @@ open class FrostWebViewClient(val web: FrostWebView) : BaseWebViewClient() {
CssAssets.ROUND_ICONS.maybe(Prefs.showRoundedIcons),
CssHider.CORE,
CssHider.COMPOSER.maybe(!Prefs.showComposer),
- CssHider.PEOPLE_YOU_MAY_KNOW.maybe(!Prefs.showSuggestedFriends && IS_FROST_PRO),
- CssHider.SUGGESTED_GROUPS.maybe(!Prefs.showSuggestedGroups && IS_FROST_PRO),
+ CssHider.PEOPLE_YOU_MAY_KNOW.maybe(!Prefs.showSuggestedFriends),
+ CssHider.SUGGESTED_GROUPS.maybe(!Prefs.showSuggestedGroups),
Prefs.themeInjector,
CssHider.NON_RECENT.maybe((web.url?.contains("?sk=h_chr") ?: false)
&& Prefs.aggressiveRecents),
JsAssets.DOCUMENT_WATCHER,
JsAssets.CLICK_A,
- CssHider.ADS.maybe(!Prefs.showFacebookAds && IS_FROST_PRO),
+ CssHider.ADS.maybe(!Prefs.showFacebookAds),
JsAssets.CONTEXT_A,
JsAssets.HEADER_HIDER,
JsAssets.MEDIA)