1
0
mirror of https://github.com/AllanWang/Frost-for-Facebook.git synced 2024-09-18 21:12:24 +02:00

Update/bindview (#1258)

* Update bindview for FrostVideoViewer

* Remove more bindview usages

* Fix compilation problems

* Remove custom drawer header
This commit is contained in:
Allan Wang 2018-12-24 00:21:21 -05:00 committed by GitHub
parent 9a40780c3b
commit c45b30e28f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 69 additions and 219 deletions

View File

@ -185,7 +185,6 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract,
translucentStatusBar = false
sliderBackgroundColor = navBg
drawerHeader = accountHeader {
customViewRes = R.layout.material_drawer_header
textColor = Prefs.iconColor.toLong()
backgroundDrawable = ColorDrawable(navHeader)
selectionSecondLineShown = false

View File

@ -5,25 +5,22 @@ import android.content.Context
import android.content.Intent
import android.content.res.ColorStateList
import android.os.Bundle
import com.google.android.material.floatingactionbutton.FloatingActionButton
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import androidx.appcompat.widget.Toolbar
import ca.allanwang.kau.internal.KauBaseActivity
import ca.allanwang.kau.utils.bindView
import ca.allanwang.kau.utils.setIcon
import ca.allanwang.kau.utils.visible
import com.mikepenz.google_material_typeface_library.GoogleMaterial
import com.pitchedapps.frost.R
import com.pitchedapps.frost.facebook.FbItem
import com.pitchedapps.frost.injectors.JsActions
import com.pitchedapps.frost.R
import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.utils.Prefs
import com.pitchedapps.frost.utils.createFreshDir
import com.pitchedapps.frost.utils.setFrostColors
import com.pitchedapps.frost.web.DebugWebView
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.activity_debug.*
import kotlinx.android.synthetic.main.view_main_fab.*
import java.io.File
/**
@ -31,11 +28,6 @@ import java.io.File
*/
class DebugActivity : KauBaseActivity() {
private val toolbar: Toolbar by bindView(R.id.toolbar)
private val web: DebugWebView by bindView(R.id.debug_webview)
private val swipeRefresh: SwipeRefreshLayout by bindView(R.id.swipe_refresh)
private val fab: FloatingActionButton by bindView(R.id.fab)
companion object {
const val RESULT_URL = "extra_result_url"
const val RESULT_SCREENSHOT = "extra_result_screenshot"
@ -56,10 +48,10 @@ class DebugActivity : KauBaseActivity() {
setFrostColors {
toolbar(toolbar)
}
web.loadUrl(FbItem.FEED.url)
web.onPageFinished = { swipeRefresh.isRefreshing = false }
debug_webview.loadUrl(FbItem.FEED.url)
debug_webview.onPageFinished = { swipe_refresh.isRefreshing = false }
swipeRefresh.setOnRefreshListener(web::reload)
swipe_refresh.setOnRefreshListener(debug_webview::reload)
fab.visible().setIcon(GoogleMaterial.Icon.gmd_bug_report, Prefs.iconColor)
fab.backgroundTintList = ColorStateList.valueOf(Prefs.accentColor)
@ -69,10 +61,10 @@ class DebugActivity : KauBaseActivity() {
val parent = baseDir(this)
parent.createFreshDir()
val rxScreenshot = Single.fromCallable {
web.getScreenshot(File(parent, "screenshot.png"))
debug_webview.getScreenshot(File(parent, "screenshot.png"))
}.subscribeOn(Schedulers.io())
val rxBody = Single.create<String> { emitter ->
web.evaluateJavascript(JsActions.RETURN_BODY.function) {
debug_webview.evaluateJavascript(JsActions.RETURN_BODY.function) {
emitter.onSuccess(it)
}
}.subscribeOn(AndroidSchedulers.mainThread())
@ -89,7 +81,7 @@ class DebugActivity : KauBaseActivity() {
return@subscribe
}
val intent = Intent()
intent.putExtra(RESULT_URL, web.url)
intent.putExtra(RESULT_URL, debug_webview.url)
intent.putExtra(RESULT_SCREENSHOT, screenshot)
if (body != null)
intent.putExtra(RESULT_BODY, body)
@ -107,17 +99,17 @@ class DebugActivity : KauBaseActivity() {
override fun onResume() {
super.onResume()
web.resumeTimers()
debug_webview.resumeTimers()
}
override fun onPause() {
web.pauseTimers()
debug_webview.pauseTimers()
super.onPause()
}
override fun onBackPressed() {
if (web.canGoBack())
web.goBack()
if (debug_webview.canGoBack())
debug_webview.goBack()
else
super.onBackPressed()
}

View File

@ -3,23 +3,23 @@ package com.pitchedapps.frost.activities
import android.app.Activity
import android.content.res.ColorStateList
import android.os.Bundle
import com.google.android.material.floatingactionbutton.FloatingActionButton
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.ItemTouchHelper
import android.view.View
import android.view.animation.AnimationUtils
import android.widget.TextView
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView
import ca.allanwang.kau.kotlin.lazyContext
import ca.allanwang.kau.utils.bindView
import ca.allanwang.kau.utils.scaleXY
import ca.allanwang.kau.utils.setIcon
import com.pitchedapps.frost.R
import ca.allanwang.kau.utils.withAlpha
import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter
import com.mikepenz.fastadapter_extensions.drag.ItemTouchCallback
import com.mikepenz.fastadapter_extensions.drag.SimpleDragCallback
import com.mikepenz.google_material_typeface_library.GoogleMaterial
import com.pitchedapps.frost.R
import com.pitchedapps.frost.dbflow.TAB_COUNT
import com.pitchedapps.frost.dbflow.loadFbTabs
import com.pitchedapps.frost.dbflow.save
@ -27,6 +27,7 @@ import com.pitchedapps.frost.facebook.FbItem
import com.pitchedapps.frost.iitems.TabIItem
import com.pitchedapps.frost.utils.Prefs
import com.pitchedapps.frost.utils.setFrostColors
import kotlinx.android.synthetic.main.activity_tab_customizer.*
import java.util.*
/**
@ -34,13 +35,7 @@ import java.util.*
*/
class TabCustomizerActivity : BaseActivity() {
val toolbar: View by bindView(R.id.pseudo_toolbar)
val recycler: RecyclerView by bindView(R.id.tab_recycler)
val instructions: TextView by bindView(R.id.instructions)
val divider: View by bindView(R.id.divider)
val adapter = FastItemAdapter<TabIItem>()
val fabCancel: FloatingActionButton by bindView(R.id.fab_cancel)
val fabSave: FloatingActionButton by bindView(R.id.fab_save)
private val adapter = FastItemAdapter<TabIItem>()
private val wobble = lazyContext { AnimationUtils.loadAnimation(it, R.anim.rotate_delta) }
@ -48,11 +43,11 @@ class TabCustomizerActivity : BaseActivity() {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_tab_customizer)
toolbar.setBackgroundColor(Prefs.headerColor)
pseudo_toolbar.setBackgroundColor(Prefs.headerColor)
recycler.layoutManager = GridLayoutManager(this, TAB_COUNT, RecyclerView.VERTICAL, false)
recycler.adapter = adapter
recycler.setHasFixedSize(true)
tab_recycler.layoutManager = GridLayoutManager(this, TAB_COUNT, RecyclerView.VERTICAL, false)
tab_recycler.adapter = adapter
tab_recycler.setHasFixedSize(true)
divider.setBackgroundColor(Prefs.textColor.withAlpha(30))
instructions.setTextColor(Prefs.textColor)
@ -63,22 +58,22 @@ class TabCustomizerActivity : BaseActivity() {
tabs.addAll(remaining)
adapter.add(tabs.map(::TabIItem))
bindSwapper(adapter, recycler)
bindSwapper(adapter, tab_recycler)
adapter.withOnClickListener { view, _, _, _ -> view!!.wobble(); true }
setResult(Activity.RESULT_CANCELED)
fabSave.setIcon(GoogleMaterial.Icon.gmd_check, Prefs.iconColor)
fabSave.backgroundTintList = ColorStateList.valueOf(Prefs.accentColor)
fabSave.setOnClickListener {
fab_save.setIcon(GoogleMaterial.Icon.gmd_check, Prefs.iconColor)
fab_save.backgroundTintList = ColorStateList.valueOf(Prefs.accentColor)
fab_save.setOnClickListener {
adapter.adapterItems.subList(0, TAB_COUNT).map(TabIItem::item).save()
setResult(Activity.RESULT_OK)
finish()
}
fabCancel.setIcon(GoogleMaterial.Icon.gmd_close, Prefs.iconColor)
fabCancel.backgroundTintList = ColorStateList.valueOf(Prefs.accentColor)
fabCancel.setOnClickListener { finish() }
fab_cancel.setIcon(GoogleMaterial.Icon.gmd_close, Prefs.iconColor)
fab_cancel.backgroundTintList = ColorStateList.valueOf(Prefs.accentColor)
fab_cancel.setOnClickListener { finish() }
setFrostColors {
themeWindow = true
}

View File

@ -2,34 +2,29 @@ package com.pitchedapps.frost.intro
import android.os.Bundle
import android.view.View
import ca.allanwang.kau.utils.bindViewResettable
import ca.allanwang.kau.utils.scaleXY
import com.pitchedapps.frost.R
import com.pitchedapps.frost.activities.IntroActivity
import com.pitchedapps.frost.enums.Theme
import com.pitchedapps.frost.utils.Prefs
import kotlinx.android.synthetic.main.intro_theme.*
/**
* Created by Allan Wang on 2017-07-28.
*/
class IntroFragmentTheme : BaseIntroFragment(R.layout.intro_theme) {
val light: View by bindViewResettable(R.id.intro_theme_light)
val dark: View by bindViewResettable(R.id.intro_theme_dark)
val amoled: View by bindViewResettable(R.id.intro_theme_amoled)
val glass: View by bindViewResettable(R.id.intro_theme_glass)
val themeList
get() = listOf(light, dark, amoled, glass)
get() = listOf(intro_theme_light, intro_theme_dark, intro_theme_amoled, intro_theme_glass)
override fun viewArray(): Array<Array<out View>> = arrayOf(arrayOf(title), arrayOf(light, dark), arrayOf(amoled, glass))
override fun viewArray(): Array<Array<out View>> = arrayOf(arrayOf(title), arrayOf(intro_theme_light, intro_theme_dark), arrayOf(intro_theme_amoled, intro_theme_glass))
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
light.setThemeClick(Theme.LIGHT)
dark.setThemeClick(Theme.DARK)
amoled.setThemeClick(Theme.AMOLED)
glass.setThemeClick(Theme.GLASS)
intro_theme_light.setThemeClick(Theme.LIGHT)
intro_theme_dark.setThemeClick(Theme.DARK)
intro_theme_amoled.setThemeClick(Theme.AMOLED)
intro_theme_glass.setThemeClick(Theme.GLASS)
val currentTheme = Prefs.theme - 1
if (currentTheme in 0..3)
themeList.forEachIndexed { index, v -> v.scaleXY = if (index == currentTheme) 1.6f else 0.8f }

View File

@ -4,12 +4,11 @@ import android.content.Context
import android.graphics.drawable.GradientDrawable
import androidx.constraintlayout.widget.ConstraintLayout
import android.util.AttributeSet
import android.widget.ImageView
import android.widget.TextView
import ca.allanwang.kau.utils.*
import com.mikepenz.iconics.typeface.IIcon
import com.pitchedapps.frost.R
import com.pitchedapps.frost.utils.Prefs
import kotlinx.android.synthetic.main.view_badged_icon.view.*
/**
@ -19,36 +18,33 @@ class BadgedIcon @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) {
val badgeTextView: TextView by bindView(R.id.badge_text)
val badgeImage: ImageView by bindView(R.id.badge_image)
init {
inflate(context, R.layout.view_badged_icon, this)
val badgeColor = Prefs.mainActivityLayout.backgroundColor().withAlpha(255).colorToForeground(0.2f)
val badgeBackground = GradientDrawable(GradientDrawable.Orientation.BOTTOM_TOP, intArrayOf(badgeColor, badgeColor))
badgeBackground.cornerRadius = 13.dpToPx.toFloat()
badgeTextView.background = badgeBackground
badgeTextView.setTextColor(Prefs.mainActivityLayout.iconColor())
badge_text.background = badgeBackground
badge_text.setTextColor(Prefs.mainActivityLayout.iconColor())
}
var iicon: IIcon? = null
set(value) {
field = value
badgeImage.setImageDrawable(value?.toDrawable(context, sizeDp = 20, color = Prefs.mainActivityLayout.iconColor()))
badge_image.setImageDrawable(value?.toDrawable(context, sizeDp = 20, color = Prefs.mainActivityLayout.iconColor()))
}
fun setAllAlpha(alpha: Float) {
//badgeTextView.setTextColor(Prefs.textColor.withAlpha(alpha.toInt()))
badgeImage.drawable.alpha = alpha.toInt()
badge_image.drawable.alpha = alpha.toInt()
}
var badgeText: String?
get() = badgeTextView.text.toString()
get() = badge_text.text.toString()
set(value) {
if (badgeTextView.text == value) return
badgeTextView.text = value
if (value != null && value != "0") badgeTextView.visible()
else badgeTextView.gone()
if (badge_text.text == value) return
badge_text.text = value
if (value != null && value != "0") badge_text.visible()
else badge_text.gone()
}
}

View File

@ -4,21 +4,18 @@ import android.content.Context
import android.graphics.Color
import android.graphics.PointF
import android.net.Uri
import androidx.appcompat.widget.Toolbar
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver
import android.widget.FrameLayout
import android.widget.ImageView
import ca.allanwang.kau.utils.*
import com.devbrackets.android.exomedia.listener.VideoControlsVisibilityListener
import com.mikepenz.google_material_typeface_library.GoogleMaterial
import com.pitchedapps.frost.R
import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.R
import com.pitchedapps.frost.utils.Prefs
import com.pitchedapps.frost.utils.frostDownload
import kotlinx.android.synthetic.main.view_video.view.*
/**
* Created by Allan Wang on 2017-10-13.
@ -27,12 +24,6 @@ class FrostVideoViewer @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr), FrostVideoViewerContract {
val container: ViewGroup by bindView(R.id.video_container)
val toolbar: Toolbar by bindView(R.id.video_toolbar)
val background: View by bindView(R.id.video_background)
val video: FrostVideoView by bindView(R.id.video)
val restarter: ImageView by bindView(R.id.video_restart)
companion object {
/**
* Matches VideoControls.CONTROL_VISIBILITY_ANIMATION_LENGTH
@ -59,29 +50,29 @@ class FrostVideoViewer @JvmOverloads constructor(
init {
inflate(R.layout.view_video, true)
alpha = 0f
background.setBackgroundColor(
video_background.setBackgroundColor(
if (!Prefs.blackMediaBg && Prefs.bgColor.isColorDark)
Prefs.bgColor.withMinAlpha(200)
else
Color.BLACK)
video.setViewerContract(this)
video.pause()
toolbar.inflateMenu(R.menu.menu_video)
context.setMenuIcons(toolbar.menu, Prefs.iconColor,
video_toolbar.inflateMenu(R.menu.menu_video)
context.setMenuIcons(video_toolbar.menu, Prefs.iconColor,
R.id.action_pip to GoogleMaterial.Icon.gmd_picture_in_picture_alt,
R.id.action_download to GoogleMaterial.Icon.gmd_file_download
)
toolbar.setOnMenuItemClickListener {
video_toolbar.setOnMenuItemClickListener {
when (it.itemId) {
R.id.action_pip -> video.isExpanded = false
R.id.action_download -> context.frostDownload(video.videoUri)
}
true
}
restarter.gone().setIcon(GoogleMaterial.Icon.gmd_replay, 64)
restarter.setOnClickListener {
video_restart.gone().setIcon(GoogleMaterial.Icon.gmd_replay, 64)
video_restart.setOnClickListener {
video.restart()
restarter.fadeOut { restarter.gone() }
video_restart.fadeOut { video_restart.gone() }
}
}
@ -115,13 +106,13 @@ class FrostVideoViewer @JvmOverloads constructor(
*/
override fun onExpand(progress: Float) {
toolbar.goneIf(progress == 0f).alpha = progress
background.alpha = progress
video_toolbar.goneIf(progress == 0f).alpha = progress
video_background.alpha = progress
}
override fun onSingleTapConfirmed(event: MotionEvent): Boolean {
if (restarter.isVisible) {
restarter.performClick()
if (video_restart.isVisible) {
video_restart.performClick()
return true
}
return false
@ -129,7 +120,7 @@ class FrostVideoViewer @JvmOverloads constructor(
override fun onVideoComplete() {
video.jumpToStart()
restarter.fadeIn()
video_restart.fadeIn()
}
fun updateLocation() {
@ -143,12 +134,12 @@ class FrostVideoViewer @JvmOverloads constructor(
override fun onControlsShown() {
if (video.isExpanded)
toolbar.fadeIn(duration = CONTROL_ANIMATION_DURATION, onStart = { toolbar.visible() })
video_toolbar.fadeIn(duration = CONTROL_ANIMATION_DURATION, onStart = { video_toolbar.visible() })
}
override fun onControlsHidden() {
if (!toolbar.isGone)
toolbar.fadeOut(duration = CONTROL_ANIMATION_DURATION) { toolbar.gone() }
if (!video_toolbar.isGone)
video_toolbar.fadeOut(duration = CONTROL_ANIMATION_DURATION) { video_toolbar.gone() }
}
}

View File

@ -1,119 +0,0 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="@dimen/material_drawer_account_header_height"
android:clickable="true"
tools:ignore="all">
<!--
Resolves padding
Check with <a href="https://github.com/mikepenz/MaterialDrawer/issues/1907">Issue</a>
-->
<ImageView
android:id="@+id/material_drawer_account_header_background"
android:layout_width="match_parent"
android:layout_height="@dimen/material_drawer_account_header_height"
android:scaleType="centerCrop" />
<RelativeLayout
android:id="@+id/material_drawer_account_header"
android:layout_width="match_parent"
android:layout_height="@dimen/material_drawer_account_header_height">
<com.mikepenz.materialdrawer.view.BezelImageView
android:id="@+id/material_drawer_account_header_current"
android:layout_width="@dimen/material_drawer_account_header_selected"
android:layout_height="@dimen/material_drawer_account_header_selected"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginBottom="@dimen/material_drawer_account_header_horizontal_bottom"
android:layout_marginLeft="@dimen/material_drawer_vertical_padding"
android:layout_marginTop="@dimen/material_drawer_account_header_horizontal_top"
android:clickable="true"
android:elevation="2dp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignTop="@+id/material_drawer_account_header_current"
android:gravity="right">
<com.mikepenz.materialdrawer.view.BezelImageView
android:id="@+id/material_drawer_account_header_small_first"
android:layout_width="@dimen/material_drawer_account_header_secondary"
android:layout_height="@dimen/material_drawer_account_header_secondary"
android:layout_marginRight="@dimen/material_drawer_vertical_padding"
android:clickable="true"
android:elevation="2dp"
android:visibility="gone" />
<com.mikepenz.materialdrawer.view.BezelImageView
android:id="@+id/material_drawer_account_header_small_second"
android:layout_width="@dimen/material_drawer_account_header_secondary"
android:layout_height="@dimen/material_drawer_account_header_secondary"
android:layout_marginRight="@dimen/material_drawer_vertical_padding"
android:clickable="true"
android:elevation="2dp"
android:visibility="gone" />
<com.mikepenz.materialdrawer.view.BezelImageView
android:id="@+id/material_drawer_account_header_small_third"
android:layout_width="@dimen/material_drawer_account_header_secondary"
android:layout_height="@dimen/material_drawer_account_header_secondary"
android:layout_marginRight="@dimen/material_drawer_vertical_padding"
android:clickable="true"
android:elevation="2dp"
android:visibility="gone" />
</LinearLayout>
<LinearLayout
android:id="@+id/material_drawer_account_header_text_section"
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="@dimen/material_drawer_account_header_dropdown_margin_bottom"
android:layout_toLeftOf="@+id/material_drawer_account_header_text_switcher"
android:gravity="center_vertical|bottom"
android:orientation="vertical"
android:paddingEnd="56dp"
android:paddingLeft="0dp"
android:paddingRight="56dp"
android:paddingStart="0dp">
<TextView
android:id="@+id/material_drawer_account_header_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/material_drawer_vertical_padding"
android:fontFamily="sans-serif-medium"
android:lines="1"
android:maxLines="1"
android:textSize="@dimen/material_drawer_account_header_title" />
<TextView
android:id="@+id/material_drawer_account_header_email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/material_drawer_vertical_padding"
android:fontFamily="sans-serif"
android:lines="1"
android:maxLines="1"
android:textSize="@dimen/material_drawer_account_header_subtext" />
</LinearLayout>
<ImageView
android:id="@+id/material_drawer_account_header_text_switcher"
android:layout_width="@dimen/material_drawer_account_header_dropdown"
android:layout_height="@dimen/material_drawer_account_header_dropdown"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="@dimen/material_drawer_account_header_dropdown_margin_bottom"
android:layout_marginRight="@dimen/material_drawer_vertical_padding" />
</RelativeLayout>
</FrameLayout>

View File

@ -10,7 +10,7 @@
android:layout_width="@dimen/account_image_size"
android:layout_height="@dimen/account_image_size" />
<androidx.legacy.widget.Space
<Space
android:layout_width="1dp"
android:layout_height="20dp" />

View File

@ -8,6 +8,7 @@ buildscript {
dependencies {
classpath "ca.allanwang:kau:${KAU}"
classpath 'com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta02'
classpath "com.android.tools.build:gradle:${ANDROID_GRADLE}"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${KOTLIN}"
classpath "com.bugsnag:bugsnag-android-gradle-plugin:${BUGSNAG_PLUGIN}"

View File

@ -14,11 +14,11 @@ org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryErro
APP_ID=Frost
APP_GROUP=com.pitchedapps
KAU=0d24880
KAU=b4a2ded
KOTLIN=1.3.11
# https://mvnrepository.com/artifact/com.android.tools.build/gradle?repo=google
ANDROID_GRADLE=3.3.0-rc02
ANDROID_GRADLE=3.2.1
# https://github.com/bugsnag/bugsnag-android/releases
BUGSNAG=4.9.3