aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAllan Wang <me@allanwang.ca>2019-08-04 22:56:03 -0700
committerGitHub <noreply@github.com>2019-08-04 22:56:03 -0700
commit2eacc8cb77b561eb1da11acb6ec8f620195fd24f (patch)
tree6eca0acb160f1b6696f4b225c4e4eb9f46644943
parent3dcf1e1f697b06a88876a183bacf5b67f0d0e8dd (diff)
parentdd391481881683e7b58a69ef2b9b671fb6197208 (diff)
downloadfrost-2eacc8cb77b561eb1da11acb6ec8f620195fd24f.tar.gz
frost-2eacc8cb77b561eb1da11acb6ec8f620195fd24f.tar.bz2
frost-2eacc8cb77b561eb1da11acb6ec8f620195fd24f.zip
Merge pull request #1496 from AllanWang/bugsnag-opt-out
Bugsnag opt out
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt54
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/IntroActivity.kt4
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/intro/IntroMainFragments.kt40
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/L.kt26
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt18
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt18
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoView.kt23
-rw-r--r--app/src/main/play/en-US/whatsnew11
-rw-r--r--app/src/main/res/layout/intro_analytics.xml52
-rw-r--r--app/src/main/res/layout/intro_end.xml2
-rw-r--r--app/src/main/res/values/styles.xml4
-rw-r--r--app/src/main/res/xml/frost_changelog.xml2
-rw-r--r--docs/Changelog.md5
13 files changed, 205 insertions, 54 deletions
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt b/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt
index 0c762b41..d6d6faea 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/FrostApp.kt
@@ -25,6 +25,7 @@ import android.widget.ImageView
import ca.allanwang.kau.logging.KL
import ca.allanwang.kau.utils.buildIsLollipopAndUp
import com.bugsnag.android.Bugsnag
+import com.bugsnag.android.Configuration
import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.signature.ApplicationVersionSignature
import com.mikepenz.materialdrawer.util.AbstractDrawerImageLoader
@@ -83,18 +84,13 @@ class FrostApp : Application() {
.withDatabase(NotificationDb.NAME, NotificationDb::class)
.build()
)
- Showcase.initialize(this, "${BuildConfig.APPLICATION_ID}.showcase")
- Prefs.initialize(this, "${BuildConfig.APPLICATION_ID}.prefs")
// if (LeakCanary.isInAnalyzerProcess(this)) return
// refWatcher = LeakCanary.install(this)
+ initPrefs()
initBugsnag()
- KL.shouldLog = { BuildConfig.DEBUG }
- Prefs.verboseLogging = false
+
L.i { "Begin Frost for Facebook" }
FrostPglAdBlock.init(this)
- if (Prefs.installDate == -1L) Prefs.installDate = System.currentTimeMillis()
- if (Prefs.identifier == -1) Prefs.identifier = Random().nextInt(Int.MAX_VALUE)
- Prefs.lastLaunch = System.currentTimeMillis()
super.onCreate()
@@ -118,7 +114,7 @@ class FrostApp : Application() {
.thumbnail(old).into(imageView)
}
})
- if (BuildConfig.DEBUG)
+ if (BuildConfig.DEBUG) {
registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
override fun onActivityPaused(activity: Activity) {}
override fun onActivityResumed(activity: Activity) {}
@@ -136,26 +132,48 @@ class FrostApp : Application() {
L.d { "Activity ${activity.localClassName} created" }
}
})
+ }
startKoin {
- if (BuildConfig.DEBUG)
+ if (BuildConfig.DEBUG) {
androidLogger()
+ }
androidContext(this@FrostApp)
modules(FrostDatabase.module(this@FrostApp))
}
}
+ private fun initPrefs() {
+ Showcase.initialize(this, "${BuildConfig.APPLICATION_ID}.showcase")
+ Prefs.initialize(this, "${BuildConfig.APPLICATION_ID}.prefs")
+ KL.shouldLog = { BuildConfig.DEBUG }
+ Prefs.verboseLogging = false
+ if (Prefs.installDate == -1L) {
+ Prefs.installDate = System.currentTimeMillis()
+ }
+ if (Prefs.identifier == -1) {
+ Prefs.identifier = Random().nextInt(Int.MAX_VALUE)
+ }
+ Prefs.lastLaunch = System.currentTimeMillis()
+ }
+
private fun initBugsnag() {
- if (BuildConfig.DEBUG) return
- Bugsnag.init(this)
- Bugsnag.disableExceptionHandler()
- if (!BuildConfig.APPLICATION_ID.startsWith("com.pitchedapps.frost")) return
+ if (BuildConfig.DEBUG) {
+ return
+ }
+ if (!BuildConfig.APPLICATION_ID.startsWith("com.pitchedapps.frost")) {
+ return
+ }
val version = BuildUtils.match(BuildConfig.VERSION_NAME)
?: return L.d { "Bugsnag disabled for ${BuildConfig.VERSION_NAME}" }
- Bugsnag.enableExceptionHandler()
- Bugsnag.setNotifyReleaseStages(*BuildUtils.getAllStages())
- Bugsnag.setAppVersion(version.versionName)
- Bugsnag.setReleaseStage(BuildUtils.getStage(BuildConfig.BUILD_TYPE))
- Bugsnag.setAutoCaptureSessions(true)
+ val config = Configuration("83cf680ed01a6fda10fe497d1c0962bb").apply {
+ appVersion = version.versionName
+ releaseStage = BuildUtils.getStage(BuildConfig.BUILD_TYPE)
+ notifyReleaseStages = BuildUtils.getAllStages()
+ autoCaptureSessions = Prefs.analytics
+ enableExceptionHandler = Prefs.analytics
+ }
+ Bugsnag.init(this, config)
+ L.bugsnagInit = true
Bugsnag.setUserId(Prefs.frostId)
Bugsnag.addToTab("Build", "Application", BuildConfig.APPLICATION_ID)
Bugsnag.addToTab("Build", "Version", BuildConfig.VERSION_NAME)
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/IntroActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/IntroActivity.kt
index 1e106765..94f8d6c1 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/activities/IntroActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/IntroActivity.kt
@@ -45,6 +45,7 @@ import com.mikepenz.google_material_typeface_library.GoogleMaterial
import com.pitchedapps.frost.R
import com.pitchedapps.frost.intro.BaseIntroFragment
import com.pitchedapps.frost.intro.IntroAccountFragment
+import com.pitchedapps.frost.intro.IntroFragmentAnalytics
import com.pitchedapps.frost.intro.IntroFragmentEnd
import com.pitchedapps.frost.intro.IntroFragmentTheme
import com.pitchedapps.frost.intro.IntroFragmentWelcome
@@ -54,6 +55,7 @@ import com.pitchedapps.frost.utils.Prefs
import com.pitchedapps.frost.utils.cookies
import com.pitchedapps.frost.utils.launchNewTask
import com.pitchedapps.frost.utils.loadAssets
+import com.pitchedapps.frost.utils.setFrostTheme
import com.pitchedapps.frost.widgets.NotificationWidget
import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.launch
@@ -80,6 +82,7 @@ class IntroActivity : KauBaseActivity(), ViewPager.PageTransformer, ViewPager.On
IntroAccountFragment(),
IntroTabTouchFragment(),
IntroTabContextFragment(),
+ IntroFragmentAnalytics(),
IntroFragmentEnd()
)
@@ -111,6 +114,7 @@ class IntroActivity : KauBaseActivity(), ViewPager.PageTransformer, ViewPager.On
indicator.setColour(Prefs.textColor)
indicator.invalidate()
fragments.forEach { it.themeFragment() }
+ setFrostTheme(true)
}
/**
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroMainFragments.kt b/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroMainFragments.kt
index 8536dd1a..22dd086b 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroMainFragments.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/intro/IntroMainFragments.kt
@@ -30,10 +30,13 @@ import androidx.fragment.app.Fragment
import ca.allanwang.kau.kotlin.LazyResettableRegistry
import ca.allanwang.kau.utils.Kotterknife
import ca.allanwang.kau.utils.bindViewResettable
+import ca.allanwang.kau.utils.setIcon
import ca.allanwang.kau.utils.setOnSingleTapListener
+import com.mikepenz.google_material_typeface_library.GoogleMaterial
import com.pitchedapps.frost.R
import com.pitchedapps.frost.activities.IntroActivity
import com.pitchedapps.frost.utils.Prefs
+import kotlinx.android.synthetic.main.intro_analytics.*
/**
* Created by Allan Wang on 2017-07-28.
@@ -56,7 +59,8 @@ abstract class BaseIntroFragment(val layoutRes: Int) : Fragment() {
val increment = maxTranslation / views.size
views.forEachIndexed { i, group ->
group.forEach {
- it.translationX = if (offset > 0) -maxTranslation + i * increment else -(i + 1) * increment
+ it.translationX =
+ if (offset > 0) -maxTranslation + i * increment else -(i + 1) * increment
it.alpha = 1 - Math.abs(offset)
}
}
@@ -73,9 +77,14 @@ abstract class BaseIntroFragment(val layoutRes: Int) : Fragment() {
protected val image: ImageView by bindViewResettable(R.id.intro_image)
protected val desc: TextView by bindViewResettable(R.id.intro_desc)
- protected fun defaultViewArray(): Array<Array<out View>> = arrayOf(arrayOf(title), arrayOf(image), arrayOf(desc))
+ protected fun defaultViewArray(): Array<Array<out View>> =
+ arrayOf(arrayOf(title), arrayOf(image), arrayOf(desc))
- override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
return inflater.inflate(layoutRes, container, false)
}
@@ -128,6 +137,31 @@ class IntroFragmentWelcome : BaseIntroFragment(R.layout.intro_welcome) {
}
}
+class IntroFragmentAnalytics : BaseIntroFragment(R.layout.intro_analytics) {
+
+ val container: ConstraintLayout by bindViewResettable(R.id.intro_analytics_container)
+
+ override fun viewArray(): Array<Array<out View>> = arrayOf(
+ arrayOf(title), arrayOf(image),
+ arrayOf(intro_switch), arrayOf(desc)
+ )
+
+ override fun themeFragmentImpl() {
+ super.themeFragmentImpl()
+ image.imageTintList = ColorStateList.valueOf(Prefs.textColor)
+ }
+
+ @SuppressLint("ClickableViewAccessibility")
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ image.setIcon(GoogleMaterial.Icon.gmd_bug_report, 120)
+ intro_switch.isSelected = Prefs.analytics
+ intro_switch.setOnCheckedChangeListener { _, isChecked ->
+ Prefs.analytics = isChecked
+ }
+ }
+}
+
class IntroFragmentEnd : BaseIntroFragment(R.layout.intro_end) {
val container: ConstraintLayout by bindViewResettable(R.id.intro_end_container)
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 7c8c1895..dd8cf594 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/L.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/L.kt
@@ -41,28 +41,40 @@ object L : KauLogger("Frost", {
}
inline fun _i(message: () -> Any?) {
- if (BuildConfig.DEBUG)
+ if (BuildConfig.DEBUG) {
i(message)
+ }
}
inline fun _d(message: () -> Any?) {
- if (BuildConfig.DEBUG)
+ if (BuildConfig.DEBUG) {
d(message)
+ }
}
inline fun _e(e: Throwable?, message: () -> Any?) {
- if (BuildConfig.DEBUG)
+ if (BuildConfig.DEBUG) {
e(e, message)
+ }
}
+ var bugsnagInit = false
+
override fun logImpl(priority: Int, message: String?, t: Throwable?) {
- if (BuildConfig.DEBUG)
+ /*
+ * Debug flag is constant and should help with optimization
+ * bugsnagInit is changed per application and helps prevent crashes (if calling pre init)
+ * analytics is changed by the user, and may be toggled throughout the app
+ */
+ if (BuildConfig.DEBUG || !bugsnagInit || !Prefs.analytics) {
super.logImpl(priority, message, t)
- else {
- if (message != null)
+ } else {
+ if (message != null) {
Bugsnag.leaveBreadcrumb(message)
- if (t != null)
+ }
+ if (t != null) {
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 c10a95ce..0885109a 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/Prefs.kt
@@ -22,6 +22,8 @@ import ca.allanwang.kau.kpref.KPref
import ca.allanwang.kau.utils.colorToForeground
import ca.allanwang.kau.utils.isColorVisibleOn
import ca.allanwang.kau.utils.withAlpha
+import com.bugsnag.android.Bugsnag
+import com.pitchedapps.frost.BuildConfig
import com.pitchedapps.frost.enums.FACEBOOK_BLUE
import com.pitchedapps.frost.enums.FeedSort
import com.pitchedapps.frost.enums.MainActivityLayout
@@ -41,7 +43,9 @@ object Prefs : KPref() {
var prevId: Long by kpref("prev_id", -1L)
- var theme: Int by kpref("theme", 0, postSetter = { _: Int -> loader.invalidate() })
+ var theme: Int by kpref("theme", 0) { _: Int ->
+ loader.invalidate()
+ }
var customTextColor: Int by kpref("color_text", 0xffeceff1.toInt())
@@ -153,7 +157,17 @@ object Prefs : KPref() {
var verboseLogging: Boolean by kpref("verbose_logging", false)
- var analytics: Boolean by kpref("analytics", true)
+ var analytics: Boolean by kpref("analytics", false) {
+ if (!BuildConfig.DEBUG) {
+ if (it) {
+ Bugsnag.setAutoCaptureSessions(true)
+ Bugsnag.enableExceptionHandler()
+ } else {
+ Bugsnag.setAutoCaptureSessions(false)
+ Bugsnag.disableExceptionHandler()
+ }
+ }
+ }
var biometricsEnabled: Boolean by kpref("biometrics_enabled", false)
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 0574aeae..8544aac3 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt
@@ -137,7 +137,8 @@ private inline fun <reified T : WebOverlayActivityBase> Context.launchWebOverlay
fun Context.launchWebOverlay(url: String) = launchWebOverlayImpl<WebOverlayActivity>(url)
-fun Context.launchWebOverlayDesktop(url: String) = launchWebOverlayImpl<WebOverlayDesktopActivity>(url)
+fun Context.launchWebOverlayDesktop(url: String) =
+ launchWebOverlayImpl<WebOverlayDesktopActivity>(url)
private fun Context.fadeBundle() = ActivityOptions.makeCustomAnimation(
this,
@@ -154,9 +155,11 @@ fun Context.launchImageActivity(imageUrl: String, text: String? = null, cookie:
}
fun Activity.launchTabCustomizerActivity() {
- startActivityForResult<TabCustomizerActivity>(SettingsActivity.ACTIVITY_REQUEST_TABS, bundleBuilder = {
- with(fadeBundle())
- })
+ startActivityForResult<TabCustomizerActivity>(
+ SettingsActivity.ACTIVITY_REQUEST_TABS,
+ bundleBuilder = {
+ with(fadeBundle())
+ })
}
fun WebOverlayActivity.url(): String {
@@ -165,11 +168,12 @@ fun WebOverlayActivity.url(): String {
fun Activity.setFrostTheme(forceTransparent: Boolean = false) {
val isTransparent =
- (Color.alpha(Prefs.bgColor) != 255) || (Color.alpha(Prefs.headerColor) != 255) || forceTransparent
- if (Prefs.bgColor.isColorDark)
+ forceTransparent || (Color.alpha(Prefs.bgColor) != 255) || (Color.alpha(Prefs.headerColor) != 255)
+ if (Prefs.bgColor.isColorDark) {
setTheme(if (isTransparent) R.style.FrostTheme_Transparent else R.style.FrostTheme)
- else
+ } else {
setTheme(if (isTransparent) R.style.FrostTheme_Light_Transparent else R.style.FrostTheme_Light)
+ }
}
class ActivityThemeUtils {
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoView.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoView.kt
index b3912bab..f21476fb 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoView.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostVideoView.kt
@@ -33,8 +33,8 @@ import ca.allanwang.kau.utils.toast
import com.devbrackets.android.exomedia.ui.widget.VideoControls
import com.devbrackets.android.exomedia.ui.widget.VideoView
import com.pitchedapps.frost.R
+import com.pitchedapps.frost.facebook.formattedFbUrl
import com.pitchedapps.frost.utils.L
-import com.pitchedapps.frost.utils.Prefs
/**
* Created by Allan Wang on 2017-10-13.
@@ -154,8 +154,7 @@ class FrostVideoView @JvmOverloads constructor(
if (isExpanded) showControls()
}
setOnErrorListener {
- if (Prefs.analytics)
- L.e(it) { "Failed to load video $videoUri" }
+ L.e(it) { "Failed to load video ${videoUri?.toString()?.formattedFbUrl}" }
toast(R.string.video_load_failed, Toast.LENGTH_SHORT)
destroy()
true
@@ -168,7 +167,10 @@ class FrostVideoView @JvmOverloads constructor(
v.setOnTouchListener(VideoTouchListener(context))
setOnVideoSizedChangedListener { intrinsicWidth, intrinsicHeight, pixelWidthHeightRatio ->
// todo use provided ratio?
- val ratio = Math.min(width.toFloat() / intrinsicWidth, height.toFloat() / intrinsicHeight.toFloat())
+ val ratio = Math.min(
+ width.toFloat() / intrinsicWidth,
+ height.toFloat() / intrinsicHeight.toFloat()
+ )
/**
* Only remap if not expanded and if dimensions have changed
*/
@@ -237,7 +239,8 @@ class FrostVideoView @JvmOverloads constructor(
}
private fun onHorizontalSwipe(offset: Float) {
- val alpha = Math.max((1f - Math.abs(offset / SWIPE_TO_CLOSE_OFFSET_THRESHOLD)) * 0.5f + 0.5f, 0f)
+ val alpha =
+ Math.max((1f - Math.abs(offset / SWIPE_TO_CLOSE_OFFSET_THRESHOLD)) * 0.5f + 0.5f, 0f)
this.alpha = alpha
}
@@ -247,7 +250,8 @@ class FrostVideoView @JvmOverloads constructor(
* -------------------------------------------------------------------
*/
- private inner class FrameTouchListener(context: Context) : GestureDetector.SimpleOnGestureListener(),
+ private inner class FrameTouchListener(context: Context) :
+ GestureDetector.SimpleOnGestureListener(),
View.OnTouchListener {
private val gestureDetector: GestureDetector = GestureDetector(context, this)
@@ -274,7 +278,8 @@ class FrostVideoView @JvmOverloads constructor(
/**
* Monitors the view click events to show and hide the video controls if they have been specified.
*/
- private inner class VideoTouchListener(context: Context) : GestureDetector.SimpleOnGestureListener(),
+ private inner class VideoTouchListener(context: Context) :
+ GestureDetector.SimpleOnGestureListener(),
View.OnTouchListener {
private val gestureDetector: GestureDetector = GestureDetector(context, this)
@@ -314,7 +319,9 @@ class FrostVideoView @JvmOverloads constructor(
if (Math.abs(baseSwipeX - event.rawX) > SWIPE_TO_CLOSE_OFFSET_THRESHOLD)
destroy()
else
- animate().translationX(baseTranslateX).setDuration(FAST_ANIMATION_DURATION).withStartAction {
+ animate().translationX(baseTranslateX).setDuration(
+ FAST_ANIMATION_DURATION
+ ).withStartAction {
animate().alpha(1f)
}
}
diff --git a/app/src/main/play/en-US/whatsnew b/app/src/main/play/en-US/whatsnew
index 7d32c3ed..d2b73404 100644
--- a/app/src/main/play/en-US/whatsnew
+++ b/app/src/main/play/en-US/whatsnew
@@ -1,8 +1,5 @@
-v2.3.1
+v2.3.2
-* Hide all story panels if enabled
-* Prevent swipe to refresh if not at the very top
-* Add vertical swipe to dismiss when viewing images
-* Add horizontal scroll support for webviews
-* Fix theme for F-Droid builds
-* Added Greek translations \ No newline at end of file
+* Disable auto feed refresh by default and add setting to re-enable it
+* Update theme
+* Disable bugsnag completely when opting out of analytics \ No newline at end of file
diff --git a/app/src/main/res/layout/intro_analytics.xml b/app/src/main/res/layout/intro_analytics.xml
new file mode 100644
index 00000000..a62a0b0f
--- /dev/null
+++ b/app/src/main/res/layout/intro_analytics.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/intro_analytics_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <TextView
+ android:id="@id/intro_title"
+ style="@style/IntroTitle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/analytics"
+ app:layout_constraintBottom_toTopOf="@id/intro_image"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintVertical_chainStyle="spread" />
+
+ <ImageView
+ android:id="@id/intro_image"
+ android:layout_width="120dp"
+ android:layout_height="120dp"
+ android:scaleType="fitCenter"
+ app:layout_constraintBottom_toTopOf="@id/intro_switch"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/intro_title"
+ tools:layout_editor_absoluteX="112dp" />
+
+ <Switch
+ android:id="@+id/intro_switch"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:layout_constraintBottom_toTopOf="@id/intro_desc"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/intro_image" />
+
+ <TextView
+ android:id="@id/intro_desc"
+ style="@style/IntroSubTitle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/analytics_desc"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/intro_switch" />
+
+</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
diff --git a/app/src/main/res/layout/intro_end.xml b/app/src/main/res/layout/intro_end.xml
index 501cf1a9..fbaa2042 100644
--- a/app/src/main/res/layout/intro_end.xml
+++ b/app/src/main/res/layout/intro_end.xml
@@ -2,8 +2,8 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
android:id="@+id/intro_end_container"
+ android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 33f36174..90978724 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -86,11 +86,15 @@
<style name="IntroTitle" parent="TextAppearance.AppCompat.Title">
<item name="android:textSize">20sp</item>
<item name="android:textAlignment">center</item>
+ <item name="android:paddingStart">@dimen/kau_activity_horizontal_margin</item>
+ <item name="android:paddingEnd">@dimen/kau_activity_horizontal_margin</item>
</style>
<style name="IntroSubTitle" parent="TextAppearance.AppCompat.Subhead">
<item name="android:textSize">18sp</item>
<item name="android:textAlignment">center</item>
+ <item name="android:paddingStart">@dimen/kau_activity_horizontal_margin</item>
+ <item name="android:paddingEnd">@dimen/kau_activity_horizontal_margin</item>
</style>
<style name="IntroButton" parent="TextAppearance.AppCompat.Button">
diff --git a/app/src/main/res/xml/frost_changelog.xml b/app/src/main/res/xml/frost_changelog.xml
index 01d0a6fb..09bb9d2e 100644
--- a/app/src/main/res/xml/frost_changelog.xml
+++ b/app/src/main/res/xml/frost_changelog.xml
@@ -10,7 +10,7 @@
<version title="v2.3.2" />
<item text="Disable auto feed refresh by default and add setting to re-enable it" />
<item text="Update theme" />
- <item text="" />
+ <item text="Disable bugsnag completely when opting out of analytics" />
<item text="" />
<item text="" />
<item text="" />
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 65911524..949eb8d4 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -1,5 +1,10 @@
# Changelog
+## v2.3.2
+* Disable auto feed refresh by default and add setting to re-enable it
+* Update theme
+* Disable bugsnag completely when opting out of analytics
+
## v2.3.1
* Hide all story panels if enabled
* Prevent swipe to refresh if not at the very top