commit
f4be94cb09
|
@ -98,7 +98,12 @@
|
||||||
F96B41E9273B501F0021B49A /* TransactionHistoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F96B41E6273B501F0021B49A /* TransactionHistoryView.swift */; };
|
F96B41E9273B501F0021B49A /* TransactionHistoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F96B41E6273B501F0021B49A /* TransactionHistoryView.swift */; };
|
||||||
F96B41EB273B50520021B49A /* Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = F96B41EA273B50520021B49A /* Strings.swift */; };
|
F96B41EB273B50520021B49A /* Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = F96B41EA273B50520021B49A /* Strings.swift */; };
|
||||||
F9C165B4274031F600592F76 /* Bindings.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C165B3274031F600592F76 /* Bindings.swift */; };
|
F9C165B4274031F600592F76 /* Bindings.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C165B3274031F600592F76 /* Bindings.swift */; };
|
||||||
|
F9C165BF2740403600592F76 /* SendStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C165B72740403600592F76 /* SendStore.swift */; };
|
||||||
|
F9C165C02740403600592F76 /* ApproveView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C165B92740403600592F76 /* ApproveView.swift */; };
|
||||||
|
F9C165C22740403600592F76 /* CreateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C165BB2740403600592F76 /* CreateView.swift */; };
|
||||||
|
F9C165C42740403600592F76 /* SentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C165BD2740403600592F76 /* SentView.swift */; };
|
||||||
F9EEB8162742C2210032EEB8 /* WithStateBinding.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9EEB8152742C2210032EEB8 /* WithStateBinding.swift */; };
|
F9EEB8162742C2210032EEB8 /* WithStateBinding.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9EEB8152742C2210032EEB8 /* WithStateBinding.swift */; };
|
||||||
|
F9C165CB2741AB5D00592F76 /* SendView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C165CA2741AB5D00592F76 /* SendView.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
|
@ -215,7 +220,12 @@
|
||||||
F96B41E6273B501F0021B49A /* TransactionHistoryView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionHistoryView.swift; sourceTree = "<group>"; };
|
F96B41E6273B501F0021B49A /* TransactionHistoryView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionHistoryView.swift; sourceTree = "<group>"; };
|
||||||
F96B41EA273B50520021B49A /* Strings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Strings.swift; sourceTree = "<group>"; };
|
F96B41EA273B50520021B49A /* Strings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Strings.swift; sourceTree = "<group>"; };
|
||||||
F9C165B3274031F600592F76 /* Bindings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bindings.swift; sourceTree = "<group>"; };
|
F9C165B3274031F600592F76 /* Bindings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bindings.swift; sourceTree = "<group>"; };
|
||||||
|
F9C165B72740403600592F76 /* SendStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SendStore.swift; sourceTree = "<group>"; };
|
||||||
|
F9C165B92740403600592F76 /* ApproveView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApproveView.swift; sourceTree = "<group>"; };
|
||||||
|
F9C165BB2740403600592F76 /* CreateView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CreateView.swift; sourceTree = "<group>"; };
|
||||||
|
F9C165BD2740403600592F76 /* SentView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SentView.swift; sourceTree = "<group>"; };
|
||||||
F9EEB8152742C2210032EEB8 /* WithStateBinding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WithStateBinding.swift; sourceTree = "<group>"; };
|
F9EEB8152742C2210032EEB8 /* WithStateBinding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WithStateBinding.swift; sourceTree = "<group>"; };
|
||||||
|
F9C165CA2741AB5D00592F76 /* SendView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendView.swift; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
@ -607,6 +617,7 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
F93874EC273C4DE200F0E875 /* Home */,
|
F93874EC273C4DE200F0E875 /* Home */,
|
||||||
|
F9C165B62740403600592F76 /* Send */,
|
||||||
F96B41E2273B501F0021B49A /* TransactionHistory */,
|
F96B41E2273B501F0021B49A /* TransactionHistory */,
|
||||||
6654C73C2715A3FA00901167 /* Onboarding */,
|
6654C73C2715A3FA00901167 /* Onboarding */,
|
||||||
);
|
);
|
||||||
|
@ -699,6 +710,26 @@
|
||||||
path = Views;
|
path = Views;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
F9C165B62740403600592F76 /* Send */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
F9C165B72740403600592F76 /* SendStore.swift */,
|
||||||
|
F9C165B82740403600592F76 /* Views */,
|
||||||
|
);
|
||||||
|
path = Send;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
F9C165B82740403600592F76 /* Views */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
F9C165CA2741AB5D00592F76 /* SendView.swift */,
|
||||||
|
F9C165BB2740403600592F76 /* CreateView.swift */,
|
||||||
|
F9C165B92740403600592F76 /* ApproveView.swift */,
|
||||||
|
F9C165BD2740403600592F76 /* SentView.swift */,
|
||||||
|
);
|
||||||
|
path = Views;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
/* End PBXGroup section */
|
/* End PBXGroup section */
|
||||||
|
|
||||||
/* Begin PBXNativeTarget section */
|
/* Begin PBXNativeTarget section */
|
||||||
|
@ -939,12 +970,14 @@
|
||||||
0DA13C9726C186FF00E3B610 /* RestoreWalletScreen.swift in Sources */,
|
0DA13C9726C186FF00E3B610 /* RestoreWalletScreen.swift in Sources */,
|
||||||
0DACFA8127208D940039EEA5 /* UInt+SuperscriptText.swift in Sources */,
|
0DACFA8127208D940039EEA5 /* UInt+SuperscriptText.swift in Sources */,
|
||||||
0DF2DC51272344E400FA31E2 /* EmptyChip.swift in Sources */,
|
0DF2DC51272344E400FA31E2 /* EmptyChip.swift in Sources */,
|
||||||
|
F9C165BF2740403600592F76 /* SendStore.swift in Sources */,
|
||||||
0D1922EA26BDD96A00052649 /* ViewModel.swift in Sources */,
|
0D1922EA26BDD96A00052649 /* ViewModel.swift in Sources */,
|
||||||
0D4E7A0926B364170058B01E /* SecantApp.swift in Sources */,
|
0D4E7A0926B364170058B01E /* SecantApp.swift in Sources */,
|
||||||
66DC733F271D88CC0053CBB6 /* StandardButtonStyle.swift in Sources */,
|
66DC733F271D88CC0053CBB6 /* StandardButtonStyle.swift in Sources */,
|
||||||
0D864A0926E154FD00A61879 /* InitFailedScreen.swift in Sources */,
|
0D864A0926E154FD00A61879 /* InitFailedScreen.swift in Sources */,
|
||||||
663FABA0271D876200E495F8 /* PrimaryButton.swift in Sources */,
|
663FABA0271D876200E495F8 /* PrimaryButton.swift in Sources */,
|
||||||
663FAB9C271D874D00E495F8 /* ActiveButton.swift in Sources */,
|
663FAB9C271D874D00E495F8 /* ActiveButton.swift in Sources */,
|
||||||
|
F9C165C02740403600592F76 /* ApproveView.swift in Sources */,
|
||||||
0DF2DC5427235E3E00FA31E2 /* View+InnerShadow.swift in Sources */,
|
0DF2DC5427235E3E00FA31E2 /* View+InnerShadow.swift in Sources */,
|
||||||
0D32281A26C5864B00262533 /* ProfileScreenViewModel.swift in Sources */,
|
0D32281A26C5864B00262533 /* ProfileScreenViewModel.swift in Sources */,
|
||||||
0D185819272723FF0046B928 /* BlueChip.swift in Sources */,
|
0D185819272723FF0046B928 /* BlueChip.swift in Sources */,
|
||||||
|
@ -954,6 +987,7 @@
|
||||||
66A0807B271993C500118B79 /* OnboardingProgressIndicator.swift in Sources */,
|
66A0807B271993C500118B79 /* OnboardingProgressIndicator.swift in Sources */,
|
||||||
663FAB9E271D875700E495F8 /* CreateButton.swift in Sources */,
|
663FAB9E271D875700E495F8 /* CreateButton.swift in Sources */,
|
||||||
0D7DF08C271DCC0E00530046 /* ScreenBackground.swift in Sources */,
|
0D7DF08C271DCC0E00530046 /* ScreenBackground.swift in Sources */,
|
||||||
|
F9C165C22740403600592F76 /* CreateView.swift in Sources */,
|
||||||
0DA13C8F26C15D1D00E3B610 /* WelcomeScreen.swift in Sources */,
|
0DA13C8F26C15D1D00E3B610 /* WelcomeScreen.swift in Sources */,
|
||||||
F9C165B4274031F600592F76 /* Bindings.swift in Sources */,
|
F9C165B4274031F600592F76 /* Bindings.swift in Sources */,
|
||||||
0D32282826C586E000262533 /* RequestZcashScreen.swift in Sources */,
|
0D32282826C586E000262533 /* RequestZcashScreen.swift in Sources */,
|
||||||
|
@ -963,8 +997,10 @@
|
||||||
0DA13CA226C1955600E3B610 /* HomeScreenViewModel.swift in Sources */,
|
0DA13CA226C1955600E3B610 /* HomeScreenViewModel.swift in Sources */,
|
||||||
0D32282926C586E000262533 /* RequestZcashScreenViewModel.swift in Sources */,
|
0D32282926C586E000262533 /* RequestZcashScreenViewModel.swift in Sources */,
|
||||||
0D32281926C5864B00262533 /* ProfileScreen.swift in Sources */,
|
0D32281926C5864B00262533 /* ProfileScreen.swift in Sources */,
|
||||||
|
F9C165CB2741AB5D00592F76 /* SendView.swift in Sources */,
|
||||||
6654C7412715A47300901167 /* Onboarding.swift in Sources */,
|
6654C7412715A47300901167 /* Onboarding.swift in Sources */,
|
||||||
0D32282426C586A800262533 /* HistoryScreenViewModel.swift in Sources */,
|
0D32282426C586A800262533 /* HistoryScreenViewModel.swift in Sources */,
|
||||||
|
F9C165C42740403600592F76 /* SentView.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -89,4 +89,13 @@ extension HomeViewStore {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var showSendBinding: Binding<Bool> {
|
||||||
|
self.binding(
|
||||||
|
get: { $0.route == .send },
|
||||||
|
send: { isActive in
|
||||||
|
return .updateRoute(isActive ? .send : nil)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,13 @@ struct HomeView: View {
|
||||||
.primaryButtonStyle
|
.primaryButtonStyle
|
||||||
.frame(height: 50)
|
.frame(height: 50)
|
||||||
|
|
||||||
|
Button(
|
||||||
|
action: { viewStore.send(.updateRoute(.send)) },
|
||||||
|
label: { Text("Go to Send") }
|
||||||
|
)
|
||||||
|
.primaryButtonStyle
|
||||||
|
.frame(height: 50)
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
|
|
||||||
HStack {
|
HStack {
|
||||||
|
@ -36,6 +43,24 @@ struct HomeView: View {
|
||||||
}
|
}
|
||||||
.padding(.horizontal, 30)
|
.padding(.horizontal, 30)
|
||||||
.navigationBarTitle("Home", displayMode: .inline)
|
.navigationBarTitle("Home", displayMode: .inline)
|
||||||
|
.navigationLinkEmpty(
|
||||||
|
isActive: viewStore.showSendBinding,
|
||||||
|
destination: {
|
||||||
|
SendView(
|
||||||
|
store: .init(
|
||||||
|
initialState: .init(
|
||||||
|
transaction: .demo,
|
||||||
|
route: nil
|
||||||
|
),
|
||||||
|
reducer: SendReducer.default(
|
||||||
|
whenDone: { viewStore.send(.updateRoute(nil)) }
|
||||||
|
)
|
||||||
|
.debug(),
|
||||||
|
environment: ()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
.fullScreenCover(
|
.fullScreenCover(
|
||||||
isPresented: viewStore.showHistoryBinding,
|
isPresented: viewStore.showHistoryBinding,
|
||||||
content: {
|
content: {
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
import SwiftUI
|
||||||
|
import ComposableArchitecture
|
||||||
|
|
||||||
|
struct SendState: Equatable {
|
||||||
|
var transaction: Transaction
|
||||||
|
var route: SendView.Route?
|
||||||
|
}
|
||||||
|
|
||||||
|
enum SendAction: Equatable {
|
||||||
|
case updateTransaction(Transaction)
|
||||||
|
case updateRoute(SendView.Route?)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark: - SendReducer
|
||||||
|
|
||||||
|
typealias SendReducer = Reducer<SendState, SendAction, Void>
|
||||||
|
|
||||||
|
extension SendReducer {
|
||||||
|
private struct SyncStatusUpdatesID: Hashable {}
|
||||||
|
|
||||||
|
static let `default` = Reducer<SendState, SendAction, Void> { state, action, _ in
|
||||||
|
switch action {
|
||||||
|
case let .updateTransaction(transaction):
|
||||||
|
state.transaction = transaction
|
||||||
|
return .none
|
||||||
|
case let .updateRoute(route):
|
||||||
|
state.route = route
|
||||||
|
return .none
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static func `default`(whenDone: @escaping () -> Void) -> SendReducer {
|
||||||
|
SendReducer { state, action, _ in
|
||||||
|
switch action {
|
||||||
|
case let .updateRoute(route) where route == .done:
|
||||||
|
return Effect.fireAndForget(whenDone)
|
||||||
|
default:
|
||||||
|
return Self.default.run(&state, action, ())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark: - SendStore
|
||||||
|
|
||||||
|
typealias SendStore = Store<SendState, SendAction>
|
||||||
|
|
||||||
|
// Mark: - SendViewStore
|
||||||
|
|
||||||
|
typealias SendViewStore = ViewStore<SendState, SendAction>
|
||||||
|
|
||||||
|
extension SendViewStore {
|
||||||
|
|
||||||
|
var bindingForTransaction: Binding<Transaction> {
|
||||||
|
self.binding(
|
||||||
|
get: \.transaction,
|
||||||
|
send: SendAction.updateTransaction
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
var routeBinding: Binding<SendView.Route?> {
|
||||||
|
self.binding(
|
||||||
|
get: \.route,
|
||||||
|
send: SendAction.updateRoute
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
var bindingForApprove: Binding<Bool> {
|
||||||
|
self.routeBinding.map(
|
||||||
|
extract: { $0 == .showApprove || self.bindingForSent.wrappedValue },
|
||||||
|
embed: { $0 ? SendView.Route.showApprove : nil }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
var bindingForSent: Binding<Bool> {
|
||||||
|
self.routeBinding.map(
|
||||||
|
extract: { $0 == .showSent || self.bindingForDone.wrappedValue },
|
||||||
|
embed: { $0 ? SendView.Route.showSent : SendView.Route.showApprove }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
var bindingForDone: Binding<Bool> {
|
||||||
|
self.routeBinding.map(
|
||||||
|
extract: { $0 == .done },
|
||||||
|
embed: { $0 ? SendView.Route.done : SendView.Route.showSent }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
import SwiftUI
|
||||||
|
import ComposableArchitecture
|
||||||
|
|
||||||
|
struct Approve: View {
|
||||||
|
let transaction: Transaction
|
||||||
|
@Binding var isComplete: Bool
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack {
|
||||||
|
Button(
|
||||||
|
action: { isComplete = true },
|
||||||
|
label: { Text("Go to sent") }
|
||||||
|
)
|
||||||
|
.primaryButtonStyle
|
||||||
|
.frame(height: 50)
|
||||||
|
.padding()
|
||||||
|
|
||||||
|
Text("\(String(dumping: transaction))")
|
||||||
|
Text("\(String(dumping: isComplete))")
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.navigationTitle(Text("2. Approve"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Approve_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
NavigationView {
|
||||||
|
StateContainer(initialState: (Transaction.demo, false)) {
|
||||||
|
Approve(
|
||||||
|
transaction: $0.0.wrappedValue,
|
||||||
|
isComplete: $0.1
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
import SwiftUI
|
||||||
|
import ComposableArchitecture
|
||||||
|
|
||||||
|
struct Create: View {
|
||||||
|
@Binding var transaction: Transaction
|
||||||
|
@Binding var isComplete: Bool
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack {
|
||||||
|
Button(
|
||||||
|
action: { isComplete = true },
|
||||||
|
label: { Text("Go To Approve") }
|
||||||
|
)
|
||||||
|
.primaryButtonStyle
|
||||||
|
.frame(height: 50)
|
||||||
|
.padding()
|
||||||
|
|
||||||
|
TextField(
|
||||||
|
"Amount",
|
||||||
|
text: $transaction
|
||||||
|
.amount
|
||||||
|
.compactMap(
|
||||||
|
extract: String.init,
|
||||||
|
embed: UInt.init
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.padding()
|
||||||
|
|
||||||
|
TextField(
|
||||||
|
"Address",
|
||||||
|
text: $transaction.toAddress
|
||||||
|
)
|
||||||
|
|
||||||
|
Text("\(String(dumping: transaction))")
|
||||||
|
Text("\(String(dumping: isComplete))")
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.padding()
|
||||||
|
.navigationTitle(Text("1. Create"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Previews
|
||||||
|
|
||||||
|
struct Create_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
NavigationView {
|
||||||
|
StateContainer(initialState: (Transaction.demo, false)) {
|
||||||
|
Create(
|
||||||
|
transaction: $0.0,
|
||||||
|
isComplete: $0.1
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
extension SendStore {
|
||||||
|
static var demo: SendStore {
|
||||||
|
return SendStore(
|
||||||
|
initialState: .init(
|
||||||
|
transaction: .demo,
|
||||||
|
route: nil
|
||||||
|
),
|
||||||
|
reducer: .default,
|
||||||
|
environment: ()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,58 @@
|
||||||
|
import SwiftUI
|
||||||
|
import ComposableArchitecture
|
||||||
|
|
||||||
|
struct SendView: View {
|
||||||
|
enum Route: Equatable {
|
||||||
|
case showApprove
|
||||||
|
case showSent
|
||||||
|
case done
|
||||||
|
}
|
||||||
|
|
||||||
|
let store: Store<SendState, SendAction>
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
WithViewStore(store) { viewStore in
|
||||||
|
Create(
|
||||||
|
transaction: viewStore.bindingForTransaction,
|
||||||
|
isComplete: viewStore.bindingForApprove
|
||||||
|
)
|
||||||
|
.navigationLinkEmpty(
|
||||||
|
isActive: viewStore.bindingForApprove,
|
||||||
|
destination: {
|
||||||
|
Approve(
|
||||||
|
transaction: viewStore.transaction,
|
||||||
|
isComplete: viewStore.bindingForSent
|
||||||
|
)
|
||||||
|
.navigationLinkEmpty(
|
||||||
|
isActive: viewStore.bindingForSent,
|
||||||
|
destination: {
|
||||||
|
Sent(
|
||||||
|
transaction: viewStore.transaction,
|
||||||
|
isComplete: viewStore.bindingForDone
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SendView_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
NavigationView {
|
||||||
|
SendView(
|
||||||
|
store: .init(
|
||||||
|
initialState: .init(
|
||||||
|
transaction: .demo,
|
||||||
|
route: nil
|
||||||
|
),
|
||||||
|
reducer: .default,
|
||||||
|
environment: ()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
|
.navigationViewStyle(StackNavigationViewStyle())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
import SwiftUI
|
||||||
|
import ComposableArchitecture
|
||||||
|
|
||||||
|
struct Sent: View {
|
||||||
|
var transaction: Transaction
|
||||||
|
@Binding var isComplete: Bool
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack {
|
||||||
|
Button(
|
||||||
|
action: {
|
||||||
|
isComplete = true
|
||||||
|
},
|
||||||
|
label: { Text("Done") }
|
||||||
|
)
|
||||||
|
.primaryButtonStyle
|
||||||
|
.frame(height: 50)
|
||||||
|
.padding()
|
||||||
|
|
||||||
|
|
||||||
|
Text("\(String(dumping: transaction))")
|
||||||
|
Text("\(String(dumping: isComplete))")
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.navigationTitle(Text("3. Sent"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Done_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
Sent(transaction: .demo, isComplete: .constant(false))
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,6 +15,7 @@ struct SecantApp: App {
|
||||||
NavigationView {
|
NavigationView {
|
||||||
HomeView(store: homeStore)
|
HomeView(store: homeStore)
|
||||||
}
|
}
|
||||||
|
.navigationViewStyle(StackNavigationViewStyle())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,14 @@ extension Binding {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func map<T>(extract: @escaping (Value) -> T, embed: @escaping (T) -> Value?) -> Binding<T> {
|
func map<T>(extract: @escaping (Value) -> T, embed: @escaping (T) -> Value) -> Binding<T> {
|
||||||
|
Binding<T>(
|
||||||
|
get: { extract(wrappedValue) },
|
||||||
|
set: { wrappedValue = embed($0) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func compactMap<T>(extract: @escaping (Value) -> T, embed: @escaping (T) -> Value?) -> Binding<T> {
|
||||||
Binding<T>(
|
Binding<T>(
|
||||||
get: { extract(wrappedValue) },
|
get: { extract(wrappedValue) },
|
||||||
set: {
|
set: {
|
||||||
|
|
Loading…
Reference in New Issue