New: Updated receive screen and scan screen.

Removed the buttons that allowed navigation between the two screens, which has the nice benefit of removing the second way that the user could enter the Send flow. Lastly, split the address back into 8 parts and did other UI cleanup on the receive screen.
This commit is contained in:
Kevin Gorham 2020-08-28 03:42:39 -04:00
parent 462e3e10d9
commit 25ffce866c
No known key found for this signature in database
GPG Key ID: CCA55602DF49FC38
5 changed files with 169 additions and 122 deletions

View File

@ -118,6 +118,7 @@ object Report {
LANDING_BACKUP_SKIPPED_3("landing.backup.skip.3"),
HOME_PROFILE("home.profile"),
HOME_HISTORY("home.history"),
HOME_RECEIVE("home.receive"),
HOME_SCAN("home.scan"),
HOME_SEND("home.send"),
HOME_FUND_NOW("home.fund.now"),
@ -130,12 +131,10 @@ object Report {
PROFILE_SEND_FEEDBACK("profile.send.feedback"),
FEEDBACK_CANCEL("feedback.cancel"),
FEEDBACK_SUBMIT("feedback.submit"),
RECEIVE_SCAN("receive.scan"),
RECEIVE_BACK("receive.back"),
RESTORE_DONE("restore.done"),
RESTORE_SUCCESS("restore.success"),
RESTORE_BACK("restore.back"),
SCAN_RECEIVE("scan.receive"),
SCAN_BACK("scan.back"),
SEND_ADDRESS_MAX("send.address.max"),
SEND_ADDRESS_NEXT("send.address.next"),

View File

@ -2,8 +2,11 @@ package cash.z.ecc.android.ui.receive
import android.content.Context
import android.os.Bundle
import android.text.SpannableString
import android.text.Spanned
import android.view.LayoutInflater
import android.view.View
import android.widget.TextView
import cash.z.android.qrecycler.QRecycler
import cash.z.ecc.android.R
import cash.z.ecc.android.databinding.FragmentReceiveNewBinding
@ -15,6 +18,7 @@ import cash.z.ecc.android.feedback.Report.Tap.*
import cash.z.ecc.android.ui.base.BaseFragment
import cash.z.ecc.android.sdk.ext.toAbbreviatedAddress
import cash.z.ecc.android.sdk.ext.twig
import cash.z.ecc.android.ui.util.AddressPartNumberSpan
import kotlinx.coroutines.launch
import kotlin.math.roundToInt
@ -25,26 +29,24 @@ class ReceiveFragment : BaseFragment<FragmentReceiveNewBinding>() {
lateinit var qrecycler: QRecycler
// lateinit var addressParts: Array<TextView>
lateinit var addressParts: Array<TextView>
override fun inflate(inflater: LayoutInflater): FragmentReceiveNewBinding =
FragmentReceiveNewBinding.inflate(inflater)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// addressParts = arrayOf(
// text_address_part_1,
// text_address_part_2,
// text_address_part_3,
// text_address_part_4,
// text_address_part_5,
// text_address_part_6,
// text_address_part_7,
// text_address_part_8
// )
binding.buttonScan.setOnClickListener {
mainActivity?.maybeOpenScan(R.id.action_nav_receive_to_nav_scan).also { tapped(RECEIVE_SCAN) }
}
addressParts = arrayOf(
binding.textAddressPart1,
binding.textAddressPart2,
binding.textAddressPart3,
binding.textAddressPart4,
binding.textAddressPart5,
binding.textAddressPart6,
binding.textAddressPart7,
binding.textAddressPart8
)
binding.backButtonHitArea.onClickNavBack() { tapped(RECEIVE_BACK) }
}
@ -67,11 +69,9 @@ class ReceiveFragment : BaseFragment<FragmentReceiveNewBinding>() {
.withCorrectionLevel(QRecycler.CorrectionLevel.MEDIUM)
.into(binding.receiveQrCode)
binding.receiveAddress.text = address.toAbbreviatedAddress(12, 12)
// address.distribute(8) { i, part ->
// setAddressPart(i, part)
// }
address.distribute(8) { i, part ->
setAddressPart(i, part)
}
}
private fun <T> String.distribute(chunks: Int, block: (Int, String) -> T) {
@ -88,13 +88,13 @@ class ReceiveFragment : BaseFragment<FragmentReceiveNewBinding>() {
}
}
// private fun setAddressPart(index: Int, addressPart: String) {
// Log.e("TWIG", "setting address for part $index) $addressPart")
// val thinSpace = "\u2005" // 0.25 em space
// val textSpan = SpannableString("${index + 1}$thinSpace$addressPart")
//
// textSpan.setSpan(AddressPartNumberSpan(), 0, 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
//
// addressParts[index].text = textSpan
// }
private fun setAddressPart(index: Int, addressPart: String) {
twig("setting address for part $index) $addressPart")
val thinSpace = "\u2005" // 0.25 em space
val textSpan = SpannableString("${index + 1}$thinSpace$addressPart")
textSpan.setSpan(AddressPartNumberSpan(), 0, 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
addressParts[index].text = textSpan
}
}

View File

@ -17,7 +17,6 @@ import cash.z.ecc.android.ext.onClickNavBack
import cash.z.ecc.android.ext.onClickNavTo
import cash.z.ecc.android.feedback.Report
import cash.z.ecc.android.feedback.Report.Tap.SCAN_BACK
import cash.z.ecc.android.feedback.Report.Tap.SCAN_RECEIVE
import cash.z.ecc.android.sdk.ext.ZcashSdk
import cash.z.ecc.android.sdk.ext.twig
import cash.z.ecc.android.ui.base.BaseFragment
@ -45,7 +44,6 @@ class ScanFragment : BaseFragment<FragmentScanBinding>() {
if (cameraExecutor != null) cameraExecutor?.shutdown()
cameraExecutor = Executors.newSingleThreadExecutor()
binding.buttonReceive.onClickNavTo(R.id.action_nav_scan_to_nav_receive) { tapped(SCAN_RECEIVE) }
binding.backButtonHitArea.onClickNavBack() { tapped(SCAN_BACK) }
}
@ -207,22 +205,6 @@ class ScanFragment : BaseFragment<FragmentScanBinding>() {
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (allPermissionsGranted()) {
// view!!.postDelayed(
// {
// onStartCamera()
// },
// 2000L
// ) // TODO: remove this temp hack to sidestep crash when permissions were not available
}
}
companion object {
private const val CAMERA_PERMISSION_REQUEST = 1002

View File

@ -90,19 +90,21 @@
android:layout_height="0dp"
android:onClick="copyAddress"
android:scaleType="fitCenter"
android:src="@drawable/ic_zcash_primary"
android:src="@drawable/ic_shield_address"
app:layout_constraintBottom_toBottomOf="@id/receive_qr_code"
app:layout_constraintDimensionRatio="H,1:1"
app:layout_constraintEnd_toEndOf="@id/receive_qr_code"
app:layout_constraintStart_toStartOf="@id/receive_qr_code"
app:layout_constraintTop_toTopOf="@id/receive_qr_code"
app:layout_constraintWidth_percent="0.14" />
app:layout_constraintWidth_percent="0.18" />
<TextView
android:id="@+id/receive_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Your Address"
android:text="@string/address_label_shielded"
android:drawableEnd="@drawable/ic_content_copy"
android:drawablePadding="16dp"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
android:textColor="@color/text_light"
android:textSize="20dp"
@ -110,67 +112,19 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/spacer_title" />
<TextView
android:id="@+id/receive_address"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/Zcash.TextAppearance.AddressPart"
android:textColor="@color/text_light"
android:textSize="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/receive_title"
tools:text="ztcs23cs...zt249skf" />
<ImageView
android:id="@+id/icon_copy"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginStart="16dp"
android:onClick="copyAddress"
android:scaleType="fitCenter"
android:src="@drawable/ic_content_copy"
app:layout_constraintBottom_toBottomOf="@id/receive_address"
app:layout_constraintStart_toEndOf="@id/receive_address"
app:layout_constraintTop_toTopOf="@id/receive_address" />
<Space
android:id="@+id/space_address_median"
android:layout_width="1dp"
android:layout_height="1dp"
app:layout_constraintTop_toBottomOf="@id/receive_address"
app:layout_constraintBottom_toTopOf="@id/button_scan"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintVertical_bias="0.4"/>
<View
android:id="@+id/hit_area_address"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="24dp"
android:onClick="copyAddress"
app:layout_constraintStart_toStartOf="@id/receive_address"
app:layout_constraintStart_toStartOf="@id/background_qr"
app:layout_constraintEnd_toEndOf="@id/background_qr"
app:layout_constraintTop_toTopOf="@id/receive_title"
app:layout_constraintBottom_toTopOf="@id/space_address_median"
app:layout_constraintTop_toBottomOf="@id/background_qr"
app:layout_constraintBottom_toBottomOf="@id/receive_address_parts"
tools:background="@color/spacer" />
<com.google.android.material.button.MaterialButton
android:id="@+id/button_scan"
android:layout_width="0dp"
android:layout_height="wrap_content"
style="@style/Zcash.Button"
android:gravity="center"
android:padding="12dp"
android:text="Scan Recipient Address"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
android:textColor="#000000"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/spacer_bottom_right"
app:layout_constraintStart_toEndOf="@id/spacer_bottom_left"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.9226" />
<!-- Back Button -->
<ImageView
android:id="@+id/back_button"
@ -197,4 +151,133 @@
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.045" />
<TextView
android:id="@+id/text_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
style="@style/TextAppearance.MaterialComponents.Headline6"
android:autoSizeTextType="uniform"
android:maxLines="1"
android:text="@string/receive_address_title"
android:textColor="@color/text_light"
app:layout_constraintBottom_toBottomOf="@id/back_button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/back_button_hit_area"
app:layout_constraintTop_toTopOf="@id/back_button" />
<!-- Address parts -->
<!-- Someday, there will be an advanced VirtualLayout that helps us do this without nesting but for now, this seems to be the only clean way to center all the fields -->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/receive_address_parts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:foregroundGravity="center"
android:padding="16dp"
app:layout_constraintEnd_toEndOf="@id/receive_title"
app:layout_constraintStart_toStartOf="@id/receive_title"
app:layout_constraintTop_toBottomOf="@id/receive_title">
<TextView
android:id="@+id/text_address_part_1"
style="@style/Zcash.TextAppearance.AddressPart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" ztestsaplin"
app:layout_constraintBottom_toTopOf="@+id/text_address_part_3"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
app:layout_constraintVertical_chainStyle="packed" />
<TextView
android:id="@+id/text_address_part_3"
style="@style/Zcash.TextAppearance.AddressPart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text=" jceuu9s2p6t"
app:layout_constraintBottom_toTopOf="@+id/text_address_part_5"
app:layout_constraintStart_toStartOf="@id/text_address_part_1"
app:layout_constraintTop_toBottomOf="@id/text_address_part_1" />
<TextView
android:id="@+id/text_address_part_5"
style="@style/Zcash.TextAppearance.AddressPart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text=" 7u7uarqls7d"
app:layout_constraintBottom_toTopOf="@+id/text_address_part_7"
app:layout_constraintStart_toStartOf="@id/text_address_part_1"
app:layout_constraintTop_toBottomOf="@id/text_address_part_3" />
<TextView
android:id="@+id/text_address_part_7"
style="@style/Zcash.TextAppearance.AddressPart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text=" rzq85xggu56"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="@id/text_address_part_1"
app:layout_constraintTop_toBottomOf="@id/text_address_part_5" />
<TextView
android:id="@+id/text_address_part_2"
style="@style/Zcash.TextAppearance.AddressPart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:text=" g1mwjzlg62j"
app:layout_constraintBottom_toTopOf="@+id/text_address_part_4"
app:layout_constraintStart_toEndOf="@id/barrier_left_address_column"
app:layout_constraintTop_toTopOf="@id/text_address_part_1" />
<TextView
android:id="@+id/text_address_part_4"
style="@style/Zcash.TextAppearance.AddressPart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text=" wns6qxwec6v"
app:layout_constraintBottom_toTopOf="@+id/text_address_part_6"
app:layout_constraintStart_toStartOf="@id/text_address_part_2"
app:layout_constraintTop_toBottomOf="@id/text_address_part_2" />
<TextView
android:id="@+id/text_address_part_6"
style="@style/Zcash.TextAppearance.AddressPart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text=" gtg3tpgqxjd"
app:layout_constraintBottom_toTopOf="@+id/text_address_part_8"
app:layout_constraintStart_toStartOf="@id/text_address_part_2"
app:layout_constraintTop_toBottomOf="@id/text_address_part_4" />
<TextView
android:id="@+id/text_address_part_8"
style="@style/Zcash.TextAppearance.AddressPart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text=" k904xderng6"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="@id/text_address_part_2"
app:layout_constraintTop_toBottomOf="@id/text_address_part_6" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier_left_address_column"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="150dp"
android:layout_marginRight="150dp"
android:padding="150dp"
app:barrierDirection="end"
app:constraint_referenced_ids="text_address_part_1,text_address_part_3,text_address_part_5,text_address_part_7" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -154,6 +154,7 @@
android:id="@+id/text_scan_error"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="32dp"
android:fontFamily="@font/inconsolata"
android:gravity="center"
android:textColor="@color/text_light_dimmed"
@ -161,29 +162,11 @@
android:ellipsize="end"
android:paddingBottom="16dp"
android:paddingTop="8dp"
app:layout_constraintBottom_toTopOf="@id/button_receive"
app:layout_constraintEnd_toEndOf="@id/scan_frame"
app:layout_constraintStart_toStartOf="@id/scan_frame"
app:layout_constraintTop_toBottomOf="@id/scan_frame"
tools:text="invalid:\nz98yz9uhz98uyz988yz98hzu8hgziouzgi9uzg9z8uogozuz z98yz9uhz98uyz988yz98hzu8hgziouzgi9uzg9z8uogozuzz98yz9uhz98uyz988yz98hzu8hgziouzgi9uzg9z8uogozuzz98yz9uhz98uyz988yz98hzu8hgziouzgi9uzg9z8uogozuzz98yz9uhz98uyz988yz98hzu8hgziouzgi9uzg9z8uogozuzz98yz9uhz98uyz988yz98hzu8hgziouzgi9uzg9z8uogozuzz98yz9uhz98uyz988yz98hzu8hgziouzgi9uzg9z8uogozuz" />
<com.google.android.material.button.MaterialButton
android:id="@+id/button_receive"
android:layout_width="0dp"
android:layout_height="0dp"
style="@style/Zcash.Button.White"
android:gravity="center"
android:padding="12dp"
android:text="Switch to Your Address"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
android:textColor="#000000"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/spacer_bottom_right"
app:layout_constraintHeight_percent="0.2"
app:layout_constraintStart_toEndOf="@id/spacer_bottom_left"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.9226" />
<ImageView
android:id="@+id/back_button"
android:layout_width="wrap_content"
@ -216,7 +199,7 @@
style="@style/TextAppearance.MaterialComponents.Headline6"
android:autoSizeTextType="uniform"
android:maxLines="1"
android:text="Scan Recipient Address"
android:text="@string/scan_address_title"
android:textColor="@color/text_light"
app:layout_constraintBottom_toBottomOf="@id/back_button"
app:layout_constraintEnd_toEndOf="parent"