Fix: Iterated on send flow from last sprint.
Addressed most design feedback from this list https://github.com/zcash/zcash-android-wallet/issues/113\#issuecomment-676622252
This commit is contained in:
parent
cf1c035c78
commit
5b02f188f6
|
@ -7,9 +7,9 @@ import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.EditText
|
import android.widget.EditText
|
||||||
import androidx.biometric.BiometricConstants.*
|
import android.widget.ImageView
|
||||||
import androidx.biometric.BiometricPrompt
|
import android.widget.TextView
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.constraintlayout.widget.Group
|
||||||
import androidx.core.view.isGone
|
import androidx.core.view.isGone
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.core.widget.ImageViewCompat
|
import androidx.core.widget.ImageViewCompat
|
||||||
|
@ -28,7 +28,6 @@ import cash.z.ecc.android.ui.base.BaseFragment
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.util.concurrent.Executor
|
|
||||||
|
|
||||||
class SendFragment : BaseFragment<FragmentSendBinding>(),
|
class SendFragment : BaseFragment<FragmentSendBinding>(),
|
||||||
ClipboardManager.OnPrimaryClipChangedListener {
|
ClipboardManager.OnPrimaryClipChangedListener {
|
||||||
|
@ -137,7 +136,9 @@ class SendFragment : BaseFragment<FragmentSendBinding>(),
|
||||||
|
|
||||||
private fun onAddressChanged(address: String) {
|
private fun onAddressChanged(address: String) {
|
||||||
resumedScope.launch {
|
resumedScope.launch {
|
||||||
var type = when (sendViewModel.validateAddress(address)) {
|
val validation = sendViewModel.validateAddress(address)
|
||||||
|
binding.buttonSend.isActivated = !validation.isNotValid
|
||||||
|
var type = when (validation) {
|
||||||
is AddressType.Transparent -> "This is a valid transparent address" to R.color.zcashGreen
|
is AddressType.Transparent -> "This is a valid transparent address" to R.color.zcashGreen
|
||||||
is AddressType.Shielded -> "This is a valid shielded address" to R.color.zcashGreen
|
is AddressType.Shielded -> "This is a valid shielded address" to R.color.zcashGreen
|
||||||
is AddressType.Invalid -> "This address appears to be invalid" to R.color.zcashRed
|
is AddressType.Invalid -> "This address appears to be invalid" to R.color.zcashRed
|
||||||
|
@ -178,7 +179,7 @@ class SendFragment : BaseFragment<FragmentSendBinding>(),
|
||||||
} else {
|
} else {
|
||||||
resumedScope.launch {
|
resumedScope.launch {
|
||||||
binding.textAddressError.text = errorMessage
|
binding.textAddressError.text = errorMessage
|
||||||
delay(1500L)
|
delay(2500L)
|
||||||
binding.textAddressError.text = ""
|
binding.textAddressError.text = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -234,28 +235,60 @@ class SendFragment : BaseFragment<FragmentSendBinding>(),
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateClipboardBanner(selected: Boolean = false, address: String? = loadAddressFromClipboard()) {
|
private fun updateClipboardBanner(selected: Boolean = false, address: String? = loadAddressFromClipboard()) {
|
||||||
if (address == null) {
|
binding.apply {
|
||||||
binding.groupClipboard.gone()
|
updateAddressBanner(
|
||||||
} else {
|
groupClipboard,
|
||||||
binding.groupClipboard.visible()
|
clipboardAddress,
|
||||||
binding.clipboardAddress.text = address.toAbbreviatedAddress(16, 16)
|
imageClipboardAddressSelected,
|
||||||
binding.imageClipboardAddressSelected.goneIf(!selected)
|
imageShield,
|
||||||
ImageViewCompat.setImageTintList(binding.imageShield, ColorStateList.valueOf(if (selected) R.color.colorPrimary.toAppColor() else R.color.zcashWhite_12.toAppColor()))
|
clipboardAddressLabel,
|
||||||
binding.clipboardAddressLabel.setTextColor(if(selected) R.color.colorPrimary.toAppColor() else R.color.text_light.toAppColor())
|
selected,
|
||||||
binding.clipboardAddress.setTextColor(if(selected) R.color.text_light.toAppColor() else R.color.text_light_dimmed.toAppColor())
|
address
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
// binding.dividerClipboard.text = "On Clipboard"
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateLastUsedBanner(selected: Boolean = false, address: String? = loadLastUsedAddress()) {
|
private fun updateLastUsedBanner(
|
||||||
if (address == null || address == loadAddressFromClipboard()) {
|
selected: Boolean = false,
|
||||||
binding.groupLastUsed.gone()
|
address: String? = loadLastUsedAddress()
|
||||||
} else {
|
) {
|
||||||
binding.groupLastUsed.visible()
|
val isBoth = address == loadAddressFromClipboard()
|
||||||
binding.lastUsedAddress.text = address.toAbbreviatedAddress(16, 16)
|
binding.apply {
|
||||||
binding.imageLastUsedAddressSelected.goneIf(!selected)
|
updateAddressBanner(
|
||||||
ImageViewCompat.setImageTintList(binding.imageLastUsedShield, ColorStateList.valueOf(if (selected) R.color.colorPrimary.toAppColor() else R.color.zcashWhite_12.toAppColor()))
|
groupLastUsed,
|
||||||
binding.lastUsedAddressLabel.setTextColor(if(selected) R.color.colorPrimary.toAppColor() else R.color.text_light.toAppColor())
|
lastUsedAddress,
|
||||||
binding.lastUsedAddress.setTextColor(if(selected) R.color.text_light.toAppColor() else R.color.text_light_dimmed.toAppColor())
|
imageLastUsedAddressSelected,
|
||||||
|
imageLastUsedShield,
|
||||||
|
lastUsedAddressLabel,
|
||||||
|
selected,
|
||||||
|
address.takeUnless { isBoth })
|
||||||
|
}
|
||||||
|
binding.dividerClipboard.text = if (isBoth) "Last Used and On Clipboard" else "On Clipboard"
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateAddressBanner(
|
||||||
|
group: Group,
|
||||||
|
addressTextView: TextView,
|
||||||
|
checkIcon: ImageView,
|
||||||
|
shieldIcon: ImageView,
|
||||||
|
addressLabel: TextView,
|
||||||
|
selected: Boolean = false,
|
||||||
|
address: String? = loadLastUsedAddress()
|
||||||
|
) {
|
||||||
|
resumedScope.launch {
|
||||||
|
if (address == null) {
|
||||||
|
group.gone()
|
||||||
|
} else {
|
||||||
|
val userAddress = sendViewModel.synchronizer.getAddress()
|
||||||
|
group.visible()
|
||||||
|
addressTextView.text = address.toAbbreviatedAddress(16, 16)
|
||||||
|
checkIcon.goneIf(!selected)
|
||||||
|
ImageViewCompat.setImageTintList(shieldIcon, ColorStateList.valueOf(if (selected) R.color.colorPrimary.toAppColor() else R.color.zcashWhite_12.toAppColor()))
|
||||||
|
addressLabel.setText(if (address == userAddress) R.string.send_banner_address_user else R.string.send_banner_address_unknown)
|
||||||
|
addressLabel.setTextColor(if(selected) R.color.colorPrimary.toAppColor() else R.color.text_light.toAppColor())
|
||||||
|
addressTextView.setTextColor(if(selected) R.color.text_light.toAppColor() else R.color.text_light_dimmed.toAppColor())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<item android:state_enabled="false" android:color="#7C5A00" />
|
||||||
|
<item android:state_activated="false" android:color="#7C5A00"/>
|
||||||
|
|
||||||
|
<item android:state_activated="true" android:color="@color/colorPrimary" />
|
||||||
|
</selector>
|
|
@ -131,6 +131,7 @@
|
||||||
android:layout_height="38dp"
|
android:layout_height="38dp"
|
||||||
android:text="Send"
|
android:text="Send"
|
||||||
android:textColor="@color/text_dark"
|
android:textColor="@color/text_dark"
|
||||||
|
android:backgroundTint="@color/selector_primary_button_activatable"
|
||||||
app:layout_constraintBottom_toBottomOf="@id/back_button"
|
app:layout_constraintBottom_toBottomOf="@id/back_button"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintHorizontal_bias="0.95"
|
app:layout_constraintHorizontal_bias="0.95"
|
||||||
|
@ -170,6 +171,16 @@
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:id="@+id/spacer_lower_content"
|
||||||
|
android:layout_width="1dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintHeight_percent="0.04"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/check_include_address" />
|
||||||
|
|
||||||
<!-- Input: Address -->
|
<!-- Input: Address -->
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:id="@+id/text_layout_address"
|
android:id="@+id/text_layout_address"
|
||||||
|
@ -177,7 +188,7 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:hint="To"
|
android:hint="To"
|
||||||
android:theme="@style/Zcash.Overlay.TextInputLayout"
|
android:theme="@style/Zcash.Overlay.TextInputLayout"
|
||||||
app:endIconDrawable="@drawable/ic_qrcode_24dp"
|
app:endIconDrawable="@drawable/ic_qr_scan"
|
||||||
app:endIconMode="custom"
|
app:endIconMode="custom"
|
||||||
app:helperText="Enter a valid Zcash address"
|
app:helperText="Enter a valid Zcash address"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
@ -220,7 +231,7 @@
|
||||||
android:background="@android:color/transparent"
|
android:background="@android:color/transparent"
|
||||||
android:imeActionLabel="add memo"
|
android:imeActionLabel="add memo"
|
||||||
android:imeOptions="actionDone"
|
android:imeOptions="actionDone"
|
||||||
android:inputType="textMultiLine"
|
android:inputType="textMultiLine|textNoSuggestions"
|
||||||
android:maxLength="512"
|
android:maxLength="512"
|
||||||
android:maxLines="3"
|
android:maxLines="3"
|
||||||
android:textColor="@color/text_light"
|
android:textColor="@color/text_light"
|
||||||
|
@ -293,7 +304,7 @@
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintHorizontal_bias="0.08"
|
app:layout_constraintHorizontal_bias="0.08"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/check_include_address" />
|
app:layout_constraintTop_toBottomOf="@id/spacer_lower_content" />
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:id="@+id/container_clipboard"
|
android:id="@+id/container_clipboard"
|
||||||
|
@ -309,7 +320,7 @@
|
||||||
android:id="@+id/image_shield"
|
android:id="@+id/image_shield"
|
||||||
android:layout_width="16dp"
|
android:layout_width="16dp"
|
||||||
android:layout_height="16dp"
|
android:layout_height="16dp"
|
||||||
android:src="@drawable/ic_shield"
|
android:src="@drawable/ic_shielded"
|
||||||
android:tint="@color/colorPrimary"
|
android:tint="@color/colorPrimary"
|
||||||
app:layout_constraintBottom_toBottomOf="@id/clipboard_address_label"
|
app:layout_constraintBottom_toBottomOf="@id/clipboard_address_label"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
@ -343,9 +354,8 @@
|
||||||
android:id="@+id/image_clipboard_address_selected"
|
android:id="@+id/image_clipboard_address_selected"
|
||||||
android:layout_width="22dp"
|
android:layout_width="22dp"
|
||||||
android:layout_height="22dp"
|
android:layout_height="22dp"
|
||||||
android:src="@drawable/ic_baseline_done_24"
|
android:src="@drawable/ic_check_shielded"
|
||||||
android:tint="@color/colorPrimary"
|
android:tint="@color/colorPrimary"
|
||||||
android:visibility="gone"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintHorizontal_bias=".95"
|
app:layout_constraintHorizontal_bias=".95"
|
||||||
|
@ -393,7 +403,7 @@
|
||||||
android:id="@+id/image_last_used_shield"
|
android:id="@+id/image_last_used_shield"
|
||||||
android:layout_width="16dp"
|
android:layout_width="16dp"
|
||||||
android:layout_height="16dp"
|
android:layout_height="16dp"
|
||||||
android:src="@drawable/ic_shield"
|
android:src="@drawable/ic_shielded"
|
||||||
android:tint="@color/colorPrimary"
|
android:tint="@color/colorPrimary"
|
||||||
app:layout_constraintBottom_toBottomOf="@id/last_used_address_label"
|
app:layout_constraintBottom_toBottomOf="@id/last_used_address_label"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
@ -428,7 +438,7 @@
|
||||||
android:id="@+id/image_last_used_address_selected"
|
android:id="@+id/image_last_used_address_selected"
|
||||||
android:layout_width="22dp"
|
android:layout_width="22dp"
|
||||||
android:layout_height="22dp"
|
android:layout_height="22dp"
|
||||||
android:src="@drawable/ic_baseline_done_24"
|
android:src="@drawable/ic_check_shielded"
|
||||||
android:tint="@color/colorPrimary"
|
android:tint="@color/colorPrimary"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
|
Loading…
Reference in New Issue