zcash-android-wallet-zcon1/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/fragment/HomeFragment.kt

604 lines
25 KiB
Kotlin
Raw Normal View History

2018-11-12 10:38:37 -08:00
package cash.z.android.wallet.ui.fragment
import android.os.Bundle
2018-12-07 09:14:54 -08:00
import android.text.SpannableString
import android.text.Spanned
import android.util.Log
2018-11-21 02:11:48 -08:00
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.AccelerateInterpolator
import android.view.animation.DecelerateInterpolator
import androidx.annotation.ColorRes
import androidx.annotation.DrawableRes
import androidx.annotation.IdRes
import androidx.annotation.StringRes
2019-02-14 17:26:56 -08:00
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
2019-02-14 17:26:56 -08:00
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import androidx.transition.Transition
2019-02-01 08:10:43 -08:00
import androidx.transition.TransitionInflater
2018-11-12 10:38:37 -08:00
import cash.z.android.wallet.R
2019-02-14 17:26:56 -08:00
import cash.z.android.wallet.databinding.FragmentHomeBinding
import cash.z.android.wallet.extention.*
import cash.z.android.wallet.sample.SampleProperties
import cash.z.android.wallet.ui.adapter.TransactionAdapter
import cash.z.android.wallet.ui.presenter.HomePresenter
import cash.z.android.wallet.ui.util.AlternatingRowColorDecoration
import cash.z.android.wallet.ui.util.AnimatorCompleteListener
2019-02-14 17:26:56 -08:00
import cash.z.android.wallet.ui.util.LottieLooper
2018-12-07 09:14:54 -08:00
import cash.z.android.wallet.ui.util.TopAlignedSpan
import cash.z.wallet.sdk.dao.WalletTransaction
2019-02-04 10:42:28 -08:00
import cash.z.wallet.sdk.data.ActiveSendTransaction
2019-02-03 17:27:54 -08:00
import cash.z.wallet.sdk.data.ActiveTransaction
import cash.z.wallet.sdk.data.TransactionState
import cash.z.wallet.sdk.ext.*
import com.google.android.material.snackbar.Snackbar
import com.leinardi.android.speeddial.SpeedDialActionItem
import dagger.Module
import dagger.android.ContributesAndroidInjector
import kotlinx.coroutines.launch
import kotlin.random.Random
2019-02-03 23:08:26 -08:00
import kotlin.random.nextLong
2019-01-31 14:47:37 -08:00
2018-11-12 10:38:37 -08:00
/**
* Fragment representing the home screen of the app. This is the screen most often seen by the user when launching the
* application.
2018-11-12 10:38:37 -08:00
*/
2019-02-14 17:26:56 -08:00
class HomeFragment : BaseFragment(), SwipeRefreshLayout.OnRefreshListener, HomePresenter.HomeView {
2018-11-21 02:11:48 -08:00
2019-02-14 17:26:56 -08:00
private lateinit var homePresenter: HomePresenter
private lateinit var binding: FragmentHomeBinding
private lateinit var zcashLogoAnimation: LottieLooper
private var snackbar: Snackbar? = null
2019-02-14 17:26:56 -08:00
private var viewsInitialized = false
2018-11-12 10:38:37 -08:00
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
viewsInitialized = false
2019-02-14 17:26:56 -08:00
// setupSharedElementTransitions()
return DataBindingUtil.inflate<FragmentHomeBinding>(
inflater, R.layout.fragment_home, container, false
).let {
binding = it
it.root
}
}
private fun setupSharedElementTransitions() {
2019-02-14 17:26:56 -08:00
TransitionInflater.from(mainActivity).inflateTransition(R.transition.transition_zec_sent).apply {
duration = 3000L
addListener(HomeTransitionListener())
this@HomeFragment.sharedElementEnterTransition = this
this@HomeFragment.sharedElementReturnTransition = this
}
2018-11-12 10:38:37 -08:00
}
2019-02-14 17:26:56 -08:00
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
2019-02-14 17:26:56 -08:00
initTemp()
init()
}
2019-02-14 17:26:56 -08:00
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
mainActivity.setToolbarShown(false)
mainActivity.setDrawerLocked(false)
2019-02-14 17:26:56 -08:00
initFab()
2019-02-03 23:08:26 -08:00
2019-02-14 17:26:56 -08:00
homePresenter = HomePresenter(this, mainActivity.synchronizer)
2019-02-03 23:08:26 -08:00
2019-02-14 17:26:56 -08:00
binding.includeContent.recyclerTransactions.apply {
layoutManager = LinearLayoutManager(activity, RecyclerView.VERTICAL, false)
adapter = TransactionAdapter()
addItemDecoration(AlternatingRowColorDecoration())
2019-02-03 23:08:26 -08:00
}
binding.includeContent.textTransactionHeaderSeeAll.setOnClickListener {
mainActivity.navController.navigate(R.id.nav_history_fragment)
}
}
override fun onResume() {
super.onResume()
launch {
homePresenter.start()
}
}
override fun onPause() {
super.onPause()
homePresenter.stop()
2019-02-14 17:26:56 -08:00
binding.lottieZcashBadge.cancelAnimation()
}
2019-02-14 17:26:56 -08:00
//
// View API
//
fun setContentViewShown(isShown: Boolean) {
with(binding.includeContent) {
groupEmptyViewItems.visibility = if (isShown) View.GONE else View.VISIBLE
groupContentViewItems.visibility = if (isShown) View.VISIBLE else View.GONE
2019-02-03 23:08:26 -08:00
}
2019-02-14 17:26:56 -08:00
toggleViews(!isShown)
}
2019-02-03 23:08:26 -08:00
2019-02-14 17:26:56 -08:00
override fun onRefresh() {
setRefreshAnimationPlaying(true).also { Log.e("TWIG-a", "refresh true from onRefresh") }
with(binding.includeContent.refreshLayout) {
isRefreshing = false
val fauxRefresh = Random.nextLong(750L..3000L)
postDelayed({
setRefreshAnimationPlaying(false).also { Log.e("TWIG-a", "refresh false from onRefresh") }
}, fauxRefresh)
}
}
2019-02-14 17:26:56 -08:00
fun setRefreshAnimationPlaying(isPlaying: Boolean) {
Log.e("TWIG-a", "set refresh to: $isPlaying for $zcashLogoAnimation")
if (isPlaying) {
zcashLogoAnimation.start()
} else {
zcashLogoAnimation.stop()
view?.postDelayed({
zcashLogoAnimation.stop()
}, 500L)
}
}
2019-02-14 17:26:56 -08:00
//TODO: pull some of this logic into the presenter, particularly the part that deals with ZEC <-> USD price conversion
override fun updateBalance(old: Long, new: Long) {
val zecValue = new.convertZatoshiToZec()
setZecValue(zecValue.toZecString(3))
setUsdValue(zecValue.convertZecToUsd(SampleProperties.USD_PER_ZEC).toUsdString())
2019-02-14 17:26:56 -08:00
onContentRefreshComplete(new)
}
override fun setTransactions(transactions: List<WalletTransaction>) {
val recent = if(transactions.size > 12) transactions.subList(0, 12) else transactions
2019-02-14 17:26:56 -08:00
with (binding.includeContent.recyclerTransactions) {
(adapter as TransactionAdapter).submitList(recent)
2019-02-14 17:26:56 -08:00
postDelayed({
smoothScrollToPosition(0)
}, 100L)
}
if (recent.size != transactions.size) {
binding.includeContent.textTransactionHeaderSeeAll.visibility = View.VISIBLE
2019-02-14 17:26:56 -08:00
}
}
2019-02-14 17:26:56 -08:00
private fun onInitialLoadComplete() {
val isEmpty = (binding.includeContent.recyclerTransactions?.adapter?.itemCount ?: 0).let { it == 0 }
Log.e("TWIG-t", "onInitialLoadComplete and isEmpty == $isEmpty")
setContentViewShown(!isEmpty)
if (isEmpty) {
binding.includeContent.textEmptyWalletMessage.setText(R.string.home_empty_wallet)
}
2019-02-14 17:26:56 -08:00
setRefreshAnimationPlaying(false).also { Log.e("TWIG-a", "refresh false from onInitialLoadComplete") }
}
2019-02-14 17:26:56 -08:00
2019-02-03 17:27:54 -08:00
override fun setActiveTransactions(activeTransactionMap: Map<ActiveTransaction, TransactionState>) {
if (activeTransactionMap.isEmpty()) {
setActiveTransactionsShown(false)
return
}
val transactions = activeTransactionMap.entries.toTypedArray()
// primary is the last one that was inserted
val primaryEntry = transactions[transactions.size - 1]
updatePrimaryTransaction(primaryEntry.key, primaryEntry.value)
// TODO: update remaining transactions
}
override fun onCancelledTooLate() {
2019-02-14 17:26:56 -08:00
snackbar = snackbar.showOk(view!!, "Oops! It was too late to cancel!")
}
2019-02-03 17:27:54 -08:00
private fun updatePrimaryTransaction(transaction: ActiveTransaction, transactionState: TransactionState) {
Log.e("TWIG", "setting transaction state to ${transactionState::class.simpleName}")
var title = binding.includeContent.textActiveTransactionTitle.text?.toString() ?: ""
var subtitle = binding.includeContent.textActiveTransactionSubtitle.text?.toString() ?: ""
var isShown = binding.includeContent.textActiveTransactionHeader.visibility == View.VISIBLE
2019-02-03 17:27:54 -08:00
when (transactionState) {
TransactionState.Creating -> {
2019-02-14 17:26:56 -08:00
binding.includeContent.headerActiveTransaction.visibility = View.VISIBLE
title = "Preparing ${transaction.value.convertZatoshiToZecString(3)} ZEC"
subtitle = "to ${(transaction as ActiveSendTransaction).toAddress.truncate()}"
setTransactionActive(transaction, true)
isShown = true
2019-02-03 17:27:54 -08:00
}
TransactionState.SendingToNetwork -> {
title = "Sending Transaction"
subtitle = "to ${(transaction as ActiveSendTransaction).toAddress.truncate()}"
binding.includeContent.textActiveTransactionValue.text = "${transaction.value.convertZatoshiToZecString(3)}"
2019-02-14 17:26:56 -08:00
binding.includeContent.textActiveTransactionValue.visibility = View.VISIBLE
binding.includeContent.buttonActiveTransactionCancel.visibility = View.GONE
setTransactionActive(transaction, true)
isShown = true
2019-02-03 17:27:54 -08:00
}
is TransactionState.Failure -> {
2019-02-14 17:26:56 -08:00
binding.includeContent.lottieActiveTransaction.setAnimation(R.raw.lottie_send_failure)
binding.includeContent.lottieActiveTransaction.playAnimation()
2019-02-03 17:27:54 -08:00
title = "Failed"
subtitle = when(transactionState.failedStep) {
TransactionState.Creating -> "Failed to create transaction"
TransactionState.SendingToNetwork -> "Failed to submit transaction to the network"
else -> "Unrecoginzed error"
}
2019-02-14 17:26:56 -08:00
binding.includeContent.buttonActiveTransactionCancel.visibility = View.GONE
binding.includeContent.textActiveTransactionValue.visibility = View.GONE
setTransactionActive(transaction, false)
2019-02-14 17:26:56 -08:00
setActiveTransactionsShown(false, 10000L)
2019-02-03 17:27:54 -08:00
}
is TransactionState.AwaitingConfirmations -> {
2019-02-03 23:08:26 -08:00
if (transactionState.confirmationCount < 1) {
2019-02-14 17:26:56 -08:00
binding.includeContent.lottieActiveTransaction.setAnimation(R.raw.lottie_send_success)
binding.includeContent.lottieActiveTransaction.playAnimation()
2019-02-03 23:08:26 -08:00
title = "ZEC Sent"
2019-02-14 17:26:56 -08:00
subtitle = "Today at 2:11pm"
binding.includeContent.textActiveTransactionValue.text = transaction.value.convertZatoshiToZecString(3)
2019-02-14 17:26:56 -08:00
binding.includeContent.textActiveTransactionValue.visibility = View.VISIBLE
binding.includeContent.buttonActiveTransactionCancel.visibility = View.GONE
} else if (transactionState.confirmationCount > 1) {
isShown = false
2019-02-03 23:08:26 -08:00
} else {
2019-02-14 17:26:56 -08:00
title = "Confirmation Received"
subtitle = "Today at 2:12pm"
// take it out of the list in a bit and skip counting confirmation animation for now (i.e. one is enough)
setActiveTransactionsShown(false, 5000L)
2019-02-03 23:08:26 -08:00
}
2019-02-03 17:27:54 -08:00
}
is TransactionState.Cancelled -> {
2019-02-14 17:26:56 -08:00
title = binding.includeContent.textActiveTransactionTitle.text.toString()
subtitle = binding.includeContent.textActiveTransactionSubtitle.text.toString()
setTransactionActive(transaction, false)
setActiveTransactionsShown(false, 10000L)
}
2019-02-03 17:27:54 -08:00
}
2019-02-14 17:26:56 -08:00
binding.includeContent.textActiveTransactionTitle.text = title
binding.includeContent.textActiveTransactionSubtitle.text = subtitle
setActiveTransactionsShown(isShown)
2019-02-03 17:27:54 -08:00
}
//
// Private View API
//
2019-02-14 17:26:56 -08:00
private fun setActiveTransactionsShown(isShown: Boolean, delay: Long = 0L) {
binding.includeContent.headerActiveTransaction.postDelayed({
binding.includeContent.headerActiveTransaction.animate().alpha(if(isShown) 1f else 0f).setDuration(250).setListener(
AnimatorCompleteListener{ binding.includeContent.groupActiveTransactionItems.visibility = if (isShown) View.VISIBLE else View.GONE }
)
2019-02-14 17:26:56 -08:00
}, delay)
}
/**
2019-02-14 17:26:56 -08:00
* General initialization called during onViewCreated. Mostly responsible for applying the default empty state of
* the view, before any data or information is known.
*/
2019-02-14 17:26:56 -08:00
private fun init() {
zcashLogoAnimation = LottieLooper(binding.lottieZcashBadge, 20..47, 69)
binding.includeContent.buttonActiveTransactionCancel.setOnClickListener {
val transaction = it.tag as? ActiveSendTransaction
if (transaction != null) {
homePresenter.onCancelActiveTransaction(transaction)
} else {
Toaster.short("Error: unable to find transaction to cancel!")
}
}
binding.includeContent.refreshLayout.setProgressViewEndTarget(false, (38f * resources.displayMetrics.density).toInt())
with(binding.includeContent.refreshLayout) {
setOnRefreshListener(this@HomeFragment)
setColorSchemeColors(R.color.zcashBlack.toAppColor())
setProgressBackgroundColorSchemeColor(R.color.zcashYellow.toAppColor())
}
// hide content
setActiveTransactionsShown(false)
setContentViewShown(false)
binding.includeContent.textEmptyWalletMessage.setText(R.string.home_empty_wallet_updating)
setRefreshAnimationPlaying(true).also { Log.e("TWIG-a", "refresh true from init") }
}
// initialize the stuff that is temporary and needs to go ASAP
private fun initTemp() {
with(binding.includeHeader) {
headerFullViews = arrayOf(textBalanceUsd, textBalanceIncludesInfo, textBalanceZec, imageZecSymbolBalanceShadow, imageZecSymbolBalance)
headerEmptyViews = arrayOf(textBalanceZecInfo, textBalanceZecEmpty, imageZecSymbolBalanceShadowEmpty, imageZecSymbolBalanceEmpty)
headerFullViews.forEach { containerHomeHeader.removeView(it) }
headerEmptyViews.forEach { containerHomeHeader.removeView(it) }
binding.includeHeader.containerHomeHeader.visibility = View.INVISIBLE
}
// toggling determines visibility. hide it all.
binding.includeContent.groupEmptyViewItems.visibility = View.GONE
binding.includeContent.groupContentViewItems.visibility = View.GONE
}
/**
* Initialize the Fab button and all its action items. Should be called during onActivityCreated.
*/
private fun initFab() {
val speedDial = binding.sdFab
val nav = mainActivity.navController
HomeFab.values().forEach {
speedDial.addActionItem(it.createItem())
}
speedDial.setOnActionSelectedListener { item ->
HomeFab.fromId(item.id)?.destination?.apply { nav.navigate(this) }
false
}
}
2019-02-14 17:26:56 -08:00
/**
* Helper for creating fablets--those little buttons that pop up when the fab is tapped.
*/
private val createItem: HomeFab.() -> SpeedDialActionItem = {
SpeedDialActionItem.Builder(id, icon)
.setFabBackgroundColor(bgColor.toAppColor())
.setFabImageTintColor(R.color.zcashWhite.toAppColor())
.setLabel(label.toAppString())
.setLabelClickable(true)
.create()
}
private fun setUsdValue(value: String) {
val valueString = String.format("$$value")
// val hairSpace = "\u200A"
// val adjustedValue = "$$hairSpace$valueString"
val textSpan = SpannableString(valueString)
textSpan.setSpan(TopAlignedSpan(), 0, 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
textSpan.setSpan(TopAlignedSpan(), valueString.length - 3, valueString.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
2019-02-14 17:26:56 -08:00
binding.includeHeader.textBalanceUsd.text = textSpan
2018-12-07 09:14:54 -08:00
}
private fun setZecValue(value: String) {
binding.includeHeader.textBalanceZec.text = value
2019-02-14 17:26:56 -08:00
// // bugfix: there is a bug in motionlayout that causes text to flicker as it is resized because the last character doesn't fit. Padding both sides with a thin space works around this bug.
// val hairSpace = "\u200A"
// val adjustedValue = "$hairSpace$valueString$hairSpace"
// text_balance_zec.text = adjustedValue
}
/**
2019-02-14 17:26:56 -08:00
* Called whenever the content has been refreshed on the screen. When it is time to show and hide things.
* If the balance goes to zero, the wallet is now empty so show the empty view.
* If the balance changes from zero, the wallet is no longer empty so hide the empty view.
* But don't do either of these things if the situation has not changed.
*/
private fun onContentRefreshComplete(value: Long) {
val isEmpty = value <= 0L
// wasEmpty isn't enough info. it must be considered along with whether these views were ever initialized
2019-02-14 17:26:56 -08:00
val wasEmpty = binding.includeContent.groupEmptyViewItems.visibility == View.VISIBLE
// situation has changed when we weren't initialized but now we have a balance or emptiness has changed
val situationHasChanged = !viewsInitialized || (isEmpty != wasEmpty)
Log.e("TWIG-t", "updateEmptyViews called with value: $value initialized: $viewsInitialized isEmpty: $isEmpty wasEmpty: $wasEmpty")
if (situationHasChanged) {
Log.e("TWIG-t", "The situation has changed! toggling views!")
2019-02-14 17:26:56 -08:00
setContentViewShown(!isEmpty)
}
2019-02-14 17:26:56 -08:00
setRefreshAnimationPlaying(false).also { Log.e("TWIG-a", "refresh false from onContentRefreshComplete") }
binding.includeHeader.containerHomeHeader.visibility = View.VISIBLE
}
2019-02-03 17:27:54 -08:00
private fun onActiveTransactionTransitionStart() {
2019-02-14 17:26:56 -08:00
binding.includeContent.buttonActiveTransactionCancel.visibility = View.INVISIBLE
2019-02-03 17:27:54 -08:00
}
private fun onActiveTransactionTransitionEnd() {
// TODO: investigate if this fix is still required after getting transition animation working again
2019-02-03 17:27:54 -08:00
// fixes a bug where the translation gets lost, during animation. As a nice side effect, visually, it makes the view appear to settle in to position
2019-02-14 17:26:56 -08:00
binding.includeContent.headerActiveTransaction.translationZ = 10.0f
binding.includeContent.buttonActiveTransactionCancel.apply {
2019-02-03 23:08:26 -08:00
postDelayed({text = "cancel"}, 50L)
2019-02-04 10:42:28 -08:00
visibility = View.VISIBLE
2019-02-03 23:08:26 -08:00
}
2019-02-03 17:27:54 -08:00
}
private fun setTransactionActive(transaction: ActiveTransaction, isActive: Boolean) {
// TODO: get view for transaction, mostly likely keep a sparse array of these or something
if (isActive) {
2019-02-14 17:26:56 -08:00
binding.includeContent.buttonActiveTransactionCancel.setText(R.string.cancel)
binding.includeContent.buttonActiveTransactionCancel.isEnabled = true
binding.includeContent.buttonActiveTransactionCancel.tag = transaction
binding.includeContent.headerActiveTransaction.animate().apply {
translationZ(10f)
duration = 200L
interpolator = DecelerateInterpolator()
}
} else {
2019-02-14 17:26:56 -08:00
binding.includeContent.buttonActiveTransactionCancel.setText(R.string.cancelled)
binding.includeContent.buttonActiveTransactionCancel.isEnabled = false
binding.includeContent.buttonActiveTransactionCancel.tag = null
binding.includeContent.headerActiveTransaction.animate().apply {
translationZ(2f)
duration = 300L
interpolator = AccelerateInterpolator()
}
2019-02-14 17:26:56 -08:00
binding.includeContent.lottieActiveTransaction.cancelAnimation()
}
}
2019-02-03 17:27:54 -08:00
2018-11-12 10:38:37 -08:00
/**
* Defines the basic properties of each FAB button for use while initializing the FAB
2018-11-12 10:38:37 -08:00
*/
enum class HomeFab(
@IdRes val id:Int,
@DrawableRes val icon:Int,
@ColorRes val bgColor:Int,
@StringRes val label:Int,
@IdRes val destination:Int
) {
/* ordered by when they need to be added to the speed dial (i.e. reverse display order) */
REQUEST(
R.id.fab_request,
R.drawable.ic_receipt_24dp,
R.color.icon_request,
R.string.destination_menu_label_request,
R.id.nav_request_fragment
),
RECEIVE(
R.id.fab_receive,
R.drawable.ic_qrcode_24dp,
R.color.icon_receive,
R.string.destination_menu_label_receive,
R.id.nav_receive_fragment
),
SEND(
R.id.fab_send,
R.drawable.ic_menu_send,
R.color.icon_send,
R.string.destination_menu_label_send,
R.id.nav_send_fragment
);
companion object {
fun fromId(id: Int): HomeFab? = values().firstOrNull { it.id == id }
}
2018-11-12 10:38:37 -08:00
}
2019-02-14 17:26:56 -08:00
//
//
//
//// ---------------------------------------------------------------------------------------------------------------------
//// TODO: Delete these test functions
//// ---------------------------------------------------------------------------------------------------------------------
//
var empty = false
val delay = 50L
lateinit var headerEmptyViews: Array<View>
lateinit var headerFullViews: Array<View>
fun forceRedraw() {
view?.postDelayed({
2019-02-14 17:26:56 -08:00
binding.includeHeader.containerHomeHeader.progress = binding.includeHeader.containerHomeHeader.progress - 0.1f
}, delay * 2)
}
// internal fun toggle(isEmpty: Boolean) {
// toggleValues(isEmpty)
// }
internal fun toggleViews(isEmpty: Boolean) {
Log.e("TWIG-t", "toggling views to isEmpty == $isEmpty")
var action: () -> Unit
if (isEmpty) {
action = {
2019-02-14 17:26:56 -08:00
binding.includeContent.groupEmptyViewItems.visibility = View.VISIBLE
binding.includeContent.groupContentViewItems.visibility = View.GONE
headerFullViews.forEach { binding.includeHeader.containerHomeHeader.removeView(it) }
headerEmptyViews.forEach {
tryIgnore {
binding.includeHeader.containerHomeHeader.addView(it)
}
}
}
} else {
action = {
binding.includeContent.groupEmptyViewItems.visibility = View.GONE
binding.includeContent.groupContentViewItems.visibility = View.VISIBLE
headerEmptyViews.forEach { binding.includeHeader.containerHomeHeader.removeView(it) }
headerFullViews.forEach {
tryIgnore {
binding.includeHeader.containerHomeHeader.addView(it)
}
}
}
}
view?.postDelayed({
binding.includeHeader.containerHomeHeader.visibility = View.VISIBLE
action()
viewsInitialized = true
}, delay)
// TODO: the motion layout does not begin in the right state for some reason. Debug this later.
view?.postDelayed(::forceRedraw, delay * 2)
}
// TODO: get rid of all of this and consider two different fragments for the header, instead
internal fun toggleViews2(isEmpty: Boolean) {
var action: () -> Unit
if (isEmpty) {
action = {
// group_empty_view_items.visibility = View.VISIBLE
// group_full_view_items.visibility = View.GONE
headerFullViews.forEach { binding.includeHeader.containerHomeHeader.removeView(it) }
headerEmptyViews.forEach {
tryIgnore {
2019-02-14 17:26:56 -08:00
binding.includeHeader.containerHomeHeader.addView(it)
}
}
}
} else {
action = {
2019-02-14 17:26:56 -08:00
// group_empty_view_items.visibility = View.GONE
// group_full_view_items.visibility = View.VISIBLE
headerEmptyViews.forEach { binding.includeHeader.containerHomeHeader.removeView(it) }
headerFullViews.forEach {
tryIgnore {
2019-02-14 17:26:56 -08:00
binding.includeHeader.containerHomeHeader.addView(it)
}
}
}
}
view?.postDelayed({
action()
viewsInitialized = true
}, delay)
// TODO: the motion layout does not begin in the right state for some reason. Debug this later.
view?.postDelayed(::forceRedraw, delay * 2)
}
// internal fun toggleValues(isEmpty: Boolean) {
// empty = isEmpty
// if(empty) {
// reduceValue()
// } else {
// increaseValue(Random.nextDouble(20.0, 100.0))
// }
// }
2019-02-14 17:26:56 -08:00
inner class HomeTransitionListener : Transition.TransitionListener {
override fun onTransitionStart(transition: Transition) {
}
override fun onTransitionEnd(transition: Transition) {
}
override fun onTransitionResume(transition: Transition) {}
override fun onTransitionPause(transition: Transition) {}
override fun onTransitionCancel(transition: Transition) {}
}
2018-11-12 10:38:37 -08:00
}
@Module
abstract class HomeFragmentModule {
@ContributesAndroidInjector
abstract fun contributeHomeFragment(): HomeFragment
2019-02-14 17:26:56 -08:00
}