checkpoint: history is feature complete

This commit is contained in:
Kevin Gorham 2019-02-19 13:09:53 -05:00 committed by Kevin Gorham
parent b215c85915
commit 504272ef93
24 changed files with 320 additions and 112 deletions

View File

@ -42,6 +42,8 @@ import kotlinx.coroutines.channels.ReceiveChannel
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import javax.inject.Inject
import kotlin.random.Random
import kotlin.random.nextInt
class MainActivity : BaseActivity() {
@ -49,6 +51,7 @@ class MainActivity : BaseActivity() {
lateinit var synchronizer: Synchronizer
lateinit var binding: ActivityMainBinding
lateinit var loadMessages: List<String>
// used to manage the drawer and drawerToggle interactions
private lateinit var appBarConfiguration: AppBarConfiguration
@ -62,7 +65,7 @@ class MainActivity : BaseActivity() {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
initAppBar()
loadMessages = generateFunLoadMessages().shuffled()
synchronizer.start(this)
}
@ -70,7 +73,6 @@ class MainActivity : BaseActivity() {
setSupportActionBar(findViewById(R.id.main_toolbar))
// supportActionBar?.setDisplayHomeAsUpEnabled(false)
setupNavigation()
supportActionBar?.setTitle("main title")
}
override fun onDestroy() {
@ -128,12 +130,37 @@ class MainActivity : BaseActivity() {
}
}
fun nextLoadMessage(index: Int = -1): String {
return if (index < 0) loadMessages.random() else loadMessages[index]
}
companion object {
init {
// Enable vector drawable magic
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
}
// TODO: move these lists, once approved
fun generateSeriousLoadMessages(): List<String> {
return listOf(
"Initializing your shielded address",
"Connecting to testnet",
"Downloading historical blocks",
"Synchronizing to current blockchain",
"Searching for past transactions",
"Validating your balance"
)
}
fun generateFunLoadMessages(): List<String> {
return listOf(
"Reticulating splines",
"Making the sausage",
"Drinking the kool-aid",
"Learning to spell Lamborghini",
"Asking Zooko, \"when moon?!\"",
"Pretending to look busy"
)
}
}
}

View File

@ -4,23 +4,25 @@ import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.annotation.LayoutRes
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import cash.z.android.wallet.R
import cash.z.android.wallet.extention.toAppColor
import cash.z.wallet.sdk.dao.WalletTransaction
import cash.z.wallet.sdk.ext.convertZatoshiToZec
import cash.z.wallet.sdk.ext.toZec
import java.text.SimpleDateFormat
import cash.z.wallet.sdk.dao.WalletTransaction
import java.util.*
import kotlin.math.absoluteValue
class TransactionAdapter : ListAdapter<WalletTransaction, TransactionViewHolder>(DIFF_CALLBACK) {
class TransactionAdapter(@LayoutRes val itemResId: Int = R.layout.item_transaction) : ListAdapter<WalletTransaction, TransactionViewHolder>(DIFF_CALLBACK) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TransactionViewHolder {
val itemView = LayoutInflater.from(parent.context).inflate(R.layout.item_transaction, parent, false)
val itemView = LayoutInflater.from(parent.context).inflate(itemResId, parent, false)
return TransactionViewHolder(itemView)
}
override fun onBindViewHolder(holder: TransactionViewHolder, position: Int) = holder.bind(getItem(position))
@ -33,19 +35,26 @@ private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<WalletTransaction>()
class TransactionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val status = itemView.findViewById<View>(R.id.view_transaction_status)
private val icon = itemView.findViewById<ImageView>(R.id.image_transaction_type)
private val timestamp = itemView.findViewById<TextView>(R.id.text_transaction_timestamp)
private val amount = itemView.findViewById<TextView>(R.id.text_transaction_amount)
private val address = itemView.findViewById<TextView>(R.id.text_transaction_address)
private val formatter = SimpleDateFormat("M/d h:mma", Locale.getDefault())
fun bind(tx: WalletTransaction) {
val sign = if(tx.isSend) "-" else "+"
val sign = if (tx.isSend) "-" else "+"
val amountColor = if (tx.isSend) R.color.text_dark_dimmed else R.color.colorPrimary
val transactionColor = if(tx.isSend) R.color.send_associated else R.color.receive_associated
val transactionColor = if (tx.isSend) R.color.send_associated else R.color.receive_associated
val transactionIcon = if (tx.isSend) R.drawable.ic_sent_transaction else R.drawable.ic_received_transaction
val zecAbsoluteValue = tx.value.absoluteValue.convertZatoshiToZec(3)
status.setBackgroundColor(transactionColor.toAppColor())
val senderAddress = if (tx.address != null) "to ${tx.address}" else "from shielded mystery person"
timestamp.text = if (!tx.isMined || tx.timeInSeconds == 0L) "Pending" else formatter.format(tx.timeInSeconds * 1000)
Log.e("TWIG-z", "TimeInSeconds: ${tx.timeInSeconds}")
amount.text = "$sign$zecAbsoluteValue"
amount.setTextColor(amountColor.toAppColor())
// maybes - and if this gets to be too much, then pass in a custom holder when constructing the adapter, instead
status?.setBackgroundColor(transactionColor.toAppColor())
address?.text = senderAddress
icon?.setImageResource(transactionIcon)
}
}

View File

@ -66,6 +66,11 @@ class FirstrunFragment : ProgressFragment(R.id.progress_firstrun), Transition.Tr
}
}
override fun showProgress(progress: Int) {
super.showProgress(progress)
binding.textProgressFirstrun.text = getProgressText(progress)
}
override fun onProgressComplete() {
super.onProgressComplete()
binding.textProgressFirstrun.visibility = View.GONE

View File

@ -32,10 +32,11 @@ class HistoryFragment : BaseFragment(), HistoryPresenter.HistoryView {
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
mainActivity.setToolbarShown(true)
historyPresenter = HistoryPresenter(this, mainActivity.synchronizer)
binding.recyclerTransactionsHistory.apply {
layoutManager = LinearLayoutManager(activity, RecyclerView.VERTICAL, false)
adapter = TransactionAdapter()
adapter = TransactionAdapter(R.layout.item_transaction_history)
addItemDecoration(AlternatingRowColorDecoration())
}
}
@ -53,7 +54,13 @@ class HistoryFragment : BaseFragment(), HistoryPresenter.HistoryView {
}
override fun setTransactions(transactions: List<WalletTransaction>) {
(binding.recyclerTransactionsHistory.adapter as TransactionAdapter).submitList(transactions)
mainActivity.supportActionBar?.setTitle(resources.getQuantityString(R.plurals.history_transaction_count_title, transactions.size, transactions.size))
with (binding.recyclerTransactionsHistory) {
(adapter as TransactionAdapter).submitList(transactions)
postDelayed({
smoothScrollToPosition(0)
}, 100L)
}
}
}

View File

@ -83,13 +83,6 @@ class HomeFragment : BaseFragment(), SwipeRefreshLayout.OnRefreshListener, HomeP
super.onViewCreated(view, savedInstanceState)
initTemp()
init()
// launch {
// Log.e("TWIG", "deciding whether to show first run")
// val extraDelay = measureTimeMillis {
// setFirstRunShown(mainActivity.synchronizer.isFirstRun() || mainActivity.synchronizer.isOutOfSync())
// }
// Log.e("TWIG", "done deciding whether to show first run in $extraDelay ms. Was that worth it? Or should we toggle a boolean in the application class?")
// }
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
@ -105,6 +98,9 @@ class HomeFragment : BaseFragment(), SwipeRefreshLayout.OnRefreshListener, HomeP
adapter = TransactionAdapter()
addItemDecoration(AlternatingRowColorDecoration())
}
binding.includeContent.textTransactionHeaderSeeAll.setOnClickListener {
mainActivity.navController.navigate(R.id.nav_history_fragment)
}
}
override fun onResume() {
@ -170,44 +166,16 @@ class HomeFragment : BaseFragment(), SwipeRefreshLayout.OnRefreshListener, HomeP
}
override fun setTransactions(transactions: List<WalletTransaction>) {
val recent = if(transactions.size > 12) transactions.subList(0, 12) else transactions
with (binding.includeContent.recyclerTransactions) {
(adapter as TransactionAdapter).submitList(transactions.sortedByDescending {
it.timeInSeconds
})
(adapter as TransactionAdapter).submitList(recent)
postDelayed({
smoothScrollToPosition(0)
}, 100L)
if (binding.includeFirstRun.visibility == View.VISIBLE) setFirstRunShown(false)
}
}
override fun showProgress(progress: Int) {
if(progress >= 100) {
view?.postDelayed({
onInitialLoadComplete()
}, 3000L)
} else {
setRefreshAnimationPlaying(true).also { Log.e("TWIG-a", "refresh true from showProgress") }
binding.includeContent.textEmptyWalletMessage.setText(R.string.home_empty_wallet_updating)
if (recent.size != transactions.size) {
binding.includeContent.textTransactionHeaderSeeAll.visibility = View.VISIBLE
}
// snackbar.showOk(view!!, "progress: $progress")
// TODO: improve this with Lottie animation. but for now just use the empty view for downloading...
// var hasEmptyViews = group_empty_view_items.visibility == View.VISIBLE
// if(!viewsInitialized) toggleViews(true)
//
// val message = if(progress >= 100) "Download complete! Processing blocks..." else "Downloading remaining blocks ($progress%)"
//// text_wallet_message.text = message
//
// if (snackbar == null && progress <= 50) {
// snackbar = Snackbar.make(view!!, "$message", Snackbar.LENGTH_INDEFINITE)
// .setAction("OK") {
// snackbar?.dismiss()
// }
// snackbar?.show()
// } else {
// snackbar?.setText(message)
// if(snackbar?.isShownOrQueued != true) snackbar?.show()
// }
}
private fun onInitialLoadComplete() {
@ -318,13 +286,6 @@ class HomeFragment : BaseFragment(), SwipeRefreshLayout.OnRefreshListener, HomeP
}, delay)
}
private fun setFirstRunShown(isShown: Boolean) {
binding.includeFirstRun.visibility = if (isShown) View.VISIBLE else View.GONE
mainActivity.setDrawerLocked(isShown)
binding.sdFab.visibility = if (!isShown) View.VISIBLE else View.GONE
binding.lottieZcashBadge.visibility = if(!isShown) View.VISIBLE else View.GONE
}
/**
* General initialization called during onViewCreated. Mostly responsible for applying the default empty state of
* the view, before any data or information is known.
@ -437,7 +398,6 @@ class HomeFragment : BaseFragment(), SwipeRefreshLayout.OnRefreshListener, HomeP
if (situationHasChanged) {
Log.e("TWIG-t", "The situation has changed! toggling views!")
setContentViewShown(!isEmpty)
if (!isEmpty) setFirstRunShown(false)
}
setRefreshAnimationPlaying(false).also { Log.e("TWIG-a", "refresh false from onContentRefreshComplete") }

View File

@ -17,6 +17,7 @@ abstract class ProgressFragment(@IdRes private val progressBarId: Int) : BaseFra
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
progressBar = view.findViewById(progressBarId)
// progressBar.visibility = View.INVISIBLE
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
@ -45,9 +46,24 @@ abstract class ProgressFragment(@IdRes private val progressBarId: Int) : BaseFra
progressBar.visibility = View.GONE
})
}
} else if (progress > 0 && progressBar.visibility != View.VISIBLE) {
progressBar.visibility = View.VISIBLE
}
progressBar.progress = progress
}
// TODO: replace this quick and dirty logic with something permanent
open fun getProgressText(progress: Int): String {
if (mainActivity == null) return ""
// cycle twice
val factor = 100 / (mainActivity.loadMessages.size * 2)
val index = (progress/factor).rem(mainActivity.loadMessages.size)
var message = "$progress% ${mainActivity.nextLoadMessage(index)}"
if (progress > 98) message = "Done!"
if (progress >= 50) message = message.replace("Zooko", "Zooko AGAIN", true).replace("Learning to spell", "Double-checking the spelling of").replace("the kool", "MORE kool", true).replace("Making the sausage", "Getting a little hangry by now!", true)
return message
}
open fun onProgressComplete() {}
}

View File

@ -35,6 +35,8 @@ class SyncFragment : ProgressFragment(R.id.progress_sync) {
binding.buttonNext.setOnClickListener {
mainActivity.navController.navigate(R.id.nav_home_fragment)
}
binding.progressSync.visibility = View.INVISIBLE
binding.textProgressSync.visibility = View.INVISIBLE
}
override fun onResume() {
@ -43,6 +45,12 @@ class SyncFragment : ProgressFragment(R.id.progress_sync) {
mainActivity.setToolbarShown(true)
}
override fun showProgress(progress: Int) {
binding.textProgressSync.text = getProgressText(progress)
binding.textProgressSync.visibility = View.VISIBLE
super.showProgress(progress)
}
override fun onProgressComplete() {
super.onProgressComplete()
binding.textProgressSync.visibility = View.GONE

View File

@ -23,6 +23,7 @@ import android.graphics.Matrix
import android.util.Log
import androidx.core.app.SharedElementCallback
import androidx.transition.TransitionInflater
import cash.z.android.wallet.BuildConfig
import cash.z.android.wallet.ui.presenter.ProgressPresenter
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@ -50,13 +51,20 @@ class WelcomeFragment : ProgressFragment(R.id.progress_welcome) {
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val network = if (resources.getBoolean(R.bool.is_testnet)) "Testnet 2.0.1" else "Mainnet 2.0.1"
var buildInfo = "PoC v${BuildConfig.VERSION_NAME} $network\nZcash Company - For demo purposes only"
binding.textWelcomeBuildInfo.text = buildInfo
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
view!!.postDelayed({
launch {
onNext()
}
}, 2000L)
}, 5000L)
// this.setExitSharedElementCallback(object : SharedElementCallback() {
// override fun onCaptureSharedElementSnapshot(

View File

@ -7,6 +7,7 @@ import cash.z.wallet.sdk.data.ActiveSendTransaction
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.data.twig
import kotlinx.coroutines.*
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.channels.ReceiveChannel
@ -49,8 +50,8 @@ class HistoryPresenter(
//
private fun bind(transactions: List<WalletTransaction>) {
Log.e("@TWIG", "binding ${transactions.size} walletTransactions")
view.setTransactions(transactions)
twig("binding ${transactions.size} walletTransactions")
view.setTransactions(transactions.sortedByDescending { it.timeInSeconds })
}
}

View File

@ -23,7 +23,6 @@ class HomePresenter(
interface HomeView : PresenterView {
fun setTransactions(transactions: List<WalletTransaction>)
fun updateBalance(old: Long, new: Long)
fun showProgress(progress: Int)
fun setActiveTransactions(activeTransactionMap: Map<ActiveTransaction, TransactionState>)
fun onCancelledTooLate()
}
@ -32,7 +31,6 @@ class HomePresenter(
Log.e("@TWIG-t", "homePresenter starting!")
launchBalanceBinder(synchronizer.balance())
launchTransactionBinder(synchronizer.allTransactions())
launchProgressMonitor(synchronizer.progress())
launchActiveTransactionMonitor(synchronizer.activeTransactions())
}
@ -60,14 +58,6 @@ class HomePresenter(
Log.e("@TWIG", "transaction binder exiting!")
}
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!")
}
private fun CoroutineScope.launchActiveTransactionMonitor(channel: ReceiveChannel<Map<ActiveTransaction, TransactionState>>) = launch {
Log.e("@TWIG-v", "active transaction monitor starting!")
for (i in channel) {
@ -89,12 +79,9 @@ class HomePresenter(
private fun bind(transactions: List<WalletTransaction>) = onMain {
Log.e("@TWIG-b", "binding ${transactions.size} walletTransactions")
view.setTransactions(transactions)
}
private fun bind(progress: Int) = onMain {
Log.e("@TWIG-b", "binding progress of $progress")
view.showProgress(progress)
view.setTransactions(transactions.sortedByDescending {
it.timeInSeconds
})
}
private fun bind(activeTransactionMap: Map<ActiveTransaction, TransactionState>) = onMain {

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:tint="#FFFFFF"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M1,21h22L12,2 1,21zM13,18h-2v-2h2v2zM13,14h-2v-4h2v4z" />
</vector>

View File

@ -5,8 +5,13 @@
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:background="@color/fragment_history_background">
<include
android:id="@+id/main_app_bar"
layout="@layout/include_main_app_bar"
tools:ignore="MissingConstraints"
android:visibility="invisible"/>
<!-- Transactions -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_transactions_history"
@ -14,11 +19,14 @@
android:layout_height="0dp"
android:clipToPadding="false"
android:paddingBottom="72dp"
android:layout_margin="16dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/main_toolbar"
app:layout_constraintTop_toBottomOf="@id/main_app_bar"
tools:itemCount="15"
tools:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/item_transaction_history"

View File

@ -56,8 +56,5 @@
app:lottie_loop="false"
app:lottie_rawRes="@raw/lottie_zcash_badge_refresh_whitebg" />
<include
android:id="@+id/include_first_run"
layout="@layout/activity_main_first_run" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/container_welcome"
@ -36,7 +37,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-light"
android:text="Reference Wallet Alpha"
android:text="@string/product_name"
android:textColor="@color/text_dark_dimmed"
android:textSize="@dimen/text_size_h5"
app:layout_constraintEnd_toEndOf="parent"
@ -48,7 +49,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="PoC v1.2.3 Testnet 2.0.0\nZcash Company - For demo purposes only"
tools:text="PoC v1.2.3 Testnet 2.0.0\nZcash Company - For demo purposes only"
android:textColor="@color/text_dark_dimmed"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"

View File

@ -136,6 +136,24 @@
app:layout_constraintTop_toBottomOf="@id/header_active_transaction"
app:layout_goneMarginTop="0dp" />
<!-- Label: See all -->
<TextView
android:id="@+id/text_transaction_header_see_all"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:fontFamily="sans-serif-light"
android:paddingBottom="12dp"
android:text="@string/home_see_all_transaction_label"
android:textAllCaps="true"
android:textColor="@color/colorPrimary"
android:textSize="@dimen/text_size_body_2"
android:textStyle="bold"
android:visibility="gone"
app:layout_constraintBaseline_toBaselineOf="@id/text_transaction_header"
app:layout_constraintEnd_toEndOf="parent"
app:layout_goneMarginTop="0dp" />
<!-- Transactions -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_transactions"

View File

@ -4,46 +4,56 @@
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container_transaction"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/home_transaction_item_background"
android:paddingEnd="8dp"
android:paddingRight="8dp"
android:layout_height="60dp"
android:background="@color/history_transaction_item_background"
android:elevation="1dp"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:layout_marginTop="8dp"
tools:ignore="RtlSymmetry">
<View
android:id="@+id/view_transaction_status"
android:layout_width="6dp"
android:layout_height="0dp"
android:layout_marginTop="1dp"
android:layout_marginBottom="1dp"
android:background="@color/colorPrimary"
<ImageView
android:id="@+id/image_transaction_type"
android:layout_width="40dp"
android:layout_height="40dp"
app:srcCompat="@drawable/ic_sent_transaction"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/text_transaction_timestamp"
app:layout_constraintBottom_toBottomOf="@id/text_transaction_timestamp"/>
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/text_transaction_timestamp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:paddingBottom="8dp"
android:paddingTop="8dp"
tools:text="8/23 3:24pm"
android:textColor="@color/text_dark"
android:textSize="@dimen/text_size_body_2"
android:textStyle="bold"
app:layout_constraintBottom_toTopOf="@id/text_transaction_address"
app:layout_constraintStart_toEndOf="@id/image_transaction_type"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"
tools:text="8/23 3:24pm" />
<TextView
android:id="@+id/text_transaction_address"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/text_dark_dimmed"
android:textSize="@dimen/text_size_body_2"
app:layout_constraintStart_toStartOf="@id/text_transaction_timestamp"
app:layout_constraintTop_toBottomOf="@id/text_transaction_timestamp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/view_transaction_status"
app:layout_constraintTop_toTopOf="parent" />
tools:text="8/23 3:24pm" />
<TextView
android:id="@+id/text_transaction_amount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="+ 4.244"
tools:text="+ 4.244"
android:textColor="@color/colorPrimary"
android:textSize="@dimen/text_size_body_2"
android:textSize="@dimen/text_size_h5"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="is_testnet">false</bool>
</resources>

View File

@ -71,10 +71,12 @@
<color name="fragment_receive_background">@color/zcashBlack_light</color>
<color name="fragment_request_background">@color/colorPrimary</color>
<color name="fragment_send_background">@color/zcashWhite_light</color>
<color name="fragment_history_background">@color/zcashWhite_light</color>
<color name="fragment_home_background">@color/zcashWhite_light</color>
<color name="launcher_icon_background">@color/zcashPrimaryMedium</color>
<color name="receive_title_background">@color/zcashBlack_12</color>
<color name="home_transaction_item_background">@color/zcashBlueGray</color>
<color name="history_transaction_item_background">@color/zcashWhite</color>
<color name="divider_background">@color/zcashBlack_12</color>
<!-- content -->

View File

@ -1,5 +1,7 @@
<resources>
<string name="app_name">Zcash Wallet</string>
<string name="product_name">Reference Wallet Alpha</string>
<string name="navigation_drawer_open">Open navigation drawer</string>
<string name="navigation_drawer_close">Close navigation drawer</string>
<string name="nav_header_title">Zcash Reference Wallet</string>
@ -22,7 +24,7 @@
<string name="destination_title_welcome"></string>
<string name="destination_title_firstrun">Getting Started</string>
<string name="destination_title_sync">Release Notes</string>
<string name="destination_title_history">History</string>
<string name="destination_title_history">Past Transactions</string>
<string name="destination_title_about">About</string>
<string name="destination_title_settings">Settings</string>
<string name="destination_title_placeholder">Coming Soon</string>
@ -53,7 +55,13 @@
<string name="home_empty_wallet_collapse">Future transactions will show up here.</string>
<string name="home_current_transaction_label">Current Activity</string>
<string name="home_past_transaction_label">Past Activity</string>
<string name="home_see_all_transaction_label">See All</string>
<!-- History -->
<plurals name="history_transaction_count_title">
<item quantity="other">%s Past Transactions</item>
<item quantity="one">%s Past Transaction</item>
</plurals>
<!-- Receive -->
<string name="receive_address_title">Your Zcash shielded address</string>

View File

@ -15,8 +15,9 @@ import javax.inject.Singleton
@Module
internal object SynchronizerModule {
const val MOCK_TX_INTERVAL = 30_000L
const val MOCK_LOAD_DURATION = 5_000L
const val MOCK_LOAD_DURATION = 3_000L
// const val MOCK_LOAD_DURATION = 30_000L
const val MOCK_TX_INTERVAL = 5_000L
const val MOCK_ACTIVE_TX_STATE_CHANGE_INTERVAL = 5_000L

View File

@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/container_welcome"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_content_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="32dp" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_content_end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_end="32dp" />
<ImageView
android:id="@+id/logo_welcome"
android:layout_width="168dp"
android:layout_height="168dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.17"
app:srcCompat="@drawable/ic_sync" />
<TextView
android:id="@+id/text_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:gravity="center"
android:text="What is new in this build?"
android:textColor="@color/walkthrough_text_header"
android:textSize="@dimen/text_size_h5"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/logo_welcome" />
<TextView
android:id="@+id/text_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:justificationMode="inter_word"
android:text=" • Everything"
android:textColor="@color/walkthrough_text_body"
app:layout_constraintEnd_toEndOf="@id/guideline_content_end"
app:layout_constraintStart_toStartOf="@+id/guideline_content_start"
app:layout_constraintTop_toBottomOf="@+id/text_header" />
<ProgressBar
android:id="@+id/progress_sync"
android:transitionName="@string/transition_walkthrough_progress_bar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="32dp"
app:layout_constraintBottom_toBottomOf="@+id/button_next"
app:layout_constraintEnd_toStartOf="@+id/button_next"
app:layout_constraintStart_toStartOf="@+id/guideline_content_start" />
<TextView
android:id="@+id/text_progress_sync"
android:transitionName="@string/transition_walkthrough_progress_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:lineSpacingExtra="12dp"
android:text="4% reticulating splines"
android:paddingEnd="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/guideline_content_start"
app:layout_constraintTop_toBottomOf="@+id/progress_sync" />
<Button
android:id="@+id/button_next"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="32dp"
android:background="@drawable/background_selector_primary_button"
android:enabled="false"
android:text="Loading..."
android:textColor="@color/walkthrough_button_text"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/guideline_content_end" />
<TextView
android:id="@+id/text_testnet_warning"
android:layout_width="0dp"
android:layout_height="70dp"
android:background="@drawable/background_rounded_corners_slight"
android:backgroundTint="@color/zcashBlueGray_dark"
android:drawableStart="@drawable/ic_warning"
android:drawablePadding="16dp"
android:drawableTint="@color/zcashYellow"
android:gravity="center_vertical"
android:paddingStart="16dp"
android:text="testnet only"
android:textAllCaps="true"
android:textColor="@color/text_light"
app:layout_constraintBottom_toTopOf="@+id/button_next"
app:layout_constraintEnd_toStartOf="@+id/guideline_content_end"
app:layout_constraintStart_toStartOf="@+id/guideline_content_start"
app:layout_constraintTop_toBottomOf="@+id/text_content"
app:layout_constraintVertical_bias="0.8" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="is_testnet">true</bool>
</resources>

View File

@ -49,7 +49,7 @@ buildscript {
'speeddial': 'com.leinardi.android:speed-dial:2.0.0',
'stetho': 'com.facebook.stetho:stetho:1.5.0',
'zcash': [
'walletSdk': "cash.z.android.wallet:zcash-android-wallet-sdk:1.6.0@aar"
'walletSdk': "cash.z.android.wallet:zcash-android-wallet-sdk:1.7.0@aar"
]
]
repositories {