checkpoint: stable non-mock release

This commit is contained in:
Kevin Gorham 2019-02-24 23:42:43 -05:00 committed by Kevin Gorham
parent 69e159ff2b
commit e2c454907d
10 changed files with 78 additions and 36 deletions

View File

@ -14,8 +14,8 @@ android {
applicationId "cash.z.android.wallet"
minSdkVersion buildConfig.minSdkVersion
targetSdkVersion buildConfig.targetSdkVersion
versionCode 17 // todo: change this to 1_00_04 format, once we graduate beyond zero for the major version number because leading zeros indicate on octal number.
versionName "0.4.9-alpha"
versionCode 18 // todo: change this to 1_00_04 format, once we graduate beyond zero for the major version number because leading zeros indicate on octal number.
versionName "0.5.0-alpha"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
multiDexEnabled true

View File

@ -41,8 +41,8 @@ internal object SynchronizerModule {
@JvmStatic
@Provides
@Singleton
fun provideRepository(application: ZcashWalletApplication, converter: JniConverter, twigger: Twig): TransactionRepository {
return PollingTransactionRepository(application, SampleProperties.wallet.dataDbName, 10_000L, converter, twigger)
fun provideRepository(application: ZcashWalletApplication, converter: JniConverter): TransactionRepository {
return PollingTransactionRepository(application, SampleProperties.wallet.dataDbName, 10_000L)
}
@JvmStatic
@ -52,7 +52,7 @@ internal object SynchronizerModule {
return Wallet(
context = application,
converter = converter,
dbDataPath = application.getDatabasePath(SampleProperties.wallet.dataDbName).absolutePath,
dataDbPath = application.getDatabasePath(SampleProperties.wallet.dataDbName).absolutePath,
paramDestinationDir = "${application.cacheDir.absolutePath}/params",
seedProvider = SampleProperties.wallet.seedProvider,
spendingKeyProvider = SampleProperties.wallet.spendingKeyProvider

View File

@ -13,15 +13,15 @@ internal fun Context.alert(
@StringRes messageResId: Int,
@StringRes positiveButtonResId: Int = android.R.string.ok,
@StringRes negativeButtonResId: Int = android.R.string.cancel,
positiveAction: () -> Unit = NO_ACTION,
negativeAction: () -> Unit = NO_ACTION
negativeAction: () -> Unit = NO_ACTION,
positiveAction: () -> Unit = NO_ACTION
) {
alert(
message = getString(messageResId),
positiveButtonResId = positiveButtonResId,
negativeButtonResId = negativeButtonResId,
positiveAction = positiveAction,
negativeAction = negativeAction
negativeAction = negativeAction,
positiveAction = positiveAction
)
}
@ -33,8 +33,8 @@ internal fun Context.alert(
message: String,
@StringRes positiveButtonResId: Int = android.R.string.ok,
@StringRes negativeButtonResId: Int = android.R.string.cancel,
positiveAction: (() -> Unit) = NO_ACTION,
negativeAction: (() -> Unit) = NO_ACTION
negativeAction: (() -> Unit) = NO_ACTION,
positiveAction: (() -> Unit) = NO_ACTION
) {
val builder = AlertDialog.Builder(this)
.setMessage(message)

View File

@ -8,8 +8,8 @@ object AliceWallet {
const val name = "test.reference.alice"
val seedProvider = SampleSeedProvider(name)
val spendingKeyProvider = SampleSpendingKeySharedPref(name)
const val cacheDbName = "testalice_cache_emulator4.db"
const val dataDbName = "testalice_data_emulator3.db"
const val cacheDbName = "testalice_cache_emulator7.db"
const val dataDbName = "testalice_data_emulator7.db"
const val defaultSendAddress = "ztestsapling1wcp9fu5d3q945nwwyqxtf0dtn6pv22hmjxa39z0034ap734mvxkqz8kug4r2u2df2keekcne322" // bob's address
}
@ -18,11 +18,31 @@ object BobWallet {
val seedProvider =
SampleSeedProvider(name)
val spendingKeyProvider = SampleSpendingKeySharedPref(name)
const val cacheDbName = "testbob_cache_pixel.db"
const val dataDbName = "testbob_data_pixel.db"
const val cacheDbName = "testbob_cache_pixel1.db"
const val dataDbName = "testbob_data_pixel1.db"
const val defaultSendAddress = "ztestsapling1yv696xtjn3jykdej2pqx0999eydvvyfphnw97ddk2h5luyedpqzud3r87aq0d7qna3jzjqqdcvw" // alice's address
}
object CarolWallet {
const val name = "test.reference.carol"
val seedProvider =
SampleSeedProvider(name)
val spendingKeyProvider = SampleSpendingKeySharedPref(name)
const val cacheDbName = "testcarol_cache1.db"
const val dataDbName = "testcarol_data1.db"
const val defaultSendAddress = "ztestsapling1jq4dz0uurs494g0n8nywuurhyy68d6g9na8th7muuvznlux3kmsyehl89xjtu0gx58u26f4xv3d" // dave's address
}
object DaveWallet {
const val name = "test.reference.dave"
val seedProvider =
SampleSeedProvider(name)
val spendingKeyProvider = SampleSpendingKeySharedPref(name)
const val cacheDbName = "testdave_cache.db"
const val dataDbName = "testdave_data.db"
const val defaultSendAddress = "ztestsapling1gl8rn5u3p0j9xk2vulre5fhe4rq58p4euzuxdqpgrlv7f0qxgtt2lkzd2gzqjnuhmj9yzmpp270" // carol's address
}
object MyWallet {
const val name = "mine"
val seedProvider =
@ -43,9 +63,9 @@ enum class Servers(val host: String) {
// TODO: load most of these properties in later, perhaps from settings
object SampleProperties {
val COMPACT_BLOCK_SERVER = Servers.WLAN.host
val COMPACT_BLOCK_SERVER = Servers.ZCASH_TESTNET.host
const val COMPACT_BLOCK_PORT = 9067
val wallet = AliceWallet
val wallet = DaveWallet
// TODO: placeholder until we have a network service for this
val USD_PER_ZEC = BigDecimal("49.07", MathContext.DECIMAL128)
}

View File

@ -44,14 +44,16 @@ class TransactionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
private val formatter = SimpleDateFormat("M/d h:mma", Locale.getDefault())
fun bind(tx: WalletTransaction) {
val isHistory = icon != null
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 transactionIcon = if (tx.isSend) R.drawable.ic_sent_transaction else R.drawable.ic_received_transaction
val zecAbsoluteValue = tx.value.absoluteValue.convertZatoshiToZec(3)
val zecAbsoluteValue = tx.value.absoluteValue.convertZatoshiToZec(6)
val toOrFrom = if (tx.isSend) "to" else "from"
val srcOrDestination = tx.address?.truncate() ?: "shielded mystery person"
timestamp.text = if (!tx.isMined || tx.timeInSeconds == 0L) "Pending" else (tx.timeInSeconds * 1000L).toRelativeTimeString() //formatter.format(tx.timeInSeconds * 1000)
timestamp.text = if (!tx.isMined || tx.timeInSeconds == 0L) "Pending"
else (if (isHistory) formatter.format(tx.timeInSeconds * 1000) else (tx.timeInSeconds * 1000L).toRelativeTimeString())
amount.text = "$sign$zecAbsoluteValue"
amount.setTextColor(amountColor.toAppColor())

View File

@ -122,7 +122,7 @@ class SendFragment : BaseFragment(), SendPresenter.SendView, ScanFragment.Barcod
binding.groupDialogSend.visibility = View.VISIBLE
}
override fun updateBalance(new: Long) {
override fun updateAvailableBalance(new: Long) {
// TODO: use a formatted string resource here
val availableTextSpan = "${new.convertZatoshiToZecString(8)} $zec Available".toSpannable()
availableTextSpan.setSpan(ForegroundColorSpan(R.color.colorPrimary.toAppColor()), availableTextSpan.length - "Available".length, availableTextSpan.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)

View File

@ -107,7 +107,8 @@ class WelcomeFragment : ProgressFragment(R.id.progress_welcome) {
mainActivity?.navController?.navigate(
destination,
null,
NavOptions.Builder().setPopUpTo(R.id.mobile_navigation, true).build(),
null,
// NavOptions.Builder().setPopUpTo(R.id.mobile_navigation, true).build(),
extras
)
}

View File

@ -6,6 +6,7 @@ import cash.z.android.wallet.ui.fragment.HomeFragment
import cash.z.android.wallet.ui.presenter.Presenter.PresenterView
import cash.z.wallet.sdk.dao.WalletTransaction
import cash.z.wallet.sdk.data.*
import cash.z.wallet.sdk.secure.Wallet
import dagger.Binds
import dagger.Module
import kotlinx.coroutines.CoroutineScope
@ -46,12 +47,12 @@ class HomePresenter @Inject constructor(
job?.cancel()?.also { job = null }
}
private fun CoroutineScope.launchBalanceBinder(channel: ReceiveChannel<Long>) = launch {
private fun CoroutineScope.launchBalanceBinder(channel: ReceiveChannel<Wallet.WalletBalance>) = launch {
var old: Long? = null
twig("balance binder starting!")
for (new in channel) {
twig("polled a balance item")
bind(old, new).also { old = new }
bind(old, new.total).also { old = new.total }
}
twig("balance binder exiting!")
}

View File

@ -7,9 +7,10 @@ import cash.z.android.wallet.sample.SampleProperties
import cash.z.android.wallet.ui.fragment.SendFragment
import cash.z.android.wallet.ui.presenter.Presenter.PresenterView
import cash.z.wallet.sdk.data.Synchronizer
import cash.z.wallet.sdk.data.twig
import cash.z.wallet.sdk.data.Twig
import cash.z.wallet.sdk.data.twig
import cash.z.wallet.sdk.ext.*
import cash.z.wallet.sdk.secure.Wallet
import dagger.Binds
import dagger.Module
import kotlinx.coroutines.CoroutineScope
@ -26,7 +27,7 @@ class SendPresenter @Inject constructor(
) : Presenter {
interface SendView : PresenterView {
fun updateBalance(new: Long)
fun updateAvailableBalance(new: Long)
fun setHeaders(isUsdSelected: Boolean, headerString: String, subheaderString: String)
fun setHeaderValue(usdString: String)
fun setSubheaderValue(usdString: String, isUsdSelected: Boolean)
@ -75,7 +76,7 @@ class SendPresenter @Inject constructor(
balanceJob?.cancel()?.also { balanceJob = null }
}
fun CoroutineScope.launchBalanceBinder(channel: ReceiveChannel<Long>) = launch {
fun CoroutineScope.launchBalanceBinder(channel: ReceiveChannel<Wallet.WalletBalance>) = launch {
twig("send balance binder starting!")
for (new in channel) {
twig("send polled a balance item")
@ -161,6 +162,8 @@ class SendPresenter @Inject constructor(
/**
* Called when the user has completed their update to the header value, typically on focus change.
*
* @return true when the given amount is parsable, positive and less than the available amount.
*/
fun inputHeaderUpdated(amountString: String): Boolean {
if (!validateAmount(amountString)) return false
@ -188,18 +191,33 @@ class SendPresenter @Inject constructor(
return true
}
/**
* Called when the user has updated the toAddress, typically on focus change.
*
* @return true when the given address' length and content are valid
*/
fun inputAddressUpdated(newAddress: String): Boolean {
if (!validateAddress(newAddress)) return false
updateModel(sendUiModel.copy(toAddress = newAddress))
return true
}
/**
* Called when the user has updated the memo field, typically after pressing the 'done' key.
*
* @return true when the given memo's content does not contain invalid characters
*/
fun inputMemoUpdated(newMemo: String): Boolean {
if (!validateMemo(newMemo)) return false
updateModel(sendUiModel.copy(memo = newMemo))
return true
}
/**
* Called after the user has pressed the send button and should be shown a confirmation dialog, next.
*
* @return true when all input fields contained valid data
*/
fun inputSendPressed(): Boolean {
// double sanity check. Make sure view and model agree and are each valid and if not, highlight the error.
if (!view.checkAllInput() || !validateAll()) return false
@ -215,12 +233,12 @@ class SendPresenter @Inject constructor(
return true
}
fun bind(newZatoshiBalance: Long) {
val available = newZatoshiBalance// - minersFee
fun bind(balanceInfo: Wallet.WalletBalance) {
val available = balanceInfo.available
if (available >= 0) {
twig("binding balance of $available")
view.updateBalance(available)
// updateModel(sendUiModel.copy(availableBalance = available))
view.updateAvailableBalance(available)
updateModel(sendUiModel.copy(availableBalance = available))
}
}
@ -317,12 +335,12 @@ class SendPresenter @Inject constructor(
view.setAmountError("Please specify a larger amount")
requiresValidation = true
false
// } else if (sendUiModel.availableBalance != null
// && zatoshiValue >= sendUiModel.availableBalance!!) {
// view.setAmountError("Exceeds available balance of " +
// "${sendUiModel.availableBalance.convertZatoshiToZecString(3)}")
// requiresValidation = true
// false
} else if (sendUiModel.availableBalance != null
&& zatoshiValue >= sendUiModel.availableBalance!!) {
view.setAmountError("Exceeds available balance of " +
"${sendUiModel.availableBalance.convertZatoshiToZecString(3)}")
requiresValidation = true
false
} else {
view.setAmountError(null)
true