[#562] Clean up the Send screen (#580)

- send screen simplified + UI changes
- confirmation screen removed (hold to confirm)
- test and snapshot tests modified accordingly
This commit is contained in:
Lukas Korba 2023-02-27 08:21:54 +01:00 committed by GitHub
parent c8d2355f9d
commit c686a74372
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 52 additions and 382 deletions

View File

@ -165,8 +165,6 @@
0D26AF2D299E8196005260EE /* DebugMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2F1C832809B606004E65FE /* DebugMenu.swift */; };
0D26AF2E299E8196005260EE /* MnemonicInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E153A5E2920CD5100112F41 /* MnemonicInterface.swift */; };
0D26AF2F299E8196005260EE /* PasteboardLiveKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E153A6429210B3B00112F41 /* PasteboardLiveKey.swift */; };
0D26AF30299E8196005260EE /* HoldToSendButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34E0AF0E28DEE4C70034CF37 /* HoldToSendButton.swift */; };
0D26AF31299E8196005260EE /* TransactionConfirmationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C165B92740403600592F76 /* TransactionConfirmationView.swift */; };
0D26AF32299E8196005260EE /* View+InnerShadow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DF2DC5327235E3E00FA31E2 /* View+InnerShadow.swift */; };
0D26AF33299E8196005260EE /* ZcashSDKEnvironmentInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E153A6D292167FF00112F41 /* ZcashSDKEnvironmentInterface.swift */; };
0D26AF34299E8196005260EE /* SecItemInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAFEB83280597B700199FC9 /* SecItemInterface.swift */; };
@ -322,12 +320,10 @@
3448CB3228E47666006ADEDB /* NotEnoughFreeSpaceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3448CB3128E47666006ADEDB /* NotEnoughFreeSpaceView.swift */; };
3448CB3728E485CB006ADEDB /* NotEnoughFeeSpaceSnapshots.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3448CB3628E485CB006ADEDB /* NotEnoughFeeSpaceSnapshots.swift */; };
346715A528E2027D0035F7C4 /* CheckCircleStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 346715A428E2027D0035F7C4 /* CheckCircleStore.swift */; };
346715A828E20FE40035F7C4 /* TransactionConfirmationSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 346715A728E20FE40035F7C4 /* TransactionConfirmationSnapshotTests.swift */; };
346D41E428DF0B8600963F36 /* CheckCircle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 346D41E328DF0B8600963F36 /* CheckCircle.swift */; };
34BF09092927C98000222134 /* Memo+toString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34BF09082927C98000222134 /* Memo+toString.swift */; };
34DA414728E4385800F8CC61 /* TransactionSendingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34DA414628E4385800F8CC61 /* TransactionSendingView.swift */; };
34DA414928E439CD00F8CC61 /* sendingTransaction.json in Resources */ = {isa = PBXBuildFile; fileRef = 34DA414828E439CD00F8CC61 /* sendingTransaction.json */; };
34E0AF0F28DEE4C70034CF37 /* HoldToSendButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34E0AF0E28DEE4C70034CF37 /* HoldToSendButton.swift */; };
34E0AF1128DEE5220034CF37 /* Wedge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34E0AF1028DEE5220034CF37 /* Wedge.swift */; };
34E5F2F328E46DB700C17E5F /* DiskSpaceChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34E5F2F228E46DB700C17E5F /* DiskSpaceChecker.swift */; };
34F682E529A75EB60022C079 /* WalletConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34F682E429A75EB60022C079 /* WalletConfig.swift */; };
@ -546,7 +542,6 @@
F9971A6C27680E1000A2DB75 /* WalletInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9971A6A27680E1000A2DB75 /* WalletInfoView.swift */; };
F9C165B4274031F600592F76 /* Bindings.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C165B3274031F600592F76 /* Bindings.swift */; };
F9C165BF2740403600592F76 /* SendFlowStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C165B72740403600592F76 /* SendFlowStore.swift */; };
F9C165C02740403600592F76 /* TransactionConfirmationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C165B92740403600592F76 /* TransactionConfirmationView.swift */; };
F9C165C22740403600592F76 /* CreateTransactionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C165BB2740403600592F76 /* CreateTransactionView.swift */; };
F9C165C42740403600592F76 /* TransactionSentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C165BD2740403600592F76 /* TransactionSentView.swift */; };
F9C165CB2741AB5D00592F76 /* SendFlowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C165CA2741AB5D00592F76 /* SendFlowView.swift */; };
@ -649,12 +644,10 @@
3448CB3128E47666006ADEDB /* NotEnoughFreeSpaceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotEnoughFreeSpaceView.swift; sourceTree = "<group>"; };
3448CB3628E485CB006ADEDB /* NotEnoughFeeSpaceSnapshots.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotEnoughFeeSpaceSnapshots.swift; sourceTree = "<group>"; };
346715A428E2027D0035F7C4 /* CheckCircleStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckCircleStore.swift; sourceTree = "<group>"; };
346715A728E20FE40035F7C4 /* TransactionConfirmationSnapshotTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionConfirmationSnapshotTests.swift; sourceTree = "<group>"; };
346D41E328DF0B8600963F36 /* CheckCircle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckCircle.swift; sourceTree = "<group>"; };
34BF09082927C98000222134 /* Memo+toString.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Memo+toString.swift"; sourceTree = "<group>"; };
34DA414628E4385800F8CC61 /* TransactionSendingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionSendingView.swift; sourceTree = "<group>"; };
34DA414828E439CD00F8CC61 /* sendingTransaction.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = sendingTransaction.json; sourceTree = "<group>"; };
34E0AF0E28DEE4C70034CF37 /* HoldToSendButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HoldToSendButton.swift; sourceTree = "<group>"; };
34E0AF1028DEE5220034CF37 /* Wedge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Wedge.swift; sourceTree = "<group>"; };
34E5F2F228E46DB700C17E5F /* DiskSpaceChecker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiskSpaceChecker.swift; sourceTree = "<group>"; };
34F682E429A75EB60022C079 /* WalletConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletConfig.swift; sourceTree = "<group>"; };
@ -862,7 +855,6 @@
F9971A6A27680E1000A2DB75 /* WalletInfoView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletInfoView.swift; sourceTree = "<group>"; };
F9C165B3274031F600592F76 /* Bindings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bindings.swift; sourceTree = "<group>"; };
F9C165B72740403600592F76 /* SendFlowStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SendFlowStore.swift; sourceTree = "<group>"; };
F9C165B92740403600592F76 /* TransactionConfirmationView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionConfirmationView.swift; sourceTree = "<group>"; };
F9C165BB2740403600592F76 /* CreateTransactionView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CreateTransactionView.swift; sourceTree = "<group>"; };
F9C165BD2740403600592F76 /* TransactionSentView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionSentView.swift; sourceTree = "<group>"; };
F9C165CA2741AB5D00592F76 /* SendFlowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendFlowView.swift; sourceTree = "<group>"; };
@ -1174,7 +1166,6 @@
346715A628E20FB30035F7C4 /* SendSnapshotTests */ = {
isa = PBXGroup;
children = (
346715A728E20FE40035F7C4 /* TransactionConfirmationSnapshotTests.swift */,
34429C6D28E703CD00F2B929 /* TransactionSendingSnapshotTests.swift */,
);
path = SendSnapshotTests;
@ -2144,8 +2135,6 @@
isa = PBXGroup;
children = (
F9C165BB2740403600592F76 /* CreateTransactionView.swift */,
34E0AF0E28DEE4C70034CF37 /* HoldToSendButton.swift */,
F9C165B92740403600592F76 /* TransactionConfirmationView.swift */,
9E5BF640281FD7B600BA3F17 /* TransactionFailedView.swift */,
34DA414628E4385800F8CC61 /* TransactionSendingView.swift */,
F9C165BD2740403600592F76 /* TransactionSentView.swift */,
@ -2705,8 +2694,6 @@
0D26AF2D299E8196005260EE /* DebugMenu.swift in Sources */,
0D26AF2E299E8196005260EE /* MnemonicInterface.swift in Sources */,
0D26AF2F299E8196005260EE /* PasteboardLiveKey.swift in Sources */,
0D26AF30299E8196005260EE /* HoldToSendButton.swift in Sources */,
0D26AF31299E8196005260EE /* TransactionConfirmationView.swift in Sources */,
0D26AF32299E8196005260EE /* View+InnerShadow.swift in Sources */,
0D26AF33299E8196005260EE /* ZcashSDKEnvironmentInterface.swift in Sources */,
0D26AF34299E8196005260EE /* SecItemInterface.swift in Sources */,
@ -2931,8 +2918,6 @@
9E2F1C842809B606004E65FE /* DebugMenu.swift in Sources */,
9E153A5F2920CE2700112F41 /* MnemonicInterface.swift in Sources */,
9E153A6729210B3B00112F41 /* PasteboardLiveKey.swift in Sources */,
34E0AF0F28DEE4C70034CF37 /* HoldToSendButton.swift in Sources */,
F9C165C02740403600592F76 /* TransactionConfirmationView.swift in Sources */,
0DF2DC5427235E3E00FA31E2 /* View+InnerShadow.swift in Sources */,
9E153A70292167FF00112F41 /* ZcashSDKEnvironmentInterface.swift in Sources */,
9EAFEB84280597B700199FC9 /* SecItemInterface.swift in Sources */,
@ -3031,7 +3016,6 @@
9E391132284644580073DD9A /* AppInitializationTests.swift in Sources */,
9E9ECC9928589E150099D5A2 /* RecoveryPhraseDisplaySnapshotTests.swift in Sources */,
9E391124283E4CAC0073DD9A /* ImportWalletTests.swift in Sources */,
346715A828E20FE40035F7C4 /* TransactionConfirmationSnapshotTests.swift in Sources */,
9E5BF63F2819542C00BA3F17 /* WalletEventsTests.swift in Sources */,
0D4E7A1B26B364180058B01E /* secantTests.swift in Sources */,
0DFE93E6272CB6F7000FCCA5 /* RecoveryPhraseValidationTests.swift in Sources */,

View File

@ -17,7 +17,6 @@ struct SendFlowReducer: ReducerProtocol {
struct State: Equatable {
enum Destination: Equatable {
case confirmation
case inProgress
case scanQR
case success
@ -81,7 +80,7 @@ struct SendFlowReducer: ReducerProtocol {
case onAppear
case onDisappear
case scan(ScanReducer.Action)
case sendConfirmationPressed
case sendPressed
case sendTransactionResult(Result<TransactionState, NSError>)
case synchronizerStateChanged(SDKSynchronizerState)
case transactionAddressInput(TransactionAddressTextFieldReducer.Action)
@ -136,20 +135,16 @@ struct SendFlowReducer: ReducerProtocol {
state.isSendingTransaction = false
return .none
case .updateDestination(.confirmation):
state.amount = Zatoshi(state.transactionAmountInputState.amount.data)
state.address = state.transactionAddressInputState.textFieldState.text.data
state.destination = .confirmation
return .none
case let .updateDestination(destination):
state.destination = destination
return .none
case .sendConfirmationPressed:
case .sendPressed:
guard !state.isSendingTransaction else {
return .none
}
state.amount = Zatoshi(state.transactionAmountInputState.amount.data)
state.address = state.transactionAddressInputState.textFieldState.text.data
do {
let storedWallet = try walletStorage.exportWallet()
@ -275,18 +270,6 @@ extension SendFlowViewStore {
)
}
var bindingForConfirmation: Binding<Bool> {
self.destinationBinding.map(
extract: {
$0 == .confirmation ||
$0 == .inProgress ||
$0 == .success ||
$0 == .failure
},
embed: { $0 ? SendFlowReducer.State.Destination.confirmation : nil }
)
}
var bindingForInProgress: Binding<Bool> {
self.destinationBinding.map(
extract: {
@ -294,7 +277,7 @@ extension SendFlowViewStore {
$0 == .success ||
$0 == .failure
},
embed: { $0 ? SendFlowReducer.State.Destination.inProgress : SendFlowReducer.State.Destination.confirmation }
embed: { $0 ? SendFlowReducer.State.Destination.inProgress : nil }
)
}

View File

@ -17,10 +17,8 @@ struct SendFlowView: View {
.onAppear { viewStore.send(.onAppear) }
.onDisappear { viewStore.send(.onDisappear) }
.navigationLinkEmpty(
isActive: viewStore.bindingForConfirmation,
destination: {
TransactionConfirmation(store: store)
}
isActive: viewStore.bindingForInProgress,
destination: { TransactionSendingView(viewStore: viewStore) }
)
.navigationLinkEmpty(
isActive: viewStore.bindingForScanQR,

View File

@ -10,74 +10,44 @@ struct CreateTransaction: View {
return WithViewStore(store) { viewStore in
VStack {
VStack(spacing: 0) {
Text("WalletBalance \(viewStore.shieldedBalance.data.total.decimalString()) ZEC")
Text("($\(viewStore.totalCurrencyBalance.decimalString()))")
Text("\(viewStore.shieldedBalance.data.total.decimalString()) ZEC Available")
Text("Aditional funds may be in transit")
.font(.system(size: 13))
.opacity(0.6)
}
.padding()
VStack {
TransactionAmountTextField(
store: store.scope(
state: \.transactionAmountInputState,
action: SendFlowReducer.Action.transactionAmountInput
)
TransactionAddressTextField(
store: store.scope(
state: \.transactionAddressInputState,
action: SendFlowReducer.Action.transactionAddressInput
)
if viewStore.isInvalidAmountFormat {
HStack {
Text("invalid amount")
.foregroundColor(.red)
Spacer()
}
} else if viewStore.isInsufficientFunds {
HStack {
Text("insufficient funds")
.foregroundColor(.red)
Spacer()
}
}
}
)
.padding()
VStack {
TransactionAddressTextField(
store: store.scope(
state: \.transactionAddressInputState,
action: SendFlowReducer.Action.transactionAddressInput
)
TransactionAmountTextField(
store: store.scope(
state: \.transactionAmountInputState,
action: SendFlowReducer.Action.transactionAmountInput
)
if viewStore.isInvalidAddressFormat {
HStack {
Text("invalid address")
.foregroundColor(.red)
Spacer()
}
}
}
)
.padding()
MultipleLineTextField(
store: store.memoStore(),
title: "Memo",
title: "Write a private message here",
titleAccessoryView: {}
)
.frame(height: 200)
.padding()
Button(
action: { viewStore.send(.updateDestination(.confirmation)) },
action: { viewStore.send(.sendPressed) },
label: { Text("Send") }
)
.activeButtonStyle
.frame(height: 50)
.padding()
.disabled(!viewStore.isValidForm)
Spacer()
}
@ -99,7 +69,7 @@ struct Create_Previews: PreviewProvider {
CreateTransaction(store: .placeholder)
}
.navigationBarTitleDisplayMode(.inline)
.preferredColorScheme(.dark)
.preferredColorScheme(.light)
}
}
}

View File

@ -1,114 +0,0 @@
//
// ZcashSendButton.swift
// wallet
//
// Created by Francisco Gindre on 1/9/20.
// Copyright © 2020 Francisco Gindre. All rights reserved.
//
import SwiftUI
import ComposableArchitecture
struct HoldToSendButton: View {
var minimumDuration: TimeInterval = 5
let innerCircleScale: CGFloat = 0.8
var completionStrokeWidth: CGFloat = 16.0
@State var isPressing = false
@State var startAngle: CGFloat = -90
@State var endAngle: CGFloat = -90
var longPressSucceded: () -> Void
var body: some View {
ZStack(alignment: .center) {
GeometryReader { geometry in
Circle()
.size(geometry.size)
.fill(Color.black)
.shadow(color: Asset.Colors.Shadow.holdToSendButtonShadow.color, radius: 2, x: 0, y: 2)
Circle()
.size(geometry.size)
.fill(Asset.Colors.Shadow.holdToSendButtonShadow.color)
.scaleEffect(self.innerCircleScale)
.opacity(0.35)
Wedge(
startAngle: self.startAngle,
endAngle: self.endAngle,
clockwise: false
)
.stroke(Asset.Colors.ProgressIndicator.holdToSendButton.color, lineWidth: self.completionStrokeWidth)
.frame(
width: geometry.size.width - self.completionStrokeWidth,
height: geometry.size.height - self.completionStrokeWidth
)
.offset(x: self.completionStrokeWidth / 2, y: self.completionStrokeWidth / 2)
Text("Press and hold\nto send ZEC")
.foregroundColor(.white)
.multilineTextAlignment(.center)
.frame(
minWidth: geometry.size.width,
idealWidth: geometry.size.width,
maxWidth: geometry.size.width,
minHeight: geometry.size.height,
idealHeight: geometry.size.height,
maxHeight: geometry.size.height,
alignment: .center
)
}
}
.frame(
width: 167,
height: 167,
alignment: .center
)
.onLongPressGesture(
minimumDuration: minimumDuration,
maximumDistance: 167,
pressing: { isPressing in
if !self.isPressing && isPressing {
self.isPressing = isPressing
withAnimation(.linear(duration: self.minimumDuration)) {
self.startAnimation()
}
} else if self.isPressing && !isPressing {
self.isPressing = isPressing
withAnimation(.easeOut(duration: 0.3)) {
self.cancelAnimation()
}
}
},
perform: {
self.endAnimation()
self.isPressing = false
longPressSucceded()
}
)
}
func startAnimation() {
self.startAngle = -90
self.endAngle = 270
}
func endAnimation() {
self.startAngle = -90
self.endAngle = 270
}
func cancelAnimation() {
self.startAngle = -90
self.endAngle = -90
}
}
struct HoldToSendButton_Previews: PreviewProvider {
static var previews: some View {
ZStack {
HoldToSendButton(longPressSucceded: { })
.applyDarkScreenBackground()
}
}
}

View File

@ -1,55 +0,0 @@
import SwiftUI
import ComposableArchitecture
struct TransactionConfirmation: View {
let store: SendFlowStore
var body: some View {
WithViewStore(store) { viewStore in
VStack {
Text("Send \(viewStore.amount.decimalString()) ZEC to")
.padding()
.foregroundColor(Asset.Colors.Text.forDarkBackground.color)
Text("\(viewStore.address)?")
.truncationMode(.middle)
.lineLimit(1)
.padding()
.foregroundColor(Asset.Colors.Text.forDarkBackground.color)
HStack {
CheckCircle(viewStore: ViewStore(store.addMemoStore()))
Text("Includes memo")
.foregroundColor(Asset.Colors.Text.forDarkBackground.color)
}
Spacer()
HoldToSendButton {
viewStore.send(.sendConfirmationPressed)
}
Spacer()
}
.applyDarkScreenBackground()
.navigationLinkEmpty(
isActive: viewStore.bindingForInProgress,
destination: { TransactionSendingView(viewStore: viewStore) }
)
}
}
}
// MARK: - Previews
struct Confirmation_Previews: PreviewProvider {
static var previews: some View {
NavigationView {
StateContainer(
initialState: (false)
) { _ in
TransactionConfirmation(store: .placeholder)
}
}
}
}

View File

@ -23,9 +23,9 @@
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xA0",
"green" : "0x81",
"red" : "0x6E"
"blue" : "0xFF",
"green" : "0xFF",
"red" : "0xFF"
}
},
"idiom" : "universal"

View File

@ -81,7 +81,7 @@ extension MultiLineTextFieldStore {
extension MultiLineTextFieldReducer.State {
static let placeholder: MultiLineTextFieldReducer.State = {
var state = MultiLineTextFieldReducer.State()
state.text = "test".redacted
state.text = "".redacted
return state
}()
}

View File

@ -58,9 +58,8 @@ struct MultilineTextEditorModifier: ViewModifier {
.foregroundColor(Asset.Colors.Text.importSeedEditor.color)
.padding()
.background(backgroundColor)
.cornerRadius(4)
.overlay(
RoundedRectangle(cornerRadius: 4)
Rectangle()
.stroke(outlineColor, lineWidth: 2)
)
}

View File

@ -38,14 +38,18 @@ struct SingleLineTextField<TitleAccessoryContent, InputPrefixContent, InputAcces
placeholder: placeholderText,
store: store
)
.padding(10)
Spacer()
inputAccessoryView
}
.frame(maxHeight: 50)
TextFieldFooter()
.overlay(
Rectangle()
.stroke(.white, lineWidth: 2)
)
.padding(.vertical, 5)
}
}
}

View File

@ -15,7 +15,7 @@ struct TransactionAddressTextField: View {
WithViewStore(store) { viewStore in
VStack {
SingleLineTextField(
placeholderText: "address",
placeholderText: "Valid Zcash Address",
title: "To",
store: store.scope(
state: \.textFieldState,
@ -43,6 +43,7 @@ struct TransactionAddressTextField: View {
.resizable()
.frame(width: 30, height: 30)
}
.padding(.trailing, 10)
}
)
}

View File

@ -12,44 +12,18 @@ struct TransactionAmountTextField: View {
let store: TransactionAmountTextFieldStore
var body: some View {
WithViewStore(store) { viewStore in
VStack {
SingleLineTextField(
placeholderText: "0",
title: "How much ZEC would you like to send?",
store: store.scope(
state: \.textFieldState,
action: TransactionAmountTextFieldReducer.Action.textField
),
titleAccessoryView: {
Button(
action: {
viewStore.send(viewStore.isMax ? .clearValue : .setMax)
},
label: {
Text(viewStore.isMax ? "Clear" : "Max")
}
)
.textFieldTitleAccessoryButtonStyle
},
inputPrefixView: {
if viewStore.currencySelectionState.currencyType == .zec {
ZcashSymbol()
.frame(width: 12, height: 12, alignment: .center)
} else {
Text("$")
}
},
inputAccessoryView: {
CurrencySelectionView(
store: store.scope(
state: \.currencySelectionState,
action: TransactionAmountTextFieldReducer.Action.currencySelection
)
)
}
)
}
VStack {
SingleLineTextField(
placeholderText: "ZEC Amount",
title: "Amount",
store: store.scope(
state: \.textFieldState,
action: TransactionAmountTextFieldReducer.Action.textField
),
titleAccessoryView: { },
inputPrefixView: { },
inputAccessoryView: { }
)
}
}
}

View File

@ -55,14 +55,14 @@ class SendTests: XCTestCase {
}
// simulate the sending confirmation button to be pressed
_ = await store.send(.sendConfirmationPressed) { state in
_ = await store.send(.sendPressed) { state in
// once sending is confirmed, the attempts to try to send again by pressing the button
// needs to be eliminated, indicated by the flag `isSendingTransaction`, need to be true
state.isSendingTransaction = true
}
await testScheduler.advance(by: 0.01)
guard let memo = try? Memo(string: "test") else {
guard let memo = try? Memo(string: "") else {
XCTFail("testSendSucceeded: memo is expected to be successfuly initialized.")
return
}
@ -127,7 +127,7 @@ class SendTests: XCTestCase {
}
// simulate the sending confirmation button to be pressed
_ = await store.send(.sendConfirmationPressed) { state in
_ = await store.send(.sendPressed) { state in
// once sending is confirmed, the attempts to try to send again by pressing the button
// needs to be eliminated, indicated by the flag `isSendingTransaction`, need to be true
state.isSendingTransaction = true
@ -193,7 +193,7 @@ class SendTests: XCTestCase {
}
// simulate the sending confirmation button to be pressed
_ = await store.send(.sendConfirmationPressed) { state in
_ = await store.send(.sendPressed) { state in
// once sending is confirmed, the attempts to try to send again by pressing the button
// needs to be eliminated, indicated by the flag `isSendingTransaction`, need to be true
state.isSendingTransaction = true

View File

@ -1,74 +0,0 @@
//
// TransactionConfirmationSnapshotTests.swift
// secantTests
//
// Created by Michal Fousek on 26.09.2022.
//
import XCTest
@testable import secant_testnet
import ComposableArchitecture
import SwiftUI
import ZcashLightClientKit
class TransactionConfirmationSnapshotTests: XCTestCase {
func testTransactionConfirmationSnapshot_addMemo() throws {
var state = SendFlowReducer.State.placeholder
state.addMemoState = true
state.transactionAddressInputState = TransactionAddressTextFieldReducer.State(
textFieldState: TCATextFieldReducer.State(
validationType: nil,
text: "ztestmockeddestinationaddress".redacted
)
)
state.transactionAmountInputState = TransactionAmountTextFieldReducer.State(
currencySelectionState: CurrencySelectionReducer.State(),
textFieldState: TCATextFieldReducer.State(
validationType: nil,
text: "2.91".redacted
)
)
let store = Store(
initialState: state,
reducer: SendFlowReducer()
.dependency(\.derivationTool, .live())
.dependency(\.mainQueue, DispatchQueue.main.eraseToAnyScheduler())
.dependency(\.numberFormatter, .live())
.dependency(\.walletStorage, .live())
)
ViewStore(store).send(.onAppear)
addAttachments(TransactionConfirmation(store: store))
}
func testTransactionConfirmationSnapshot_dontAddMemo() throws {
var state = SendFlowReducer.State.placeholder
state.addMemoState = true
state.transactionAddressInputState = TransactionAddressTextFieldReducer.State(
textFieldState: TCATextFieldReducer.State(
validationType: nil,
text: "ztestmockeddestinationaddress".redacted
)
)
state.transactionAmountInputState = TransactionAmountTextFieldReducer.State(
currencySelectionState: CurrencySelectionReducer.State(),
textFieldState: TCATextFieldReducer.State(
validationType: nil,
text: "2.91".redacted
)
)
let store = Store(
initialState: state,
reducer: SendFlowReducer()
.dependency(\.derivationTool, .live())
.dependency(\.mainQueue, DispatchQueue.main.eraseToAnyScheduler())
.dependency(\.numberFormatter, .live())
.dependency(\.walletStorage, .live())
)
ViewStore(store).send(.onAppear)
addAttachments(TransactionConfirmation(store: store))
}
}