First run screen is functional

This commit is contained in:
Kevin Gorham 2019-02-04 02:08:26 -05:00 committed by Kevin Gorham
parent 9a45b5e242
commit 6a8cc9bc6c
20 changed files with 499 additions and 183 deletions

View File

@ -85,10 +85,10 @@ internal object SynchronizerModule {
// TODO: load most of these properties in later, perhaps from settings
object Properties {
const val COMPACT_BLOCK_SERVER = "10.0.2.2"
// const val COMPACT_BLOCK_SERVER = "lightwalletd.z.cash"
// const val COMPACT_BLOCK_SERVER = "10.0.0.26"
const val COMPACT_BLOCK_SERVER = "lightwalletd.z.cash"
const val COMPACT_BLOCK_PORT = 9067
const val CACHE_DB_NAME = "wallet_cache.db"
const val DATA_DB_NAME = "wallet_data.db"
const val CACHE_DB_NAME = "wallet_cache9.db"
const val DATA_DB_NAME = "wallet_data9.db"
val SEED_PROVIDER = SampleSeedProvider("dummyseed")
}

View File

@ -0,0 +1,46 @@
package cash.z.android.wallet.ui.activity
import android.os.Bundle
import androidx.fragment.app.Fragment
import dagger.android.AndroidInjection
import dagger.android.AndroidInjector
import dagger.android.DispatchingAndroidInjector
import dagger.android.HasFragmentInjector
import dagger.android.support.DaggerAppCompatActivity
import dagger.android.support.HasSupportFragmentInjector
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
abstract class BaseMainActivity : DaggerAppCompatActivity(), CoroutineScope, HasFragmentInjector,
HasSupportFragmentInjector {
private lateinit var job: Job
override val coroutineContext: CoroutineContext
get() = job + Dispatchers.Main
override fun onDestroy() {
super.onDestroy()
job.cancel()
}
@Inject
lateinit var supportFragmentInjector: DispatchingAndroidInjector<Fragment>
@Inject
lateinit var frameworkFragmentInjector: DispatchingAndroidInjector<android.app.Fragment>
override fun onCreate(savedInstanceState: Bundle?) {
job = Job()
super.onCreate(savedInstanceState)
}
override fun supportFragmentInjector(): AndroidInjector<androidx.fragment.app.Fragment>? {
return supportFragmentInjector
}
override fun fragmentInjector(): AndroidInjector<android.app.Fragment>? {
return frameworkFragmentInjector
}
}

View File

@ -1,6 +1,8 @@
package cash.z.android.wallet.ui.activity
import android.os.Bundle
import android.util.Log
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.view.inputmethod.InputMethodManager.HIDE_NOT_ALWAYS
import androidx.appcompat.app.AppCompatDelegate
@ -23,7 +25,14 @@ import dagger.android.support.DaggerAppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.nav_header_main.*
import cash.z.wallet.sdk.data.Synchronizer
import com.google.android.material.snackbar.Snackbar
import dagger.android.AndroidInjection
import kotlinx.android.synthetic.main.activity_main_first_run.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.channels.ReceiveChannel
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import javax.inject.Inject
class MainActivity : BaseActivity() {

View File

@ -14,6 +14,7 @@ import androidx.annotation.ColorRes
import androidx.annotation.DrawableRes
import androidx.annotation.IdRes
import androidx.annotation.StringRes
import androidx.drawerlayout.widget.DrawerLayout
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.transition.Transition
@ -39,6 +40,9 @@ import kotlinx.android.synthetic.main.include_home_header.*
import kotlinx.coroutines.launch
import kotlin.random.Random
import com.google.android.material.snackbar.Snackbar
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.activity_main_first_run.*
import kotlin.random.nextLong
/**
@ -75,11 +79,7 @@ class HomeFragment : BaseFragment(), HomePresenter.HomeView {
super.onViewCreated(view, savedInstanceState)
// setActiveTransactionsShown(false)
(activity as MainActivity).let { mainActivity ->
mainActivity.setSupportActionBar(home_toolbar)
mainActivity.setupNavigation()
mainActivity.supportActionBar?.setTitle(R.string.destination_title_home)
}
headerFullViews = arrayOf(text_balance_usd, text_balance_includes_info, text_balance_zec, image_zec_symbol_balance_shadow, image_zec_symbol_balance)
headerEmptyViews = arrayOf(text_balance_zec_info, text_balance_zec_empty, image_zec_symbol_balance_shadow_empty, image_zec_symbol_balance_empty)
@ -89,23 +89,44 @@ class HomeFragment : BaseFragment(), HomePresenter.HomeView {
group_empty_view_items.visibility = View.GONE
group_full_view_items.visibility = View.GONE
if (MainActivity.DEV_MODE) {
image_logo.setOnClickListener {
image_logo.setOnClickListener {
if (MainActivity.DEV_MODE) {
mainActivity.navController.navigate(R.id.nav_send_fragment)
// forceRedraw()
// toggleViews(false)
} else {
forceRedraw()
toggleViews(false)
}
}
button_active_transaction_cancel.setOnClickListener {
onCancelActiveTransaction()
}
refresh_layout.setOnRefreshListener {
val fauxRefresh = Random.nextLong(750L..3000L)
refresh_layout.postDelayed({
refresh_layout.isRefreshing = false
}, fauxRefresh)
}
if (mainActivity.synchronizer.processor.dataDbExists) {
container_first_run.visibility = View.GONE
mainActivity.findViewById<DrawerLayout>(R.id.drawer_layout).setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
sd_fab.visibility = View.VISIBLE
} else {
container_first_run.visibility = View.VISIBLE
mainActivity.findViewById<DrawerLayout>(R.id.drawer_layout).setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
sd_fab.visibility = View.GONE
}
}
override fun onResume() {
super.onResume()
val isEmpty = (recycler_transactions?.adapter?.itemCount ?: 0).let { it == 0 }
// val isEmpty = (recycler_transactions?.adapter?.itemCount ?: 0).let { it == 0 }
// Log.e("TWIG-t", "Resuming and isEmpty == $isEmpty")
// toggleViews(isEmpty)
@ -121,6 +142,12 @@ class HomeFragment : BaseFragment(), HomePresenter.HomeView {
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
(activity as MainActivity).let { mainActivity ->
mainActivity.setSupportActionBar(home_toolbar)
mainActivity.setupNavigation()
mainActivity.supportActionBar?.setTitle(R.string.destination_title_home)
}
homePresenter = HomePresenter(this, mainActivity.synchronizer)
initFab(activity!!)
@ -175,6 +202,12 @@ class HomeFragment : BaseFragment(), HomePresenter.HomeView {
snackbar?.setText(message)
if(progress == 100 && snackbar?.isShownOrQueued != true) snackbar?.show()
}
if (progress >= 100) {
container_first_run.visibility = View.GONE
mainActivity.findViewById<DrawerLayout>(R.id.drawer_layout).setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
sd_fab.visibility = View.VISIBLE
}
}
override fun setActiveTransactions(activeTransactionMap: Map<ActiveTransaction, TransactionState>) {
@ -206,6 +239,8 @@ class HomeFragment : BaseFragment(), HomePresenter.HomeView {
button_active_transaction_cancel.text = "${transaction.value/1000L}"
}
is TransactionState.Failure -> {
lottie_active_transaction.setAnimation(R.raw.lottie_send_failure)
lottie_active_transaction.playAnimation()
title = "Failed"
subtitle = when(transactionState.failedStep) {
TransactionState.Creating -> "Failed to create transaction"
@ -216,8 +251,14 @@ class HomeFragment : BaseFragment(), HomePresenter.HomeView {
onCancelActiveTransaction()
}
is TransactionState.AwaitingConfirmations -> {
title = "ZEC Sent"
subtitle = "Awaiting Confirmations (${transactionState.confirmationCount}/10)"
if (transactionState.confirmationCount < 1) {
lottie_active_transaction.setAnimation(R.raw.lottie_send_success)
lottie_active_transaction.playAnimation()
title = "ZEC Sent"
subtitle = "Awaiting Confirmations (${transactionState.confirmationCount}/10)"
} else {
// play confirmation counting animation
}
}
}
text_active_transaction_title.text = title
@ -305,11 +346,14 @@ class HomeFragment : BaseFragment(), HomePresenter.HomeView {
private fun onActiveTransactionTransitionEnd() {
// 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
header_active_transaction.translationZ = 10.0f
button_active_transaction_cancel.apply {
postDelayed({text = "cancel"}, 50L)
}
}
private fun onCancelActiveTransaction() {
button_active_transaction_cancel.isEnabled = false
button_active_transaction_cancel.text = "canceled"
button_active_transaction_cancel.text = "cancel"
header_active_transaction.animate().apply {
translationZ(0f)
duration = 200L
@ -330,7 +374,6 @@ class HomeFragment : BaseFragment(), HomePresenter.HomeView {
} )
}
homePresenter.onCancelActiveTransaction()
}

View File

@ -4,26 +4,25 @@ import android.util.Log
import cash.z.android.wallet.extention.Toaster
import cash.z.android.wallet.ui.presenter.Presenter.PresenterView
import cash.z.android.wallet.vo.WalletTransaction
import cash.z.android.wallet.vo.WalletTransactionStatus
import cash.z.android.wallet.vo.WalletTransactionStatus.RECEIVED
import cash.z.android.wallet.vo.WalletTransactionStatus.SENT
import cash.z.wallet.sdk.data.ActiveTransaction
import cash.z.wallet.sdk.data.Synchronizer
import cash.z.wallet.sdk.data.TransactionState
import cash.z.wallet.sdk.vo.NoteQuery
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Job
import kotlinx.coroutines.*
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.channels.ReceiveChannel
import kotlinx.coroutines.channels.map
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.math.BigDecimal
import kotlin.coroutines.CoroutineContext
class HomePresenter(
private val view: HomeView,
private val synchronizer: Synchronizer
) : Presenter {
) : Presenter, CoroutineScope {
private val job = Job()
override val coroutineContext: CoroutineContext get() = Dispatchers.IO + job
interface HomeView : PresenterView {
fun setTransactions(transactions: List<WalletTransaction>)
@ -32,42 +31,30 @@ class HomePresenter(
fun setActiveTransactions(activeTransactionMap: Map<ActiveTransaction, TransactionState>)
}
private var balanceJob: Job? = null
private var transactionJob: Job? = null
private var progressJob: Job? = null
private var activeTransactionJob: Job? = null
override suspend fun start() {
Log.e("@TWIG-t", "homePresenter starting!")
with(view) {
balanceJob = launchBalanceBinder(synchronizer.repository.balance())
transactionJob = launchTransactionBinder(synchronizer.repository.allTransactions())
progressJob = launchProgressMonitor(synchronizer.downloader.progress())
activeTransactionJob = launchActiveTransactionMonitor(synchronizer.activeTransactions())
}
launchBalanceBinder(synchronizer.repository.balance())
launchTransactionBinder(synchronizer.repository.allTransactions())
launchProgressMonitor(synchronizer.downloader.progress())
launchActiveTransactionMonitor(synchronizer.activeTransactions())
}
override fun stop() {
Log.e("@TWIG-t", "homePresenter stopping!")
// using nullsafe 'also' to only set these to null when they weren't already null
balanceJob?.cancel()?.also { balanceJob = null }
transactionJob?.cancel()?.also { transactionJob = null }
progressJob?.cancel()?.also { progressJob = null }
activeTransactionJob?.cancel()?.also { progressJob = null }
job.cancel()
}
fun CoroutineScope.launchBalanceBinder(channel: ReceiveChannel<Long>) = launch {
private fun CoroutineScope.launchBalanceBinder(channel: ReceiveChannel<Long>) = launch {
var old: Long? = null
Log.e("@TWIG-t", "balance binder starting!")
for (new in channel) {
Log.e("@TWIG-t", "polled a balance item")
Log.e("@TWIG-t", "polled a balance item")
bind(old, new).also { old = new }
}
Log.e("@TWIG", "balance binder exiting!")
}
fun CoroutineScope.launchTransactionBinder(channel: ReceiveChannel<List<NoteQuery>>) = launch {
private fun CoroutineScope.launchTransactionBinder(channel: ReceiveChannel<List<NoteQuery>>) = launch {
Log.e("@TWIG", "transaction binder starting!")
for (noteQueryList in channel) {
Log.e("@TWIG", "received ${noteQueryList.size} transactions for presenting")
@ -81,14 +68,15 @@ class HomePresenter(
private suspend fun updateTimeStamp(noteQuery: NoteQuery) = synchronizer.updateTimeStamp(noteQuery.height)
fun CoroutineScope.launchProgressMonitor(channel: ReceiveChannel<Int>) = launch {
private fun CoroutineScope.launchProgressMonitor(channel: ReceiveChannel<Int>) = launch {
Log.e("@TWIG", "progress monitor starting on thread ${Thread.currentThread().name}!")
for (i in channel) {
bind(i)
}
Log.e("@TWIG", "progress monitor exiting!")
}
fun CoroutineScope.launchActiveTransactionMonitor(channel: ReceiveChannel<Map<ActiveTransaction, TransactionState>>) = launch {
private fun CoroutineScope.launchActiveTransactionMonitor(channel: ReceiveChannel<Map<ActiveTransaction, TransactionState>>) = launch {
Log.e("@TWIG-v", "active transaction monitor starting!")
for (i in channel) {
bind(i)
@ -96,20 +84,26 @@ class HomePresenter(
Log.e("@TWIG-v", "active transaction monitor exiting!")
}
private fun bind(old: Long?, new: Long) {
//
// View Callbacks on Main Thread
//
private fun bind(old: Long?, new: Long) = onMain {
Log.e("@TWIG-t", "binding balance of $new")
view.updateBalance(old ?: 0L, new)
}
private fun bind(transactions: List<WalletTransaction>) {
private fun bind(transactions: List<WalletTransaction>) = onMain {
Log.e("@TWIG-t", "binding ${transactions.size} walletTransactions")
view.setTransactions(transactions)
}
private fun bind(progress: Int) {
private fun bind(progress: Int) = onMain {
view.showProgress(progress)
if(progress == 100) {
view.launch {
if (progress == 100) {
launch {
// TODO: remove this behavior and pull it down into the synchronizer
Log.e("@TWIG-t", "triggering manual scan!")
synchronizer.processor.scanBlocks()
@ -117,24 +111,29 @@ class HomePresenter(
}
}
private fun bind(activeTransactionMap: Map<ActiveTransaction, TransactionState>) {
private fun bind(activeTransactionMap: Map<ActiveTransaction, TransactionState>) = onMain {
Log.e("@TWIG-v", "binding a.t. map of size ${activeTransactionMap.size}")
if (activeTransactionMap.isNotEmpty()) view.setActiveTransactions(activeTransactionMap)
}
fun onCancelActiveTransaction() {
// TODO: hold a reference to the job and cancel it
Toaster.short("Cancelled transaction!")
}
private fun onMain(block: () -> Unit) = launch {
withContext(Main) {
Log.e("@TWIG-t", "running task on main thread - start ${coroutineContext[Job]} | ${coroutineContext[CoroutineName]}")
block()
Log.e("@TWIG-t", "running task on main thread - complete")
}
}
private fun NoteQuery.toWalletTransaction(timeOverride: Long? = null): WalletTransaction {
// convert time from seconds to milliseconds
val timestamp = if (timeOverride == null) time * 1000 else timeOverride * 1000
Log.e("@TWIG-u", "setting timestamp to $timestamp for value $value")
return WalletTransaction(height, if (sent) SENT else RECEIVED, timestamp, BigDecimal(value / 1e8))
}
}

View File

@ -0,0 +1,38 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cash.z.android.wallet.ui.util
import android.content.Context
import android.util.AttributeSet
import androidx.constraintlayout.motion.widget.MotionLayout
import androidx.viewpager.widget.ViewPager
class ViewpagerHeader @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : MotionLayout(context, attrs, defStyleAttr), ViewPager.OnPageChangeListener {
override fun onPageScrollStateChanged(state: Int) {
}
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
val numPages = 3
progress = (position + positionOffset) / (numPages - 1)
}
override fun onPageSelected(position: Int) {
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 865 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?><!--
Copyright (C) 2018 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<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/container_first_run"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
android:background="#81CAFF">
<cash.z.android.wallet.ui.util.ViewpagerHeader
android:layout_width="match_parent"
android:layout_height="230dp"
app:layoutDescription="@xml/scene_15"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<ImageView
android:id="@+id/mountains"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:src="@drawable/mountains" />
<ImageView
android:id="@+id/trees1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/trees"
tools:layout_editor_absoluteX="23dp"
tools:layout_editor_absoluteY="130dp" />
<ImageView
android:id="@+id/trees2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/trees"
tools:layout_editor_absoluteX="7dp"
tools:layout_editor_absoluteY="98dp" />
<ImageView
android:id="@+id/car"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/car"
tools:layout_editor_absoluteX="7dp"
tools:layout_editor_absoluteY="194dp" />
</cash.z.android.wallet.ui.util.ViewpagerHeader>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -37,4 +37,6 @@
app:layout_anchor="@id/home_app_bar"
app:layout_anchorGravity="bottom|center"
app:srcCompat="@drawable/ic_zcashlogo_badge" />
<include layout="@layout/activity_main_first_run"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -9,147 +9,152 @@
android:fillViewport="true"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/content_home"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingStart="16dp"
android:paddingTop="30dp"
android:paddingEnd="16dp"
android:paddingBottom="16dp"
android:transitionName="@string/transition_active_transaction_background">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/refresh_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<!-- Active Transaction - primary -->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/header_active_transaction"
android:id="@+id/content_home"
android:layout_width="match_parent"
android:layout_height="70dp"
android:background="@drawable/background_rounded_corners_opaque"
android:clipToPadding="false"
android:padding="16dp"
android:transitionName="@string/transition_active_transaction_card"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
android:layout_height="match_parent"
android:paddingStart="16dp"
android:paddingTop="30dp"
android:paddingEnd="16dp"
android:paddingBottom="16dp"
android:transitionName="@string/transition_active_transaction_background">
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/lottie_active_transaction"
android:layout_width="36dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
<!-- Active Transaction - primary -->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/header_active_transaction"
android:layout_width="match_parent"
android:layout_height="70dp"
android:background="@drawable/background_rounded_corners_opaque"
android:clipToPadding="false"
android:padding="16dp"
android:transitionName="@string/transition_active_transaction_card"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:lottie_autoPlay="true"
app:lottie_loop="false"
app:lottie_rawRes="@raw/lottie_active_transaction_fail" />
app:layout_constraintTop_toTopOf="parent">
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/lottie_active_transaction"
android:layout_width="36dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:lottie_autoPlay="true"
app:lottie_loop="false"
app:lottie_rawRes="@raw/lottie_send_common" />
<TextView
android:id="@+id/text_active_transaction_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:text="Preparing 1.01 ZEC"
android:textSize="@dimen/text_size_body_1"
android:textStyle="bold"
android:transitionName="@string/transition_active_transaction_title"
app:layout_constraintStart_toEndOf="@id/lottie_active_transaction"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/text_active_transaction_subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="to zsapling...123456789"
android:textSize="@dimen/text_size_caption"
android:transitionName="@string/transition_active_transaction_address"
app:layout_constraintStart_toStartOf="@id/text_active_transaction_title"
app:layout_constraintTop_toBottomOf="@id/text_active_transaction_title" />
<Button
android:id="@+id/button_active_transaction_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@null"
android:text="cancel"
android:textColor="@color/selector_red_button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<!-- Label: Past Activity -->
<TextView
android:id="@+id/text_active_transaction_title"
android:id="@+id/text_transaction_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:text="Preparing 1.01 ZEC"
android:textSize="@dimen/text_size_body_1"
android:layout_marginTop="16dp"
android:paddingBottom="16dp"
android:text="Past Activity"
android:textColor="@color/text_dark"
android:textSize="@dimen/text_size_body_2"
android:textStyle="bold"
android:transitionName="@string/transition_active_transaction_title"
app:layout_constraintStart_toEndOf="@id/lottie_active_transaction"
app:layout_constraintTop_toTopOf="parent" />
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/header_active_transaction" />
<TextView
android:id="@+id/text_active_transaction_subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="to zsapling...123456789"
android:textSize="@dimen/text_size_caption"
android:transitionName="@string/transition_active_transaction_address"
app:layout_constraintStart_toStartOf="@id/text_active_transaction_title"
app:layout_constraintTop_toBottomOf="@id/text_active_transaction_title" />
<!-- Transactions -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_transactions"
android:layout_width="0dp"
android:layout_height="0dp"
android:clipToPadding="false"
<Button
android:id="@+id/button_active_transaction_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@null"
android:text="cancel"
android:textColor="@color/selector_red_button"
android:paddingBottom="72dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/text_transaction_header"
tools:itemCount="15"
tools:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/item_transaction"
tools:orientation="vertical" />
<!-- Empty: image -->
<ImageView
android:id="@+id/image_empty_wallet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.281966"
app:srcCompat="@drawable/ic_emptywallet" />
<!-- Empty: message -->
<TextView
android:id="@+id/text_wallet_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="center"
android:padding="16dp"
android:text="@string/home_empty_wallet"
android:textColor="#AAAAAA"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/image_empty_wallet" />
<!-- -->
<!-- Groups -->
<!-- -->
<androidx.constraintlayout.widget.Group
android:id="@+id/group_full_view_items"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="text_transaction_header,recycler_transactions" />
<androidx.constraintlayout.widget.Group
android:id="@+id/group_empty_view_items"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="image_empty_wallet,text_wallet_message" />
</androidx.constraintlayout.widget.ConstraintLayout>
<!-- Label: Past Activity -->
<TextView
android:id="@+id/text_transaction_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:paddingBottom="16dp"
android:text="Past Activity"
android:textColor="@color/text_dark"
android:textSize="@dimen/text_size_body_2"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/header_active_transaction" />
<!-- Transactions -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_transactions"
android:layout_width="0dp"
android:layout_height="0dp"
android:clipToPadding="false"
android:paddingBottom="72dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/text_transaction_header"
tools:itemCount="15"
tools:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/item_transaction"
tools:orientation="vertical" />
<!-- Empty: image -->
<ImageView
android:id="@+id/image_empty_wallet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.281966"
app:srcCompat="@drawable/ic_emptywallet" />
<!-- Empty: message -->
<TextView
android:id="@+id/text_wallet_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="center"
android:padding="16dp"
android:text="@string/home_empty_wallet"
android:textColor="#AAAAAA"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/image_empty_wallet" />
<!-- -->
<!-- Groups -->
<!-- -->
<androidx.constraintlayout.widget.Group
android:id="@+id/group_full_view_items"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="text_transaction_header,recycler_transactions" />
<androidx.constraintlayout.widget.Group
android:id="@+id/group_empty_view_items"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="image_empty_wallet,text_wallet_message" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</androidx.core.widget.NestedScrollView>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,103 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2018 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<MotionScene
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:motion="http://schemas.android.com/apk/res-auto">
<Transition
motion:constraintSetStart="@+id/start"
motion:constraintSetEnd="@+id/end"
motion:duration="1000"
motion:interpolator="linear">
<OnSwipe
motion:touchAnchorId="@+id/car"
motion:touchAnchorSide="right"
motion:dragDirection="dragRight" />
<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@id/mountains"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:translationX="10dp"
android:scaleX="1.2"
android:scaleY="1.2"
motion:layout_constraintTop_toTopOf="parent"/>
<Constraint
android:id="@id/trees1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:layout_marginBottom="60dp"
motion:layout_constraintLeft_toLeftOf="parent"
motion:layout_constraintBottom_toBottomOf="parent"/>
<Constraint
android:id="@id/trees2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="90dp"
android:layout_marginBottom="30dp"
motion:layout_constraintLeft_toLeftOf="parent"
motion:layout_constraintBottom_toBottomOf="parent"/>
<Constraint
android:id="@id/car"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginBottom="8dp"
motion:layout_constraintLeft_toLeftOf="parent"
motion:layout_constraintBottom_toBottomOf="parent"/>
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@id/mountains"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:translationX="-10dp"
android:scaleX="1.2"
android:scaleY="1.2"
motion:layout_constraintTop_toTopOf="parent"/>
<Constraint
android:id="@id/trees1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="0dp"
android:layout_marginBottom="60dp"
motion:layout_constraintLeft_toLeftOf="parent"
motion:layout_constraintBottom_toBottomOf="parent"/>
<Constraint
android:id="@id/trees2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginBottom="30dp"
motion:layout_constraintLeft_toLeftOf="parent"
motion:layout_constraintBottom_toBottomOf="parent"/>
<Constraint
android:id="@id/car"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="20dp"
android:layout_marginBottom="8dp"
motion:layout_constraintRight_toRightOf="parent"
motion:layout_constraintBottom_toBottomOf="parent"/>
</ConstraintSet>
</Transition>
</MotionScene>