Primary transaction is functional

This commit is contained in:
Kevin Gorham 2019-02-03 20:27:54 -05:00 committed by Kevin Gorham
parent ecf69cb338
commit 9a45b5e242
7 changed files with 115 additions and 43 deletions

View File

@ -57,8 +57,8 @@ internal object SynchronizerModule {
@JvmStatic
@Provides
@Singleton
fun provideManager(): ActiveTransactionManager {
return ActiveTransactionManager()
fun provideManager(twigger: Twig): ActiveTransactionManager {
return ActiveTransactionManager(twigger)
}
@JvmStatic
@ -83,10 +83,10 @@ internal object SynchronizerModule {
}
// TODO: load this stuff in, later
// 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.2.2"
// 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"

View File

@ -94,7 +94,7 @@ class MainActivity : BaseActivity() {
* A simple flag that helps with removing shortcuts in the code used during development.
* TODO: either elevate this to a real thing (based off a system property or some such) or delete it!
*/
const val DEV_MODE = true
const val DEV_MODE = false
// TODO: placeholder until we have a network service for this
const val USD_PER_ZEC = 49.07

View File

@ -9,7 +9,6 @@ import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.AccelerateDecelerateInterpolator
import android.view.animation.AccelerateInterpolator
import androidx.annotation.ColorRes
import androidx.annotation.DrawableRes
@ -17,12 +16,9 @@ import androidx.annotation.IdRes
import androidx.annotation.StringRes
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.transition.ChangeBounds
import androidx.transition.Transition
import androidx.transition.TransitionInflater
import androidx.transition.TransitionSet
import cash.z.android.wallet.R
import cash.z.android.wallet.extention.Toaster
import cash.z.android.wallet.extention.toAppColor
import cash.z.android.wallet.extention.toAppString
import cash.z.android.wallet.extention.tryIgnore
@ -32,6 +28,8 @@ import cash.z.android.wallet.ui.presenter.HomePresenter
import cash.z.android.wallet.ui.util.AlternatingRowColorDecoration
import cash.z.android.wallet.ui.util.TopAlignedSpan
import cash.z.android.wallet.vo.WalletTransaction
import cash.z.wallet.sdk.data.ActiveTransaction
import cash.z.wallet.sdk.data.TransactionState
import com.leinardi.android.speeddial.SpeedDialActionItem
import dagger.Module
import dagger.android.ContributesAndroidInjector
@ -51,7 +49,7 @@ class HomeFragment : BaseFragment(), HomePresenter.HomeView {
lateinit var homePresenter: HomePresenter
lateinit var transactionAdapter: TransactionAdapter
var viewsInitialized = false
private var viewsInitialized = false
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
@ -67,25 +65,7 @@ class HomeFragment : BaseFragment(), HomePresenter.HomeView {
val enterTransitionSet =
TransitionInflater.from(mainActivity).inflateTransition(R.transition.transition_zec_sent).apply {
duration = 300L
}.addListener(object : Transition.TransitionListener {
override fun onTransitionEnd(transition: Transition) {
// 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
}
override fun onTransitionResume(transition: Transition) {
}
override fun onTransitionPause(transition: Transition) {
}
override fun onTransitionCancel(transition: Transition) {
}
override fun onTransitionStart(transition: Transition) {
}
})
}.addListener(HomeTransitionListener())
this.sharedElementEnterTransition = enterTransitionSet
this.sharedElementReturnTransition = enterTransitionSet
@ -93,6 +73,8 @@ class HomeFragment : BaseFragment(), HomePresenter.HomeView {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// setActiveTransactionsShown(false)
(activity as MainActivity).let { mainActivity ->
mainActivity.setSupportActionBar(home_toolbar)
mainActivity.setupNavigation()
@ -195,6 +177,57 @@ class HomeFragment : BaseFragment(), HomePresenter.HomeView {
}
}
override fun setActiveTransactions(activeTransactionMap: Map<ActiveTransaction, TransactionState>) {
if (activeTransactionMap.isEmpty()) {
setActiveTransactionsShown(false)
return
}
setActiveTransactionsShown(true)
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
}
private fun updatePrimaryTransaction(transaction: ActiveTransaction, transactionState: TransactionState) {
var title = "Active Transaction"
var subtitle = "Processing..."
when (transactionState) {
TransactionState.Creating -> {
title = "Preparing ${transaction.value} ZEC"
subtitle = "to ********"
button_active_transaction_cancel.text = "cancel"
}
TransactionState.SendingToNetwork -> {
title = "Sending Transaction"
subtitle = "to ********"
button_active_transaction_cancel.text = "${transaction.value/1000L}"
}
is TransactionState.Failure -> {
title = "Failed"
subtitle = when(transactionState.failedStep) {
TransactionState.Creating -> "Failed to create transaction"
TransactionState.SendingToNetwork -> "Failed to submit transaction to the network"
else -> "Unrecoginzed error"
}
button_active_transaction_cancel.visibility = View.GONE
onCancelActiveTransaction()
}
is TransactionState.AwaitingConfirmations -> {
title = "ZEC Sent"
subtitle = "Awaiting Confirmations (${transactionState.confirmationCount}/10)"
}
}
text_active_transaction_title.text = title
text_active_transaction_subtitle.text = subtitle
}
private fun setActiveTransactionsShown(isShown: Boolean) {
header_active_transaction.visibility = if (isShown) View.VISIBLE else View.GONE
}
//
// Private View API
@ -265,6 +298,15 @@ class HomeFragment : BaseFragment(), HomePresenter.HomeView {
}
}
private fun onActiveTransactionTransitionStart() {
}
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
}
private fun onCancelActiveTransaction() {
button_active_transaction_cancel.isEnabled = false
button_active_transaction_cancel.text = "canceled"
@ -292,6 +334,18 @@ class HomeFragment : BaseFragment(), HomePresenter.HomeView {
homePresenter.onCancelActiveTransaction()
}
inner class HomeTransitionListener : Transition.TransitionListener {
override fun onTransitionStart(transition: Transition) {
onActiveTransactionTransitionStart()
}
override fun onTransitionEnd(transition: Transition) {
onActiveTransactionTransitionEnd()
}
override fun onTransitionResume(transition: Transition){}
override fun onTransitionPause(transition: Transition){}
override fun onTransitionCancel(transition: Transition) {}
}
/**
* Defines the basic properties of each FAB button for use while initializing the FAB
*/

View File

@ -11,8 +11,6 @@ import android.view.ViewGroup
import androidx.core.text.toSpannable
import androidx.databinding.DataBindingUtil
import androidx.navigation.fragment.FragmentNavigatorExtras
import androidx.transition.Fade
import androidx.transition.Transition
import androidx.transition.TransitionInflater
import cash.z.android.wallet.R
import cash.z.android.wallet.databinding.FragmentSendBinding
@ -23,7 +21,6 @@ import cash.z.android.wallet.ui.activity.MainActivity
import cash.z.android.wallet.ui.presenter.SendPresenter
import dagger.Module
import dagger.android.ContributesAndroidInjector
import kotlinx.android.synthetic.main.include_home_content.*
import kotlinx.coroutines.launch
import java.text.DecimalFormat
@ -106,7 +103,7 @@ class SendFragment : BaseFragment(), SendPresenter.SendView {
hideSendDialog()
}
binding.dialogSubmitButton.setOnClickListener {
sendPresenter.onDialogConfirm()
if (MainActivity.DEV_MODE) submit() else onSendZec()
}
}

View File

@ -7,7 +7,9 @@ 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
@ -27,11 +29,13 @@ class HomePresenter(
fun setTransactions(transactions: List<WalletTransaction>)
fun updateBalance(old: Long, new: Long)
fun showProgress(progress: Int)
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!")
@ -39,6 +43,7 @@ class HomePresenter(
balanceJob = launchBalanceBinder(synchronizer.repository.balance())
transactionJob = launchTransactionBinder(synchronizer.repository.allTransactions())
progressJob = launchProgressMonitor(synchronizer.downloader.progress())
activeTransactionJob = launchActiveTransactionMonitor(synchronizer.activeTransactions())
}
}
@ -49,6 +54,7 @@ class HomePresenter(
balanceJob?.cancel()?.also { balanceJob = null }
transactionJob?.cancel()?.also { transactionJob = null }
progressJob?.cancel()?.also { progressJob = null }
activeTransactionJob?.cancel()?.also { progressJob = null }
}
fun CoroutineScope.launchBalanceBinder(channel: ReceiveChannel<Long>) = launch {
@ -82,17 +88,25 @@ class HomePresenter(
Log.e("@TWIG", "progress monitor exiting!")
}
fun bind(old: Long?, new: Long) {
fun CoroutineScope.launchActiveTransactionMonitor(channel: ReceiveChannel<Map<ActiveTransaction, TransactionState>>) = launch {
Log.e("@TWIG-v", "active transaction monitor starting!")
for (i in channel) {
bind(i)
}
Log.e("@TWIG-v", "active transaction monitor exiting!")
}
private fun bind(old: Long?, new: Long) {
Log.e("@TWIG-t", "binding balance of $new")
view.updateBalance(old ?: 0L, new)
}
fun bind(transactions: List<WalletTransaction>) {
private fun bind(transactions: List<WalletTransaction>) {
Log.e("@TWIG-t", "binding ${transactions.size} walletTransactions")
view.setTransactions(transactions)
}
fun bind(progress: Int) {
private fun bind(progress: Int) {
view.showProgress(progress)
if(progress == 100) {
view.launch {
@ -103,6 +117,12 @@ class HomePresenter(
}
}
private fun bind(activeTransactionMap: Map<ActiveTransaction, TransactionState>) {
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!")
@ -115,5 +135,6 @@ class HomePresenter(
return WalletTransaction(height, if (sent) SENT else RECEIVED, timestamp, BigDecimal(value / 1e8))
}
}

View File

@ -5,6 +5,7 @@ import cash.z.android.wallet.ui.presenter.Presenter.PresenterView
import cash.z.wallet.sdk.data.Synchronizer
import cash.z.wallet.sdk.vo.Transaction
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.channels.ReceiveChannel
import kotlinx.coroutines.launch
@ -22,13 +23,14 @@ class SendPresenter(
private var balanceJob: Job? = null
override suspend fun start() {
Log.e("@TWIG-v", "homePresenter starting!")
Log.e("@TWIG-v", "sendPresenter starting!")
with(view) {
balanceJob = launchBalanceBinder(synchronizer.repository.balance())
}
}
override fun stop() {
Log.e("@TWIG-v", "sendPresenter stopping!")
balanceJob?.cancel()?.also { balanceJob = null }
}
@ -43,14 +45,12 @@ class SendPresenter(
}
fun sendToAddress(value: Double, toAddress: String) {
view.launch {
//TODO: prehaps grab the activity scope or let the sycnchronizer have scope and make that function not suspend
// also, we need to handle cancellations. So yeah, definitely do this differently
GlobalScope.launch {
val zatoshi = Math.round(value * 1e8)
synchronizer.sendToAddress(zatoshi, toAddress)
// TOOD: already be subscribed to active transactions channel!
}
}
fun onDialogConfirm() {
view.submit()
}