mirror of
https://github.com/AllanWang/Frost-for-Facebook.git
synced 2024-11-10 04:52:38 +01:00
Merge pull request #1496 from AllanWang/bugsnag-opt-out
Bugsnag opt out
This commit is contained in:
commit
2eacc8cb77
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
* Disable auto feed refresh by default and add setting to re-enable it
|
||||
* Update theme
|
||||
* Disable bugsnag completely when opting out of analytics
|
52
app/src/main/res/layout/intro_analytics.xml
Normal file
52
app/src/main/res/layout/intro_analytics.xml
Normal file
@ -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>
|
@ -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
|
||||
|
@ -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">
|
||||
|
@ -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="" />
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user