- Route -> Destination refactor done - test working - cleanup of URLRouting usage
This commit is contained in:
parent
a591ee93ce
commit
8e3544b732
|
@ -11,12 +11,12 @@ import ComposableArchitecture
|
||||||
import ZcashLightClientKit
|
import ZcashLightClientKit
|
||||||
|
|
||||||
struct Deeplink {
|
struct Deeplink {
|
||||||
enum Route: Equatable {
|
enum Destination: Equatable {
|
||||||
case home
|
case home
|
||||||
case send(amount: Int64, address: String, memo: String)
|
case send(amount: Int64, address: String, memo: String)
|
||||||
}
|
}
|
||||||
|
|
||||||
func resolveDeeplinkURL(_ url: URL, isValidZcashAddress: (String) throws -> Bool) throws -> Route {
|
func resolveDeeplinkURL(_ url: URL, isValidZcashAddress: (String) throws -> Bool) throws -> Destination {
|
||||||
// simplified format zcash:<address>
|
// simplified format zcash:<address>
|
||||||
// TODO [#109]: simplified for now until ZIP-321 is implememnted (https://github.com/zcash/secant-ios-wallet/issues/109)
|
// TODO [#109]: simplified for now until ZIP-321 is implememnted (https://github.com/zcash/secant-ios-wallet/issues/109)
|
||||||
let address = url.absoluteString.replacingOccurrences(of: "zcash:", with: "")
|
let address = url.absoluteString.replacingOccurrences(of: "zcash:", with: "")
|
||||||
|
@ -29,12 +29,12 @@ struct Deeplink {
|
||||||
// regular URL format zcash://
|
// regular URL format zcash://
|
||||||
let appRouter = OneOf {
|
let appRouter = OneOf {
|
||||||
// GET /home
|
// GET /home
|
||||||
URLRouting.Route(.case(Route.home)) {
|
Route(.case(Destination.home)) {
|
||||||
Path { "home" }
|
Path { "home" }
|
||||||
}
|
}
|
||||||
|
|
||||||
// GET /home/send?amount=:amount&address=:address&memo=:memo
|
// GET /home/send?amount=:amount&address=:address&memo=:memo
|
||||||
URLRouting.Route(.case(Route.send(amount:address:memo:))) {
|
Route(.case(Destination.send(amount:address:memo:))) {
|
||||||
Path { "home"; "send" }
|
Path { "home"; "send" }
|
||||||
Query {
|
Query {
|
||||||
Field("amount", default: 0) { Int64.parser() }
|
Field("amount", default: 0) { Int64.parser() }
|
||||||
|
|
|
@ -17,5 +17,5 @@ extension DependencyValues {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DeeplinkClient {
|
struct DeeplinkClient {
|
||||||
let resolveDeeplinkURL: (URL, DerivationToolClient) throws -> Deeplink.Route
|
let resolveDeeplinkURL: (URL, DerivationToolClient) throws -> Deeplink.Destination
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ struct AppReducer: ReducerProtocol {
|
||||||
private enum CancelId {}
|
private enum CancelId {}
|
||||||
|
|
||||||
struct State: Equatable {
|
struct State: Equatable {
|
||||||
enum Route: Equatable {
|
enum Destination: Equatable {
|
||||||
case welcome
|
case welcome
|
||||||
case startup
|
case startup
|
||||||
case onboarding
|
case onboarding
|
||||||
|
@ -25,17 +25,17 @@ struct AppReducer: ReducerProtocol {
|
||||||
var onboardingState: OnboardingFlowReducer.State
|
var onboardingState: OnboardingFlowReducer.State
|
||||||
var phraseValidationState: RecoveryPhraseValidationFlowReducer.State
|
var phraseValidationState: RecoveryPhraseValidationFlowReducer.State
|
||||||
var phraseDisplayState: RecoveryPhraseDisplayReducer.State
|
var phraseDisplayState: RecoveryPhraseDisplayReducer.State
|
||||||
var prevRoute: Route?
|
var prevDestination: Destination?
|
||||||
var internalRoute: Route = .welcome
|
var internalDestination: Destination = .welcome
|
||||||
var sandboxState: SandboxReducer.State
|
var sandboxState: SandboxReducer.State
|
||||||
var storedWallet: StoredWallet?
|
var storedWallet: StoredWallet?
|
||||||
var welcomeState: WelcomeReducer.State
|
var welcomeState: WelcomeReducer.State
|
||||||
|
|
||||||
var route: Route {
|
var destination: Destination {
|
||||||
get { internalRoute }
|
get { internalDestination }
|
||||||
set {
|
set {
|
||||||
prevRoute = internalRoute
|
prevDestination = internalDestination
|
||||||
internalRoute = newValue
|
internalDestination = newValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ struct AppReducer: ReducerProtocol {
|
||||||
case phraseValidation(RecoveryPhraseValidationFlowReducer.Action)
|
case phraseValidation(RecoveryPhraseValidationFlowReducer.Action)
|
||||||
case respondToWalletInitializationState(InitializationState)
|
case respondToWalletInitializationState(InitializationState)
|
||||||
case sandbox(SandboxReducer.Action)
|
case sandbox(SandboxReducer.Action)
|
||||||
case updateRoute(AppReducer.State.Route)
|
case updateDestination(AppReducer.State.Destination)
|
||||||
case welcome(WelcomeReducer.Action)
|
case welcome(WelcomeReducer.Action)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,29 +93,29 @@ struct AppReducer: ReducerProtocol {
|
||||||
|
|
||||||
Reduce { state, action in
|
Reduce { state, action in
|
||||||
switch action {
|
switch action {
|
||||||
case let .updateRoute(route):
|
case let .updateDestination(destination):
|
||||||
state.route = route
|
state.destination = destination
|
||||||
|
|
||||||
case .sandbox(.reset):
|
case .sandbox(.reset):
|
||||||
state.route = .startup
|
state.destination = .startup
|
||||||
|
|
||||||
case .onboarding(.createNewWallet):
|
case .onboarding(.createNewWallet):
|
||||||
return Effect(value: .createNewWallet)
|
return Effect(value: .createNewWallet)
|
||||||
|
|
||||||
case .phraseValidation(.proceedToHome):
|
case .phraseValidation(.proceedToHome):
|
||||||
state.route = .home
|
state.destination = .home
|
||||||
|
|
||||||
case .phraseValidation(.displayBackedUpPhrase):
|
case .phraseValidation(.displayBackedUpPhrase):
|
||||||
state.route = .phraseDisplay
|
state.destination = .phraseDisplay
|
||||||
|
|
||||||
case .phraseDisplay(.finishedPressed):
|
case .phraseDisplay(.finishedPressed):
|
||||||
// user is still supposed to do the backup phrase validation test
|
// user is still supposed to do the backup phrase validation test
|
||||||
if state.prevRoute == .welcome || state.prevRoute == .onboarding {
|
if state.prevDestination == .welcome || state.prevDestination == .onboarding {
|
||||||
state.route = .phraseValidation
|
state.destination = .phraseValidation
|
||||||
}
|
}
|
||||||
// user wanted to see the backup phrase once again (at validation finished screen)
|
// user wanted to see the backup phrase once again (at validation finished screen)
|
||||||
if state.prevRoute == .phraseValidation {
|
if state.prevDestination == .phraseValidation {
|
||||||
state.route = .home
|
state.destination = .home
|
||||||
}
|
}
|
||||||
|
|
||||||
case .deeplink(let url):
|
case .deeplink(let url):
|
||||||
|
@ -144,13 +144,13 @@ struct AppReducer: ReducerProtocol {
|
||||||
}
|
}
|
||||||
|
|
||||||
case .deeplinkHome:
|
case .deeplinkHome:
|
||||||
state.route = .home
|
state.destination = .home
|
||||||
state.homeState.route = nil
|
state.homeState.destination = nil
|
||||||
return .none
|
return .none
|
||||||
|
|
||||||
case let .deeplinkSend(amount, address, memo):
|
case let .deeplinkSend(amount, address, memo):
|
||||||
state.route = .home
|
state.destination = .home
|
||||||
state.homeState.route = .send
|
state.homeState.destination = .send
|
||||||
state.homeState.sendState.amount = amount
|
state.homeState.sendState.amount = amount
|
||||||
state.homeState.sendState.address = address
|
state.homeState.sendState.address = address
|
||||||
state.homeState.sendState.memoState.text = memo
|
state.homeState.sendState.memoState.text = memo
|
||||||
|
@ -162,7 +162,7 @@ struct AppReducer: ReducerProtocol {
|
||||||
}
|
}
|
||||||
return Effect(value: .deeplink(url))
|
return Effect(value: .deeplink(url))
|
||||||
|
|
||||||
/// Default is meaningful here because there's `appReducer` handling actions and this reducer is handling only routes. We don't here plenty of unused cases.
|
/// Default is meaningful here because there's `appReducer` handling actions and this reducer is handling only destinations. We don't here plenty of unused cases.
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -206,7 +206,7 @@ struct AppReducer: ReducerProtocol {
|
||||||
)
|
)
|
||||||
case .uninitialized:
|
case .uninitialized:
|
||||||
state.appInitializationState = .uninitialized
|
state.appInitializationState = .uninitialized
|
||||||
return Effect(value: .updateRoute(.onboarding))
|
return Effect(value: .updateDestination(.onboarding))
|
||||||
.delay(for: 3, scheduler: mainQueue)
|
.delay(for: 3, scheduler: mainQueue)
|
||||||
.eraseToEffect()
|
.eraseToEffect()
|
||||||
.cancellable(id: CancelId.self, cancelInFlight: true)
|
.cancellable(id: CancelId.self, cancelInFlight: true)
|
||||||
|
@ -257,7 +257,7 @@ struct AppReducer: ReducerProtocol {
|
||||||
return .none
|
return .none
|
||||||
}
|
}
|
||||||
|
|
||||||
var landingRoute: AppReducer.State.Route = .home
|
var landingDestination: AppReducer.State.Destination = .home
|
||||||
|
|
||||||
if !storedWallet.hasUserPassedPhraseBackupTest {
|
if !storedWallet.hasUserPassedPhraseBackupTest {
|
||||||
do {
|
do {
|
||||||
|
@ -266,7 +266,7 @@ struct AppReducer: ReducerProtocol {
|
||||||
let recoveryPhrase = RecoveryPhrase(words: phraseWords)
|
let recoveryPhrase = RecoveryPhrase(words: phraseWords)
|
||||||
state.phraseDisplayState.phrase = recoveryPhrase
|
state.phraseDisplayState.phrase = recoveryPhrase
|
||||||
state.phraseValidationState = randomRecoveryPhrase.random(recoveryPhrase)
|
state.phraseValidationState = randomRecoveryPhrase.random(recoveryPhrase)
|
||||||
landingRoute = .phraseDisplay
|
landingDestination = .phraseDisplay
|
||||||
} catch {
|
} catch {
|
||||||
// TODO [#201]: - merge with issue 201 (https://github.com/zcash/secant-ios-wallet/issues/201) and its Error States
|
// TODO [#201]: - merge with issue 201 (https://github.com/zcash/secant-ios-wallet/issues/201) and its Error States
|
||||||
return .none
|
return .none
|
||||||
|
@ -275,7 +275,7 @@ struct AppReducer: ReducerProtocol {
|
||||||
|
|
||||||
state.appInitializationState = .initialized
|
state.appInitializationState = .initialized
|
||||||
|
|
||||||
return Effect(value: .updateRoute(landingRoute))
|
return Effect(value: .updateDestination(landingDestination))
|
||||||
.delay(for: 3, scheduler: mainQueue)
|
.delay(for: 3, scheduler: mainQueue)
|
||||||
.eraseToEffect()
|
.eraseToEffect()
|
||||||
.cancellable(id: CancelId.self, cancelInFlight: true)
|
.cancellable(id: CancelId.self, cancelInFlight: true)
|
||||||
|
@ -325,16 +325,16 @@ struct AppReducer: ReducerProtocol {
|
||||||
case .welcome(.debugMenuStartup), .home(.debugMenuStartup):
|
case .welcome(.debugMenuStartup), .home(.debugMenuStartup):
|
||||||
return .concatenate(
|
return .concatenate(
|
||||||
Effect.cancel(id: CancelId.self),
|
Effect.cancel(id: CancelId.self),
|
||||||
Effect(value: .updateRoute(.startup))
|
Effect(value: .updateDestination(.startup))
|
||||||
)
|
)
|
||||||
|
|
||||||
case .onboarding(.importWallet(.successfullyRecovered)):
|
case .onboarding(.importWallet(.successfullyRecovered)):
|
||||||
return Effect(value: .updateRoute(.home))
|
return Effect(value: .updateDestination(.home))
|
||||||
|
|
||||||
case .onboarding(.importWallet(.initializeSDK)):
|
case .onboarding(.importWallet(.initializeSDK)):
|
||||||
return Effect(value: .initializeSDK)
|
return Effect(value: .initializeSDK)
|
||||||
|
|
||||||
/// Default is meaningful here because there's `routeReducer` handling routes and this reducer is handling only actions. We don't here plenty of unused cases.
|
/// Default is meaningful here because there's `destinationReducer` handling destinations and this reducer is handling only actions. We don't here plenty of unused cases.
|
||||||
default:
|
default:
|
||||||
return .none
|
return .none
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ struct AppView: View {
|
||||||
var body: some View {
|
var body: some View {
|
||||||
WithViewStore(store) { viewStore in
|
WithViewStore(store) { viewStore in
|
||||||
Group {
|
Group {
|
||||||
switch viewStore.route {
|
switch viewStore.destination {
|
||||||
case .home:
|
case .home:
|
||||||
NavigationView {
|
NavigationView {
|
||||||
HomeView(
|
HomeView(
|
||||||
|
@ -86,21 +86,21 @@ struct AppView: View {
|
||||||
private extension AppView {
|
private extension AppView {
|
||||||
@ViewBuilder func debugView(_ viewStore: AppViewStore) -> some View {
|
@ViewBuilder func debugView(_ viewStore: AppViewStore) -> some View {
|
||||||
List {
|
List {
|
||||||
Section(header: Text("Navigation Stack Routes")) {
|
Section(header: Text("Navigation Stack Destinations")) {
|
||||||
Button("Go To Sandbox (navigation proof)") {
|
Button("Go To Sandbox (navigation proof)") {
|
||||||
viewStore.send(.updateRoute(.sandbox))
|
viewStore.send(.updateDestination(.sandbox))
|
||||||
}
|
}
|
||||||
|
|
||||||
Button("Go To Onboarding") {
|
Button("Go To Onboarding") {
|
||||||
viewStore.send(.updateRoute(.onboarding))
|
viewStore.send(.updateDestination(.onboarding))
|
||||||
}
|
}
|
||||||
|
|
||||||
Button("Go To Phrase Validation Demo") {
|
Button("Go To Phrase Validation Demo") {
|
||||||
viewStore.send(.updateRoute(.phraseValidation))
|
viewStore.send(.updateDestination(.phraseValidation))
|
||||||
}
|
}
|
||||||
|
|
||||||
Button("Restart the app") {
|
Button("Restart the app") {
|
||||||
viewStore.send(.updateRoute(.welcome))
|
viewStore.send(.updateDestination(.welcome))
|
||||||
}
|
}
|
||||||
|
|
||||||
Button("[Be careful] Nuke Wallet") {
|
Button("[Be careful] Nuke Wallet") {
|
||||||
|
|
|
@ -12,7 +12,7 @@ struct HomeReducer: ReducerProtocol {
|
||||||
private enum CancelId {}
|
private enum CancelId {}
|
||||||
|
|
||||||
struct State: Equatable {
|
struct State: Equatable {
|
||||||
enum Route: Equatable {
|
enum Destination: Equatable {
|
||||||
case notEnoughFreeDiskSpace
|
case notEnoughFreeDiskSpace
|
||||||
case profile
|
case profile
|
||||||
case request
|
case request
|
||||||
|
@ -21,7 +21,7 @@ struct HomeReducer: ReducerProtocol {
|
||||||
case balanceBreakdown
|
case balanceBreakdown
|
||||||
}
|
}
|
||||||
|
|
||||||
var route: Route?
|
var destination: Destination?
|
||||||
|
|
||||||
var balanceBreakdownState: BalanceBreakdownReducer.State
|
var balanceBreakdownState: BalanceBreakdownReducer.State
|
||||||
var drawerOverlay: DrawerOverlay
|
var drawerOverlay: DrawerOverlay
|
||||||
|
@ -68,7 +68,7 @@ struct HomeReducer: ReducerProtocol {
|
||||||
case synchronizerStateChanged(SDKSynchronizerState)
|
case synchronizerStateChanged(SDKSynchronizerState)
|
||||||
case walletEvents(WalletEventsFlowReducer.Action)
|
case walletEvents(WalletEventsFlowReducer.Action)
|
||||||
case updateDrawer(DrawerOverlay)
|
case updateDrawer(DrawerOverlay)
|
||||||
case updateRoute(HomeReducer.State.Route?)
|
case updateDestination(HomeReducer.State.Destination?)
|
||||||
case updateSynchronizerStatus
|
case updateSynchronizerStatus
|
||||||
case updateWalletEvents([WalletEvent])
|
case updateWalletEvents([WalletEvent])
|
||||||
}
|
}
|
||||||
|
@ -110,9 +110,9 @@ struct HomeReducer: ReducerProtocol {
|
||||||
.map(HomeReducer.Action.synchronizerStateChanged)
|
.map(HomeReducer.Action.synchronizerStateChanged)
|
||||||
.eraseToEffect()
|
.eraseToEffect()
|
||||||
.cancellable(id: CancelId.self, cancelInFlight: true)
|
.cancellable(id: CancelId.self, cancelInFlight: true)
|
||||||
return .concatenate(Effect(value: .updateRoute(nil)), syncEffect)
|
return .concatenate(Effect(value: .updateDestination(nil)), syncEffect)
|
||||||
} else {
|
} else {
|
||||||
return Effect(value: .updateRoute(.notEnoughFreeDiskSpace))
|
return Effect(value: .updateDestination(.notEnoughFreeDiskSpace))
|
||||||
}
|
}
|
||||||
|
|
||||||
case .onDisappear:
|
case .onDisappear:
|
||||||
|
@ -145,16 +145,16 @@ struct HomeReducer: ReducerProtocol {
|
||||||
}
|
}
|
||||||
return .none
|
return .none
|
||||||
|
|
||||||
case .updateRoute(let route):
|
case .updateDestination(let destination):
|
||||||
state.route = route
|
state.destination = destination
|
||||||
return .none
|
return .none
|
||||||
|
|
||||||
case .profile(.back):
|
case .profile(.back):
|
||||||
state.route = nil
|
state.destination = nil
|
||||||
return .none
|
return .none
|
||||||
|
|
||||||
case .profile(.settings(.quickRescan)):
|
case .profile(.settings(.quickRescan)):
|
||||||
state.route = nil
|
state.destination = nil
|
||||||
return Effect.task {
|
return Effect.task {
|
||||||
do {
|
do {
|
||||||
try await sdkSynchronizer.rewind(.quick)
|
try await sdkSynchronizer.rewind(.quick)
|
||||||
|
@ -165,7 +165,7 @@ struct HomeReducer: ReducerProtocol {
|
||||||
}
|
}
|
||||||
|
|
||||||
case .profile(.settings(.fullRescan)):
|
case .profile(.settings(.fullRescan)):
|
||||||
state.route = nil
|
state.destination = nil
|
||||||
return Effect.task {
|
return Effect.task {
|
||||||
do {
|
do {
|
||||||
try await sdkSynchronizer.rewind(.birthday)
|
try await sdkSynchronizer.rewind(.birthday)
|
||||||
|
@ -185,30 +185,30 @@ struct HomeReducer: ReducerProtocol {
|
||||||
// TODO [#221]: error we need to handle (https://github.com/zcash/secant-ios-wallet/issues/221)
|
// TODO [#221]: error we need to handle (https://github.com/zcash/secant-ios-wallet/issues/221)
|
||||||
return .none
|
return .none
|
||||||
|
|
||||||
case .walletEvents(.updateRoute(.all)):
|
case .walletEvents(.updateDestination(.all)):
|
||||||
return state.drawerOverlay != .full ? Effect(value: .updateDrawer(.full)) : .none
|
return state.drawerOverlay != .full ? Effect(value: .updateDrawer(.full)) : .none
|
||||||
|
|
||||||
case .walletEvents(.updateRoute(.latest)):
|
case .walletEvents(.updateDestination(.latest)):
|
||||||
return state.drawerOverlay != .partial ? Effect(value: .updateDrawer(.partial)) : .none
|
return state.drawerOverlay != .partial ? Effect(value: .updateDrawer(.partial)) : .none
|
||||||
|
|
||||||
case .walletEvents:
|
case .walletEvents:
|
||||||
return .none
|
return .none
|
||||||
|
|
||||||
case .send(.updateRoute(.done)):
|
case .send(.updateDestination(.done)):
|
||||||
return Effect(value: .updateRoute(nil))
|
return Effect(value: .updateDestination(nil))
|
||||||
|
|
||||||
case .send:
|
case .send:
|
||||||
return .none
|
return .none
|
||||||
|
|
||||||
case .scan(.found):
|
case .scan(.found):
|
||||||
audioServices.systemSoundVibrate()
|
audioServices.systemSoundVibrate()
|
||||||
return Effect(value: .updateRoute(nil))
|
return Effect(value: .updateDestination(nil))
|
||||||
|
|
||||||
case .scan:
|
case .scan:
|
||||||
return .none
|
return .none
|
||||||
|
|
||||||
case .balanceBreakdown(.onDisappear):
|
case .balanceBreakdown(.onDisappear):
|
||||||
state.route = nil
|
state.destination = nil
|
||||||
return .none
|
return .none
|
||||||
|
|
||||||
case .balanceBreakdown:
|
case .balanceBreakdown:
|
||||||
|
@ -270,11 +270,11 @@ extension HomeStore {
|
||||||
// MARK: - ViewStore
|
// MARK: - ViewStore
|
||||||
|
|
||||||
extension HomeViewStore {
|
extension HomeViewStore {
|
||||||
func bindingForRoute(_ route: HomeReducer.State.Route) -> Binding<Bool> {
|
func bindingForDestination(_ destination: HomeReducer.State.Destination) -> Binding<Bool> {
|
||||||
self.binding(
|
self.binding(
|
||||||
get: { $0.route == route },
|
get: { $0.destination == destination },
|
||||||
send: { isActive in
|
send: { isActive in
|
||||||
return .updateRoute(isActive ? route : nil)
|
return .updateDestination(isActive ? destination : nil)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,12 +27,12 @@ struct HomeView: View {
|
||||||
.navigationBarHidden(true)
|
.navigationBarHidden(true)
|
||||||
.onAppear(perform: { viewStore.send(.onAppear) })
|
.onAppear(perform: { viewStore.send(.onAppear) })
|
||||||
.onDisappear(perform: { viewStore.send(.onDisappear) })
|
.onDisappear(perform: { viewStore.send(.onDisappear) })
|
||||||
.fullScreenCover(isPresented: viewStore.bindingForRoute(.balanceBreakdown)) {
|
.fullScreenCover(isPresented: viewStore.bindingForDestination(.balanceBreakdown)) {
|
||||||
BalanceBreakdownView(store: store.balanceBreakdownStore())
|
BalanceBreakdownView(store: store.balanceBreakdownStore())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.navigationLinkEmpty(
|
.navigationLinkEmpty(
|
||||||
isActive: viewStore.bindingForRoute(.notEnoughFreeDiskSpace),
|
isActive: viewStore.bindingForDestination(.notEnoughFreeDiskSpace),
|
||||||
destination: { NotEnoughFreeSpaceView(viewStore: viewStore) }
|
destination: { NotEnoughFreeSpaceView(viewStore: viewStore) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ extension HomeView {
|
||||||
.frame(width: 60, height: 60)
|
.frame(width: 60, height: 60)
|
||||||
.padding(.trailing, 15)
|
.padding(.trailing, 15)
|
||||||
.navigationLink(
|
.navigationLink(
|
||||||
isActive: viewStore.bindingForRoute(.profile),
|
isActive: viewStore.bindingForDestination(.profile),
|
||||||
destination: {
|
destination: {
|
||||||
ProfileView(store: store.profileStore())
|
ProfileView(store: store.profileStore())
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ extension HomeView {
|
||||||
.padding(.horizontal, 50)
|
.padding(.horizontal, 50)
|
||||||
.neumorphicButton()
|
.neumorphicButton()
|
||||||
.navigationLink(
|
.navigationLink(
|
||||||
isActive: viewStore.bindingForRoute(.send),
|
isActive: viewStore.bindingForDestination(.send),
|
||||||
destination: {
|
destination: {
|
||||||
SendFlowView(store: store.sendStore())
|
SendFlowView(store: store.sendStore())
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ extension HomeView {
|
||||||
.padding(.top, 7)
|
.padding(.top, 7)
|
||||||
.padding(.leading, 22)
|
.padding(.leading, 22)
|
||||||
.navigationLink(
|
.navigationLink(
|
||||||
isActive: viewStore.bindingForRoute(.scan),
|
isActive: viewStore.bindingForDestination(.scan),
|
||||||
destination: {
|
destination: {
|
||||||
ScanView(store: store.scanStore())
|
ScanView(store: store.scanStore())
|
||||||
}
|
}
|
||||||
|
@ -128,7 +128,7 @@ extension HomeView {
|
||||||
|
|
||||||
VStack {
|
VStack {
|
||||||
Button {
|
Button {
|
||||||
viewStore.send(.updateRoute(.balanceBreakdown))
|
viewStore.send(.updateDestination(.balanceBreakdown))
|
||||||
} label: {
|
} label: {
|
||||||
Text("$\(viewStore.shieldedBalance.total.decimalString())")
|
Text("$\(viewStore.shieldedBalance.total.decimalString())")
|
||||||
.font(.custom(FontFamily.Zboto.regular.name, size: 40))
|
.font(.custom(FontFamily.Zboto.regular.name, size: 40))
|
||||||
|
|
|
@ -14,7 +14,7 @@ typealias OnboardingFlowViewStore = ViewStore<OnboardingFlowReducer.State, Onboa
|
||||||
|
|
||||||
struct OnboardingFlowReducer: ReducerProtocol {
|
struct OnboardingFlowReducer: ReducerProtocol {
|
||||||
struct State: Equatable {
|
struct State: Equatable {
|
||||||
enum Route: Equatable, CaseIterable {
|
enum Destination: Equatable, CaseIterable {
|
||||||
case createNewWallet
|
case createNewWallet
|
||||||
case importExistingWallet
|
case importExistingWallet
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ struct OnboardingFlowReducer: ReducerProtocol {
|
||||||
var steps: IdentifiedArrayOf<Step> = Self.onboardingSteps
|
var steps: IdentifiedArrayOf<Step> = Self.onboardingSteps
|
||||||
var index = 0
|
var index = 0
|
||||||
var skippedAtindex: Int?
|
var skippedAtindex: Int?
|
||||||
var route: Route?
|
var destination: Destination?
|
||||||
|
|
||||||
var currentStep: Step { steps[index] }
|
var currentStep: Step { steps[index] }
|
||||||
var isFinalStep: Bool { steps.count == index + 1 }
|
var isFinalStep: Bool { steps.count == index + 1 }
|
||||||
|
@ -51,7 +51,7 @@ struct OnboardingFlowReducer: ReducerProtocol {
|
||||||
case next
|
case next
|
||||||
case back
|
case back
|
||||||
case skip
|
case skip
|
||||||
case updateRoute(OnboardingFlowReducer.State.Route?)
|
case updateDestination(OnboardingFlowReducer.State.Destination?)
|
||||||
case createNewWallet
|
case createNewWallet
|
||||||
case importExistingWallet
|
case importExistingWallet
|
||||||
case importWallet(ImportWalletReducer.Action)
|
case importWallet(ImportWalletReducer.Action)
|
||||||
|
@ -85,16 +85,16 @@ struct OnboardingFlowReducer: ReducerProtocol {
|
||||||
state.index = state.steps.count - 1
|
state.index = state.steps.count - 1
|
||||||
return .none
|
return .none
|
||||||
|
|
||||||
case .updateRoute(let route):
|
case .updateDestination(let destination):
|
||||||
state.route = route
|
state.destination = destination
|
||||||
return .none
|
return .none
|
||||||
|
|
||||||
case .createNewWallet:
|
case .createNewWallet:
|
||||||
state.route = .createNewWallet
|
state.destination = .createNewWallet
|
||||||
return .none
|
return .none
|
||||||
|
|
||||||
case .importExistingWallet:
|
case .importExistingWallet:
|
||||||
state.route = .importExistingWallet
|
state.destination = .importExistingWallet
|
||||||
return .none
|
return .none
|
||||||
|
|
||||||
case .importWallet:
|
case .importWallet:
|
||||||
|
@ -142,11 +142,11 @@ extension OnboardingFlowReducer.State {
|
||||||
// MARK: - ViewStore
|
// MARK: - ViewStore
|
||||||
|
|
||||||
extension OnboardingFlowViewStore {
|
extension OnboardingFlowViewStore {
|
||||||
func bindingForRoute(_ route: OnboardingFlowReducer.State.Route) -> Binding<Bool> {
|
func bindingForDestination(_ destination: OnboardingFlowReducer.State.Destination) -> Binding<Bool> {
|
||||||
self.binding(
|
self.binding(
|
||||||
get: { $0.route == route },
|
get: { $0.destination == destination },
|
||||||
send: { isActive in
|
send: { isActive in
|
||||||
return .updateRoute(isActive ? route : nil)
|
return .updateDestination(isActive ? destination : nil)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ struct OnboardingFooterView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.navigationLinkEmpty(
|
.navigationLinkEmpty(
|
||||||
isActive: viewStore.bindingForRoute(.importExistingWallet),
|
isActive: viewStore.bindingForDestination(.importExistingWallet),
|
||||||
destination: {
|
destination: {
|
||||||
ImportWalletView(
|
ImportWalletView(
|
||||||
store: store.scope(
|
store: store.scope(
|
||||||
|
|
|
@ -6,7 +6,7 @@ typealias ProfileViewStore = ViewStore<ProfileReducer.State, ProfileReducer.Acti
|
||||||
|
|
||||||
struct ProfileReducer: ReducerProtocol {
|
struct ProfileReducer: ReducerProtocol {
|
||||||
struct State: Equatable {
|
struct State: Equatable {
|
||||||
enum Route {
|
enum Destination {
|
||||||
case addressDetails
|
case addressDetails
|
||||||
case settings
|
case settings
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ struct ProfileReducer: ReducerProtocol {
|
||||||
var addressDetailsState: AddressDetailsReducer.State
|
var addressDetailsState: AddressDetailsReducer.State
|
||||||
var appBuild = ""
|
var appBuild = ""
|
||||||
var appVersion = ""
|
var appVersion = ""
|
||||||
var route: Route?
|
var destination: Destination?
|
||||||
var sdkVersion = ""
|
var sdkVersion = ""
|
||||||
var settingsState: SettingsReducer.State
|
var settingsState: SettingsReducer.State
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ struct ProfileReducer: ReducerProtocol {
|
||||||
case onAppear
|
case onAppear
|
||||||
case onAppearFinished(String)
|
case onAppearFinished(String)
|
||||||
case settings(SettingsReducer.Action)
|
case settings(SettingsReducer.Action)
|
||||||
case updateRoute(ProfileReducer.State.Route?)
|
case updateDestination(ProfileReducer.State.Destination?)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Dependency(\.appVersion) var appVersion
|
@Dependency(\.appVersion) var appVersion
|
||||||
|
@ -60,8 +60,8 @@ struct ProfileReducer: ReducerProtocol {
|
||||||
case .back:
|
case .back:
|
||||||
return .none
|
return .none
|
||||||
|
|
||||||
case let .updateRoute(route):
|
case let .updateDestination(destination):
|
||||||
state.route = route
|
state.destination = destination
|
||||||
return .none
|
return .none
|
||||||
|
|
||||||
case .addressDetails:
|
case .addressDetails:
|
||||||
|
@ -88,22 +88,22 @@ extension ProfileStore {
|
||||||
// MARK: - ViewStore
|
// MARK: - ViewStore
|
||||||
|
|
||||||
extension ProfileViewStore {
|
extension ProfileViewStore {
|
||||||
var routeBinding: Binding<ProfileReducer.State.Route?> {
|
var destinationBinding: Binding<ProfileReducer.State.Destination?> {
|
||||||
self.binding(
|
self.binding(
|
||||||
get: \.route,
|
get: \.destination,
|
||||||
send: ProfileReducer.Action.updateRoute
|
send: ProfileReducer.Action.updateDestination
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
var bindingForAddressDetails: Binding<Bool> {
|
var bindingForAddressDetails: Binding<Bool> {
|
||||||
self.routeBinding.map(
|
self.destinationBinding.map(
|
||||||
extract: { $0 == .addressDetails },
|
extract: { $0 == .addressDetails },
|
||||||
embed: { $0 ? .addressDetails : nil }
|
embed: { $0 ? .addressDetails : nil }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
var bindingForSettings: Binding<Bool> {
|
var bindingForSettings: Binding<Bool> {
|
||||||
self.routeBinding.map(
|
self.destinationBinding.map(
|
||||||
extract: { $0 == .settings },
|
extract: { $0 == .settings },
|
||||||
embed: { $0 ? .settings : nil }
|
embed: { $0 ? .settings : nil }
|
||||||
)
|
)
|
||||||
|
@ -116,7 +116,7 @@ extension ProfileReducer.State {
|
||||||
static var placeholder: Self {
|
static var placeholder: Self {
|
||||||
.init(
|
.init(
|
||||||
addressDetailsState: .placeholder,
|
addressDetailsState: .placeholder,
|
||||||
route: nil,
|
destination: nil,
|
||||||
settingsState: .placeholder
|
settingsState: .placeholder
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ struct ProfileView: View {
|
||||||
.padding(30)
|
.padding(30)
|
||||||
|
|
||||||
Button(
|
Button(
|
||||||
action: { viewStore.send(.updateRoute(.addressDetails)) },
|
action: { viewStore.send(.updateDestination(.addressDetails)) },
|
||||||
label: { Text("See address details") }
|
label: { Text("See address details") }
|
||||||
)
|
)
|
||||||
.activeButtonStyle
|
.activeButtonStyle
|
||||||
|
@ -30,7 +30,7 @@ struct ProfileView: View {
|
||||||
.foregroundColor(Asset.Colors.TextField.Underline.purple.color)
|
.foregroundColor(Asset.Colors.TextField.Underline.purple.color)
|
||||||
|
|
||||||
Button(
|
Button(
|
||||||
action: { viewStore.send(.updateRoute(.settings)) },
|
action: { viewStore.send(.updateDestination(.settings)) },
|
||||||
label: { Text("Settings") }
|
label: { Text("Settings") }
|
||||||
)
|
)
|
||||||
.primaryButtonStyle
|
.primaryButtonStyle
|
||||||
|
|
|
@ -14,7 +14,7 @@ typealias RecoveryPhraseValidationFlowViewStore = ViewStore<RecoveryPhraseValida
|
||||||
|
|
||||||
struct RecoveryPhraseValidationFlowReducer: ReducerProtocol {
|
struct RecoveryPhraseValidationFlowReducer: ReducerProtocol {
|
||||||
struct State: Equatable {
|
struct State: Equatable {
|
||||||
enum Route: Equatable, CaseIterable {
|
enum Destination: Equatable, CaseIterable {
|
||||||
case validation
|
case validation
|
||||||
case success
|
case success
|
||||||
case failure
|
case failure
|
||||||
|
@ -27,7 +27,7 @@ struct RecoveryPhraseValidationFlowReducer: ReducerProtocol {
|
||||||
var missingIndices: [Int]
|
var missingIndices: [Int]
|
||||||
var missingWordChips: [PhraseChip.Kind]
|
var missingWordChips: [PhraseChip.Kind]
|
||||||
var validationWords: [ValidationWord]
|
var validationWords: [ValidationWord]
|
||||||
var route: Route?
|
var destination: Destination?
|
||||||
|
|
||||||
var isComplete: Bool {
|
var isComplete: Bool {
|
||||||
!validationWords.isEmpty && validationWords.count == missingIndices.count
|
!validationWords.isEmpty && validationWords.count == missingIndices.count
|
||||||
|
@ -40,7 +40,7 @@ struct RecoveryPhraseValidationFlowReducer: ReducerProtocol {
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Action: Equatable {
|
enum Action: Equatable {
|
||||||
case updateRoute(RecoveryPhraseValidationFlowReducer.State.Route?)
|
case updateDestination(RecoveryPhraseValidationFlowReducer.State.Destination?)
|
||||||
case reset
|
case reset
|
||||||
case move(wordChip: PhraseChip.Kind, intoGroup: Int)
|
case move(wordChip: PhraseChip.Kind, intoGroup: Int)
|
||||||
case succeed
|
case succeed
|
||||||
|
@ -60,8 +60,8 @@ struct RecoveryPhraseValidationFlowReducer: ReducerProtocol {
|
||||||
switch action {
|
switch action {
|
||||||
case .reset:
|
case .reset:
|
||||||
state = randomRecoveryPhrase.random(state.phrase)
|
state = randomRecoveryPhrase.random(state.phrase)
|
||||||
state.route = .validation
|
state.destination = .validation
|
||||||
// FIXME [#186]: Resetting causes route to be nil = preamble screen, hence setting the .validation. The transition back is not animated
|
// FIXME [#186]: Resetting causes destination to be nil = preamble screen, hence setting the .validation. The transition back is not animated
|
||||||
// though
|
// though
|
||||||
|
|
||||||
case let .move(wordChip, group):
|
case let .move(wordChip, group):
|
||||||
|
@ -91,20 +91,20 @@ struct RecoveryPhraseValidationFlowReducer: ReducerProtocol {
|
||||||
return .none
|
return .none
|
||||||
|
|
||||||
case .succeed:
|
case .succeed:
|
||||||
state.route = .success
|
state.destination = .success
|
||||||
|
|
||||||
case .fail:
|
case .fail:
|
||||||
state.route = .failure
|
state.destination = .failure
|
||||||
|
|
||||||
case .failureFeedback:
|
case .failureFeedback:
|
||||||
feedbackGenerator.generateErrorFeedback()
|
feedbackGenerator.generateErrorFeedback()
|
||||||
|
|
||||||
case .updateRoute(let route):
|
case .updateDestination(let destination):
|
||||||
guard let route = route else {
|
guard let destination = destination else {
|
||||||
state = randomRecoveryPhrase.random(state.phrase)
|
state = randomRecoveryPhrase.random(state.phrase)
|
||||||
return .none
|
return .none
|
||||||
}
|
}
|
||||||
state.route = route
|
state.destination = destination
|
||||||
|
|
||||||
case .proceedToHome:
|
case .proceedToHome:
|
||||||
break
|
break
|
||||||
|
@ -169,11 +169,11 @@ extension RecoveryPhrase.Group {
|
||||||
// MARK: - ViewStore
|
// MARK: - ViewStore
|
||||||
|
|
||||||
extension RecoveryPhraseValidationFlowViewStore {
|
extension RecoveryPhraseValidationFlowViewStore {
|
||||||
func bindingForRoute(_ route: RecoveryPhraseValidationFlowReducer.State.Route) -> Binding<Bool> {
|
func bindingForDestination(_ destination: RecoveryPhraseValidationFlowReducer.State.Destination) -> Binding<Bool> {
|
||||||
self.binding(
|
self.binding(
|
||||||
get: { $0.route == route },
|
get: { $0.destination == destination },
|
||||||
send: { isActive in
|
send: { isActive in
|
||||||
return .updateRoute(isActive ? route : nil)
|
return .updateDestination(isActive ? destination : nil)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -182,27 +182,27 @@ extension RecoveryPhraseValidationFlowViewStore {
|
||||||
extension RecoveryPhraseValidationFlowViewStore {
|
extension RecoveryPhraseValidationFlowViewStore {
|
||||||
var bindingForValidation: Binding<Bool> {
|
var bindingForValidation: Binding<Bool> {
|
||||||
self.binding(
|
self.binding(
|
||||||
get: { $0.route != nil },
|
get: { $0.destination != nil },
|
||||||
send: { isActive in
|
send: { isActive in
|
||||||
return .updateRoute(isActive ? .validation : nil)
|
return .updateDestination(isActive ? .validation : nil)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
var bindingForSuccess: Binding<Bool> {
|
var bindingForSuccess: Binding<Bool> {
|
||||||
self.binding(
|
self.binding(
|
||||||
get: { $0.route == .success },
|
get: { $0.destination == .success },
|
||||||
send: { isActive in
|
send: { isActive in
|
||||||
return .updateRoute(isActive ? .success : .validation)
|
return .updateDestination(isActive ? .success : .validation)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
var bindingForFailure: Binding<Bool> {
|
var bindingForFailure: Binding<Bool> {
|
||||||
self.binding(
|
self.binding(
|
||||||
get: { $0.route == .failure },
|
get: { $0.destination == .failure },
|
||||||
send: { isActive in
|
send: { isActive in
|
||||||
return .updateRoute(isActive ? .failure : .validation)
|
return .updateDestination(isActive ? .failure : .validation)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -221,7 +221,7 @@ extension RecoveryPhraseValidationFlowReducer.State {
|
||||||
.unassigned(word: "garlic")
|
.unassigned(word: "garlic")
|
||||||
],
|
],
|
||||||
validationWords: [],
|
validationWords: [],
|
||||||
route: nil
|
destination: nil
|
||||||
)
|
)
|
||||||
|
|
||||||
static let placeholderStep1 = RecoveryPhraseValidationFlowReducer.State(
|
static let placeholderStep1 = RecoveryPhraseValidationFlowReducer.State(
|
||||||
|
@ -236,7 +236,7 @@ extension RecoveryPhraseValidationFlowReducer.State {
|
||||||
validationWords: [
|
validationWords: [
|
||||||
.init(groupIndex: 2, word: "morning")
|
.init(groupIndex: 2, word: "morning")
|
||||||
],
|
],
|
||||||
route: nil
|
destination: nil
|
||||||
)
|
)
|
||||||
|
|
||||||
static let placeholderStep2 = RecoveryPhraseValidationFlowReducer.State(
|
static let placeholderStep2 = RecoveryPhraseValidationFlowReducer.State(
|
||||||
|
@ -252,7 +252,7 @@ extension RecoveryPhraseValidationFlowReducer.State {
|
||||||
.init(groupIndex: 2, word: "morning"),
|
.init(groupIndex: 2, word: "morning"),
|
||||||
.init(groupIndex: 0, word: "thank")
|
.init(groupIndex: 0, word: "thank")
|
||||||
],
|
],
|
||||||
route: nil
|
destination: nil
|
||||||
)
|
)
|
||||||
|
|
||||||
static let placeholderStep3 = RecoveryPhraseValidationFlowReducer.State(
|
static let placeholderStep3 = RecoveryPhraseValidationFlowReducer.State(
|
||||||
|
@ -269,7 +269,7 @@ extension RecoveryPhraseValidationFlowReducer.State {
|
||||||
.init(groupIndex: 0, word: "thank"),
|
.init(groupIndex: 0, word: "thank"),
|
||||||
.init(groupIndex: 3, word: "garlic")
|
.init(groupIndex: 3, word: "garlic")
|
||||||
],
|
],
|
||||||
route: nil
|
destination: nil
|
||||||
)
|
)
|
||||||
|
|
||||||
static let placeholderStep4 = RecoveryPhraseValidationFlowReducer.State(
|
static let placeholderStep4 = RecoveryPhraseValidationFlowReducer.State(
|
||||||
|
@ -287,7 +287,7 @@ extension RecoveryPhraseValidationFlowReducer.State {
|
||||||
.init(groupIndex: 3, word: "garlic"),
|
.init(groupIndex: 3, word: "garlic"),
|
||||||
.init(groupIndex: 1, word: "boil")
|
.init(groupIndex: 1, word: "boil")
|
||||||
],
|
],
|
||||||
route: nil
|
destination: nil
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ struct RecoveryPhraseValidationFlowView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
Button(
|
Button(
|
||||||
action: { viewStore.send(.updateRoute(.validation)) },
|
action: { viewStore.send(.updateDestination(.validation)) },
|
||||||
label: { Text("recoveryPhraseTestPreamble.button.goNext") }
|
label: { Text("recoveryPhraseTestPreamble.button.goNext") }
|
||||||
)
|
)
|
||||||
.activeButtonStyle
|
.activeButtonStyle
|
||||||
|
|
|
@ -6,7 +6,7 @@ typealias SandboxViewStore = ViewStore<SandboxReducer.State, SandboxReducer.Acti
|
||||||
|
|
||||||
struct SandboxReducer: ReducerProtocol {
|
struct SandboxReducer: ReducerProtocol {
|
||||||
struct State: Equatable {
|
struct State: Equatable {
|
||||||
enum Route: Equatable, CaseIterable {
|
enum Destination: Equatable, CaseIterable {
|
||||||
case history
|
case history
|
||||||
case send
|
case send
|
||||||
case recoveryPhraseDisplay
|
case recoveryPhraseDisplay
|
||||||
|
@ -16,11 +16,11 @@ struct SandboxReducer: ReducerProtocol {
|
||||||
}
|
}
|
||||||
var walletEventsState: WalletEventsFlowReducer.State
|
var walletEventsState: WalletEventsFlowReducer.State
|
||||||
var profileState: ProfileReducer.State
|
var profileState: ProfileReducer.State
|
||||||
var route: Route?
|
var destination: Destination?
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Action: Equatable {
|
enum Action: Equatable {
|
||||||
case updateRoute(SandboxReducer.State.Route?)
|
case updateDestination(SandboxReducer.State.Destination?)
|
||||||
case walletEvents(WalletEventsFlowReducer.Action)
|
case walletEvents(WalletEventsFlowReducer.Action)
|
||||||
case profile(ProfileReducer.Action)
|
case profile(ProfileReducer.Action)
|
||||||
case reset
|
case reset
|
||||||
|
@ -28,8 +28,8 @@ struct SandboxReducer: ReducerProtocol {
|
||||||
|
|
||||||
func reduce(into state: inout State, action: Action) -> ComposableArchitecture.EffectTask<Action> {
|
func reduce(into state: inout State, action: Action) -> ComposableArchitecture.EffectTask<Action> {
|
||||||
switch action {
|
switch action {
|
||||||
case let .updateRoute(route):
|
case let .updateDestination(destination):
|
||||||
state.route = route
|
state.destination = destination
|
||||||
return .none
|
return .none
|
||||||
|
|
||||||
case let .walletEvents(walletEventsAction):
|
case let .walletEvents(walletEventsAction):
|
||||||
|
@ -73,22 +73,22 @@ extension SandboxViewStore {
|
||||||
func toggleSelectedTransaction() {
|
func toggleSelectedTransaction() {
|
||||||
let isAlreadySelected = (self.selectedTranactionID != nil)
|
let isAlreadySelected = (self.selectedTranactionID != nil)
|
||||||
let walletEvent = self.walletEventsState.walletEvents[5]
|
let walletEvent = self.walletEventsState.walletEvents[5]
|
||||||
let newRoute = isAlreadySelected ? nil : WalletEventsFlowReducer.State.Route.showWalletEvent(walletEvent)
|
let newDestination = isAlreadySelected ? nil : WalletEventsFlowReducer.State.Destination.showWalletEvent(walletEvent)
|
||||||
send(.walletEvents(.updateRoute(newRoute)))
|
send(.walletEvents(.updateDestination(newDestination)))
|
||||||
}
|
}
|
||||||
|
|
||||||
var selectedTranactionID: String? {
|
var selectedTranactionID: String? {
|
||||||
self.walletEventsState
|
self.walletEventsState
|
||||||
.route
|
.destination
|
||||||
.flatMap(/WalletEventsFlowReducer.State.Route.showWalletEvent)
|
.flatMap(/WalletEventsFlowReducer.State.Destination.showWalletEvent)
|
||||||
.map(\.id)
|
.map(\.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func bindingForRoute(_ route: SandboxReducer.State.Route) -> Binding<Bool> {
|
func bindingForDestination(_ destination: SandboxReducer.State.Destination) -> Binding<Bool> {
|
||||||
self.binding(
|
self.binding(
|
||||||
get: { $0.route == route },
|
get: { $0.destination == destination },
|
||||||
send: { isActive in
|
send: { isActive in
|
||||||
return .updateRoute(isActive ? route : nil)
|
return .updateDestination(isActive ? destination : nil)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ extension SandboxReducer.State {
|
||||||
.init(
|
.init(
|
||||||
walletEventsState: .placeHolder,
|
walletEventsState: .placeHolder,
|
||||||
profileState: .placeholder,
|
profileState: .placeholder,
|
||||||
route: nil
|
destination: nil
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,7 @@ extension SandboxStore {
|
||||||
initialState: SandboxReducer.State(
|
initialState: SandboxReducer.State(
|
||||||
walletEventsState: .placeHolder,
|
walletEventsState: .placeHolder,
|
||||||
profileState: .placeholder,
|
profileState: .placeholder,
|
||||||
route: nil
|
destination: nil
|
||||||
),
|
),
|
||||||
reducer: SandboxReducer()
|
reducer: SandboxReducer()
|
||||||
)
|
)
|
||||||
|
|
|
@ -2,25 +2,25 @@ import SwiftUI
|
||||||
import ComposableArchitecture
|
import ComposableArchitecture
|
||||||
|
|
||||||
struct SandboxView: View {
|
struct SandboxView: View {
|
||||||
struct SandboxRouteValue: Identifiable {
|
struct SandboxDestinationValue: Identifiable {
|
||||||
let id: Int
|
let id: Int
|
||||||
let route: SandboxReducer.State.Route
|
let destination: SandboxReducer.State.Destination
|
||||||
}
|
}
|
||||||
|
|
||||||
let store: SandboxStore
|
let store: SandboxStore
|
||||||
|
|
||||||
var navigationRouteValues: [SandboxRouteValue] = SandboxReducer.State.Route.allCases
|
var navigationDestinationValues: [SandboxDestinationValue] = SandboxReducer.State.Destination.allCases
|
||||||
.enumerated()
|
.enumerated()
|
||||||
.filter { $0.1 != .history }
|
.filter { $0.1 != .history }
|
||||||
.map { SandboxRouteValue(id: $0.0, route: $0.1) }
|
.map { SandboxDestinationValue(id: $0.0, destination: $0.1) }
|
||||||
|
|
||||||
var modalRoutes: [SandboxRouteValue] = SandboxReducer.State.Route.allCases
|
var modalDestinations: [SandboxDestinationValue] = SandboxReducer.State.Destination.allCases
|
||||||
.enumerated()
|
.enumerated()
|
||||||
.filter { $0.1 == .history }
|
.filter { $0.1 == .history }
|
||||||
.map { SandboxRouteValue(id: $0.0, route: $0.1) }
|
.map { SandboxDestinationValue(id: $0.0, destination: $0.1) }
|
||||||
|
|
||||||
@ViewBuilder func view(for route: SandboxReducer.State.Route) -> some View {
|
@ViewBuilder func view(for destination: SandboxReducer.State.Destination) -> some View {
|
||||||
switch route {
|
switch destination {
|
||||||
case .history:
|
case .history:
|
||||||
WalletEventsFlowView(store: store.historyStore())
|
WalletEventsFlowView(store: store.historyStore())
|
||||||
case .send:
|
case .send:
|
||||||
|
@ -45,23 +45,23 @@ struct SandboxView: View {
|
||||||
WithViewStore(store) { viewStore in
|
WithViewStore(store) { viewStore in
|
||||||
VStack {
|
VStack {
|
||||||
List {
|
List {
|
||||||
Section(header: Text("Navigation Stack Routes")) {
|
Section(header: Text("Navigation Stack Destinations")) {
|
||||||
ForEach(navigationRouteValues) { routeValue in
|
ForEach(navigationDestinationValues) { destinationValue in
|
||||||
Text("\(String(describing: routeValue.route))")
|
Text("\(String(describing: destinationValue.destination))")
|
||||||
.navigationLink(
|
.navigationLink(
|
||||||
isActive: viewStore.bindingForRoute(routeValue.route),
|
isActive: viewStore.bindingForDestination(destinationValue.destination),
|
||||||
destination: {
|
destination: {
|
||||||
view(for: routeValue.route)
|
view(for: destinationValue.destination)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Section(header: Text("Modal Routes")) {
|
Section(header: Text("Modal Destinations")) {
|
||||||
ForEach(modalRoutes) { routeValue in
|
ForEach(modalDestinations) { destinationValue in
|
||||||
Button(
|
Button(
|
||||||
action: { viewStore.send(.updateRoute(routeValue.route)) },
|
action: { viewStore.send(.updateDestination(destinationValue.destination)) },
|
||||||
label: { Text("\(String(describing: routeValue.route))") }
|
label: { Text("\(String(describing: destinationValue.destination))") }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,13 +80,13 @@ struct SandboxView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.fullScreenCover(
|
.fullScreenCover(
|
||||||
isPresented: viewStore.bindingForRoute(.history),
|
isPresented: viewStore.bindingForDestination(.history),
|
||||||
content: {
|
content: {
|
||||||
NavigationView {
|
NavigationView {
|
||||||
WalletEventsFlowView(store: store.historyStore())
|
WalletEventsFlowView(store: store.historyStore())
|
||||||
.toolbar {
|
.toolbar {
|
||||||
ToolbarItem {
|
ToolbarItem {
|
||||||
Button("Done") { viewStore.send(.updateRoute(nil)) }
|
Button("Done") { viewStore.send(.updateDestination(nil)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ struct SendFlowReducer: ReducerProtocol {
|
||||||
private enum SyncStatusUpdatesID {}
|
private enum SyncStatusUpdatesID {}
|
||||||
|
|
||||||
struct State: Equatable {
|
struct State: Equatable {
|
||||||
enum Route: Equatable {
|
enum Destination: Equatable {
|
||||||
case confirmation
|
case confirmation
|
||||||
case inProgress
|
case inProgress
|
||||||
case success
|
case success
|
||||||
|
@ -27,7 +27,7 @@ struct SendFlowReducer: ReducerProtocol {
|
||||||
var addMemoState: Bool
|
var addMemoState: Bool
|
||||||
var isSendingTransaction = false
|
var isSendingTransaction = false
|
||||||
var memoState: MultiLineTextFieldReducer.State
|
var memoState: MultiLineTextFieldReducer.State
|
||||||
var route: Route?
|
var destination: Destination?
|
||||||
var shieldedBalance = WalletBalance.zero
|
var shieldedBalance = WalletBalance.zero
|
||||||
var transactionAddressInputState: TransactionAddressTextFieldReducer.State
|
var transactionAddressInputState: TransactionAddressTextFieldReducer.State
|
||||||
var transactionAmountInputState: TransactionAmountTextFieldReducer.State
|
var transactionAmountInputState: TransactionAmountTextFieldReducer.State
|
||||||
|
@ -83,7 +83,7 @@ struct SendFlowReducer: ReducerProtocol {
|
||||||
case synchronizerStateChanged(SDKSynchronizerState)
|
case synchronizerStateChanged(SDKSynchronizerState)
|
||||||
case transactionAddressInput(TransactionAddressTextFieldReducer.Action)
|
case transactionAddressInput(TransactionAddressTextFieldReducer.Action)
|
||||||
case transactionAmountInput(TransactionAmountTextFieldReducer.Action)
|
case transactionAmountInput(TransactionAmountTextFieldReducer.Action)
|
||||||
case updateRoute(SendFlowReducer.State.Route?)
|
case updateDestination(SendFlowReducer.State.Destination?)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Dependency(\.derivationTool) var derivationTool
|
@Dependency(\.derivationTool) var derivationTool
|
||||||
|
@ -115,27 +115,27 @@ struct SendFlowReducer: ReducerProtocol {
|
||||||
case .addMemo:
|
case .addMemo:
|
||||||
return .none
|
return .none
|
||||||
|
|
||||||
case .updateRoute(.done):
|
case .updateDestination(.done):
|
||||||
state.route = nil
|
state.destination = nil
|
||||||
state.memoState.text = ""
|
state.memoState.text = ""
|
||||||
state.transactionAmountInputState.textFieldState.text = ""
|
state.transactionAmountInputState.textFieldState.text = ""
|
||||||
state.transactionAmountInputState.amount = 0
|
state.transactionAmountInputState.amount = 0
|
||||||
state.transactionAddressInputState.textFieldState.text = ""
|
state.transactionAddressInputState.textFieldState.text = ""
|
||||||
return .none
|
return .none
|
||||||
|
|
||||||
case .updateRoute(.failure):
|
case .updateDestination(.failure):
|
||||||
state.route = .failure
|
state.destination = .failure
|
||||||
state.isSendingTransaction = false
|
state.isSendingTransaction = false
|
||||||
return .none
|
return .none
|
||||||
|
|
||||||
case .updateRoute(.confirmation):
|
case .updateDestination(.confirmation):
|
||||||
state.amount = Zatoshi(state.transactionAmountInputState.amount)
|
state.amount = Zatoshi(state.transactionAmountInputState.amount)
|
||||||
state.address = state.transactionAddressInputState.textFieldState.text
|
state.address = state.transactionAddressInputState.textFieldState.text
|
||||||
state.route = .confirmation
|
state.destination = .confirmation
|
||||||
return .none
|
return .none
|
||||||
|
|
||||||
case let .updateRoute(route):
|
case let .updateDestination(destination):
|
||||||
state.route = route
|
state.destination = destination
|
||||||
return .none
|
return .none
|
||||||
|
|
||||||
case .sendConfirmationPressed:
|
case .sendConfirmationPressed:
|
||||||
|
@ -169,20 +169,20 @@ struct SendFlowReducer: ReducerProtocol {
|
||||||
.eraseToEffect()
|
.eraseToEffect()
|
||||||
|
|
||||||
return .concatenate(
|
return .concatenate(
|
||||||
Effect(value: .updateRoute(.inProgress)),
|
Effect(value: .updateDestination(.inProgress)),
|
||||||
sendTransActionEffect
|
sendTransActionEffect
|
||||||
)
|
)
|
||||||
} catch {
|
} catch {
|
||||||
return Effect(value: .updateRoute(.failure))
|
return Effect(value: .updateDestination(.failure))
|
||||||
}
|
}
|
||||||
|
|
||||||
case .sendTransactionResult(let result):
|
case .sendTransactionResult(let result):
|
||||||
state.isSendingTransaction = false
|
state.isSendingTransaction = false
|
||||||
do {
|
do {
|
||||||
_ = try result.get()
|
_ = try result.get()
|
||||||
return Effect(value: .updateRoute(.success))
|
return Effect(value: .updateDestination(.success))
|
||||||
} catch {
|
} catch {
|
||||||
return Effect(value: .updateRoute(.failure))
|
return Effect(value: .updateDestination(.failure))
|
||||||
}
|
}
|
||||||
|
|
||||||
case .transactionAmountInput:
|
case .transactionAmountInput:
|
||||||
|
@ -239,47 +239,47 @@ extension SendFlowStore {
|
||||||
// MARK: - ViewStore
|
// MARK: - ViewStore
|
||||||
|
|
||||||
extension SendFlowViewStore {
|
extension SendFlowViewStore {
|
||||||
var routeBinding: Binding<SendFlowReducer.State.Route?> {
|
var destinationBinding: Binding<SendFlowReducer.State.Destination?> {
|
||||||
self.binding(
|
self.binding(
|
||||||
get: \.route,
|
get: \.destination,
|
||||||
send: SendFlowReducer.Action.updateRoute
|
send: SendFlowReducer.Action.updateDestination
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
var bindingForConfirmation: Binding<Bool> {
|
var bindingForConfirmation: Binding<Bool> {
|
||||||
self.routeBinding.map(
|
self.destinationBinding.map(
|
||||||
extract: {
|
extract: {
|
||||||
$0 == .confirmation ||
|
$0 == .confirmation ||
|
||||||
$0 == .inProgress ||
|
$0 == .inProgress ||
|
||||||
$0 == .success ||
|
$0 == .success ||
|
||||||
$0 == .failure
|
$0 == .failure
|
||||||
},
|
},
|
||||||
embed: { $0 ? SendFlowReducer.State.Route.confirmation : nil }
|
embed: { $0 ? SendFlowReducer.State.Destination.confirmation : nil }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
var bindingForInProgress: Binding<Bool> {
|
var bindingForInProgress: Binding<Bool> {
|
||||||
self.routeBinding.map(
|
self.destinationBinding.map(
|
||||||
extract: {
|
extract: {
|
||||||
$0 == .inProgress ||
|
$0 == .inProgress ||
|
||||||
$0 == .success ||
|
$0 == .success ||
|
||||||
$0 == .failure
|
$0 == .failure
|
||||||
},
|
},
|
||||||
embed: { $0 ? SendFlowReducer.State.Route.inProgress : SendFlowReducer.State.Route.confirmation }
|
embed: { $0 ? SendFlowReducer.State.Destination.inProgress : SendFlowReducer.State.Destination.confirmation }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
var bindingForSuccess: Binding<Bool> {
|
var bindingForSuccess: Binding<Bool> {
|
||||||
self.routeBinding.map(
|
self.destinationBinding.map(
|
||||||
extract: { $0 == .success },
|
extract: { $0 == .success },
|
||||||
embed: { _ in SendFlowReducer.State.Route.success }
|
embed: { _ in SendFlowReducer.State.Destination.success }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
var bindingForFailure: Binding<Bool> {
|
var bindingForFailure: Binding<Bool> {
|
||||||
self.routeBinding.map(
|
self.destinationBinding.map(
|
||||||
extract: { $0 == .failure },
|
extract: { $0 == .failure },
|
||||||
embed: { _ in SendFlowReducer.State.Route.failure }
|
embed: { _ in SendFlowReducer.State.Destination.failure }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -291,7 +291,7 @@ extension SendFlowReducer.State {
|
||||||
.init(
|
.init(
|
||||||
addMemoState: true,
|
addMemoState: true,
|
||||||
memoState: .placeholder,
|
memoState: .placeholder,
|
||||||
route: nil,
|
destination: nil,
|
||||||
transactionAddressInputState: .placeholder,
|
transactionAddressInputState: .placeholder,
|
||||||
transactionAmountInputState: .amount
|
transactionAmountInputState: .amount
|
||||||
)
|
)
|
||||||
|
@ -301,7 +301,7 @@ extension SendFlowReducer.State {
|
||||||
.init(
|
.init(
|
||||||
addMemoState: true,
|
addMemoState: true,
|
||||||
memoState: .placeholder,
|
memoState: .placeholder,
|
||||||
route: nil,
|
destination: nil,
|
||||||
transactionAddressInputState: .placeholder,
|
transactionAddressInputState: .placeholder,
|
||||||
transactionAmountInputState: .placeholder
|
transactionAmountInputState: .placeholder
|
||||||
)
|
)
|
||||||
|
|
|
@ -36,7 +36,7 @@ struct SendFLowView_Previews: PreviewProvider {
|
||||||
initialState: .init(
|
initialState: .init(
|
||||||
addMemoState: true,
|
addMemoState: true,
|
||||||
memoState: .placeholder,
|
memoState: .placeholder,
|
||||||
route: nil,
|
destination: nil,
|
||||||
transactionAddressInputState: .placeholder,
|
transactionAddressInputState: .placeholder,
|
||||||
transactionAmountInputState: .placeholder
|
transactionAmountInputState: .placeholder
|
||||||
),
|
),
|
||||||
|
|
|
@ -71,7 +71,7 @@ struct CreateTransaction: View {
|
||||||
.padding()
|
.padding()
|
||||||
|
|
||||||
Button(
|
Button(
|
||||||
action: { viewStore.send(.updateRoute(.confirmation)) },
|
action: { viewStore.send(.updateDestination(.confirmation)) },
|
||||||
label: { Text("Send") }
|
label: { Text("Send") }
|
||||||
)
|
)
|
||||||
.activeButtonStyle
|
.activeButtonStyle
|
||||||
|
|
|
@ -10,7 +10,7 @@ struct TransactionFailed: View {
|
||||||
|
|
||||||
Button(
|
Button(
|
||||||
action: {
|
action: {
|
||||||
viewStore.send(.updateRoute(.done))
|
viewStore.send(.updateDestination(.done))
|
||||||
},
|
},
|
||||||
label: { Text("Close") }
|
label: { Text("Close") }
|
||||||
)
|
)
|
||||||
|
|
|
@ -10,7 +10,7 @@ struct TransactionSent: View {
|
||||||
|
|
||||||
Button(
|
Button(
|
||||||
action: {
|
action: {
|
||||||
viewStore.send(.updateRoute(.done))
|
viewStore.send(.updateDestination(.done))
|
||||||
},
|
},
|
||||||
label: { Text("Close") }
|
label: { Text("Close") }
|
||||||
)
|
)
|
||||||
|
|
|
@ -6,13 +6,13 @@ typealias SettingsViewStore = ViewStore<SettingsReducer.State, SettingsReducer.A
|
||||||
|
|
||||||
struct SettingsReducer: ReducerProtocol {
|
struct SettingsReducer: ReducerProtocol {
|
||||||
struct State: Equatable {
|
struct State: Equatable {
|
||||||
enum Route {
|
enum Destination {
|
||||||
case backupPhrase
|
case backupPhrase
|
||||||
}
|
}
|
||||||
|
|
||||||
var phraseDisplayState: RecoveryPhraseDisplayReducer.State
|
var phraseDisplayState: RecoveryPhraseDisplayReducer.State
|
||||||
var rescanDialog: ConfirmationDialogState<SettingsReducer.Action>?
|
var rescanDialog: ConfirmationDialogState<SettingsReducer.Action>?
|
||||||
var route: Route?
|
var destination: Destination?
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Action: Equatable {
|
enum Action: Equatable {
|
||||||
|
@ -23,7 +23,7 @@ struct SettingsReducer: ReducerProtocol {
|
||||||
case phraseDisplay(RecoveryPhraseDisplayReducer.Action)
|
case phraseDisplay(RecoveryPhraseDisplayReducer.Action)
|
||||||
case quickRescan
|
case quickRescan
|
||||||
case rescanBlockchain
|
case rescanBlockchain
|
||||||
case updateRoute(SettingsReducer.State.Route?)
|
case updateDestination(SettingsReducer.State.Destination?)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Dependency(\.localAuthentication) var localAuthentication
|
@Dependency(\.localAuthentication) var localAuthentication
|
||||||
|
@ -47,7 +47,7 @@ struct SettingsReducer: ReducerProtocol {
|
||||||
let phraseWords = try mnemonic.asWords(storedWallet.seedPhrase)
|
let phraseWords = try mnemonic.asWords(storedWallet.seedPhrase)
|
||||||
let recoveryPhrase = RecoveryPhrase(words: phraseWords)
|
let recoveryPhrase = RecoveryPhrase(words: phraseWords)
|
||||||
state.phraseDisplayState.phrase = recoveryPhrase
|
state.phraseDisplayState.phrase = recoveryPhrase
|
||||||
return Effect(value: .updateRoute(.backupPhrase))
|
return Effect(value: .updateDestination(.backupPhrase))
|
||||||
} catch {
|
} catch {
|
||||||
// TODO [#201]: - merge with issue 201 (https://github.com/zcash/secant-ios-wallet/issues/201) and its Error States
|
// TODO [#201]: - merge with issue 201 (https://github.com/zcash/secant-ios-wallet/issues/201) and its Error States
|
||||||
return .none
|
return .none
|
||||||
|
@ -70,11 +70,11 @@ struct SettingsReducer: ReducerProtocol {
|
||||||
return .none
|
return .none
|
||||||
|
|
||||||
case .phraseDisplay:
|
case .phraseDisplay:
|
||||||
state.route = nil
|
state.destination = nil
|
||||||
return .none
|
return .none
|
||||||
|
|
||||||
case .updateRoute(let route):
|
case .updateDestination(let destination):
|
||||||
state.route = route
|
state.destination = destination
|
||||||
return .none
|
return .none
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,15 +88,15 @@ struct SettingsReducer: ReducerProtocol {
|
||||||
// MARK: - ViewStore
|
// MARK: - ViewStore
|
||||||
|
|
||||||
extension SettingsViewStore {
|
extension SettingsViewStore {
|
||||||
var routeBinding: Binding<SettingsReducer.State.Route?> {
|
var destinationBinding: Binding<SettingsReducer.State.Destination?> {
|
||||||
self.binding(
|
self.binding(
|
||||||
get: \.route,
|
get: \.destination,
|
||||||
send: SettingsReducer.Action.updateRoute
|
send: SettingsReducer.Action.updateDestination
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
var bindingForBackupPhrase: Binding<Bool> {
|
var bindingForBackupPhrase: Binding<Bool> {
|
||||||
self.routeBinding.map(
|
self.destinationBinding.map(
|
||||||
extract: { $0 == .backupPhrase },
|
extract: { $0 == .backupPhrase },
|
||||||
embed: { $0 ? .backupPhrase : nil }
|
embed: { $0 ? .backupPhrase : nil }
|
||||||
)
|
)
|
||||||
|
|
|
@ -9,13 +9,13 @@ struct WalletEventsFlowReducer: ReducerProtocol {
|
||||||
private enum CancelId {}
|
private enum CancelId {}
|
||||||
|
|
||||||
struct State: Equatable {
|
struct State: Equatable {
|
||||||
enum Route: Equatable {
|
enum Destination: Equatable {
|
||||||
case latest
|
case latest
|
||||||
case all
|
case all
|
||||||
case showWalletEvent(WalletEvent)
|
case showWalletEvent(WalletEvent)
|
||||||
}
|
}
|
||||||
|
|
||||||
var route: Route?
|
var destination: Destination?
|
||||||
|
|
||||||
@BindableState var alert: AlertState<WalletEventsFlowReducer.Action>?
|
@BindableState var alert: AlertState<WalletEventsFlowReducer.Action>?
|
||||||
var latestMinedHeight: BlockHeight?
|
var latestMinedHeight: BlockHeight?
|
||||||
|
@ -31,7 +31,7 @@ struct WalletEventsFlowReducer: ReducerProtocol {
|
||||||
case onAppear
|
case onAppear
|
||||||
case onDisappear
|
case onDisappear
|
||||||
case openBlockExplorer(URL?)
|
case openBlockExplorer(URL?)
|
||||||
case updateRoute(WalletEventsFlowReducer.State.Route?)
|
case updateDestination(WalletEventsFlowReducer.State.Destination?)
|
||||||
case replyTo(String)
|
case replyTo(String)
|
||||||
case synchronizerStateChanged(SDKSynchronizerState)
|
case synchronizerStateChanged(SDKSynchronizerState)
|
||||||
case updateWalletEvents([WalletEvent])
|
case updateWalletEvents([WalletEvent])
|
||||||
|
@ -76,14 +76,14 @@ struct WalletEventsFlowReducer: ReducerProtocol {
|
||||||
state.walletEvents = IdentifiedArrayOf(uniqueElements: sortedWalletEvents)
|
state.walletEvents = IdentifiedArrayOf(uniqueElements: sortedWalletEvents)
|
||||||
return .none
|
return .none
|
||||||
|
|
||||||
case .updateRoute(.showWalletEvent(let walletEvent)):
|
case .updateDestination(.showWalletEvent(let walletEvent)):
|
||||||
state.selectedWalletEvent = walletEvent
|
state.selectedWalletEvent = walletEvent
|
||||||
state.route = .showWalletEvent(walletEvent)
|
state.destination = .showWalletEvent(walletEvent)
|
||||||
return .none
|
return .none
|
||||||
|
|
||||||
case .updateRoute(let route):
|
case .updateDestination(let destination):
|
||||||
state.route = route
|
state.destination = destination
|
||||||
if route == nil {
|
if destination == nil {
|
||||||
state.selectedWalletEvent = nil
|
state.selectedWalletEvent = nil
|
||||||
}
|
}
|
||||||
return .none
|
return .none
|
||||||
|
@ -130,7 +130,7 @@ struct WalletEventsFlowReducer: ReducerProtocol {
|
||||||
// MARK: - ViewStore
|
// MARK: - ViewStore
|
||||||
|
|
||||||
extension WalletEventsFlowViewStore {
|
extension WalletEventsFlowViewStore {
|
||||||
private typealias Route = WalletEventsFlowReducer.State.Route
|
private typealias Destination = WalletEventsFlowReducer.State.Destination
|
||||||
|
|
||||||
func bindingForSelectedWalletEvent(_ walletEvent: WalletEvent?) -> Binding<Bool> {
|
func bindingForSelectedWalletEvent(_ walletEvent: WalletEvent?) -> Binding<Bool> {
|
||||||
self.binding(
|
self.binding(
|
||||||
|
@ -139,14 +139,14 @@ extension WalletEventsFlowViewStore {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return $0.route.map(/WalletEventsFlowReducer.State.Route.showWalletEvent) == walletEvent
|
return $0.destination.map(/WalletEventsFlowReducer.State.Destination.showWalletEvent) == walletEvent
|
||||||
},
|
},
|
||||||
send: { isActive in
|
send: { isActive in
|
||||||
guard let walletEvent = walletEvent else {
|
guard let walletEvent = walletEvent else {
|
||||||
return WalletEventsFlowReducer.Action.updateRoute(nil)
|
return WalletEventsFlowReducer.Action.updateDestination(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
return WalletEventsFlowReducer.Action.updateRoute( isActive ? WalletEventsFlowReducer.State.Route.showWalletEvent(walletEvent) : nil)
|
return WalletEventsFlowReducer.Action.updateDestination( isActive ? WalletEventsFlowReducer.State.Destination.showWalletEvent(walletEvent) : nil)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ extension WalletEventsFlowView {
|
||||||
ForEach(viewStore.walletEvents) { walletEvent in
|
ForEach(viewStore.walletEvents) { walletEvent in
|
||||||
walletEvent.rowView(viewStore)
|
walletEvent.rowView(viewStore)
|
||||||
.onTapGesture {
|
.onTapGesture {
|
||||||
viewStore.send(.updateRoute(.showWalletEvent(walletEvent)))
|
viewStore.send(.updateDestination(.showWalletEvent(walletEvent)))
|
||||||
}
|
}
|
||||||
.listRowInsets(EdgeInsets())
|
.listRowInsets(EdgeInsets())
|
||||||
.foregroundColor(Asset.Colors.Text.body.color)
|
.foregroundColor(Asset.Colors.Text.body.color)
|
||||||
|
@ -54,7 +54,7 @@ extension WalletEventsFlowView {
|
||||||
HStack(spacing: 0) {
|
HStack(spacing: 0) {
|
||||||
VStack {
|
VStack {
|
||||||
Button {
|
Button {
|
||||||
viewStore.send(.updateRoute(.latest))
|
viewStore.send(.updateDestination(.latest))
|
||||||
} label: {
|
} label: {
|
||||||
Text("Latest")
|
Text("Latest")
|
||||||
.font(.custom(FontFamily.Rubik.regular.name, size: 18))
|
.font(.custom(FontFamily.Rubik.regular.name, size: 18))
|
||||||
|
@ -70,7 +70,7 @@ extension WalletEventsFlowView {
|
||||||
|
|
||||||
VStack {
|
VStack {
|
||||||
Button {
|
Button {
|
||||||
viewStore.send(.updateRoute(.all))
|
viewStore.send(.updateDestination(.all))
|
||||||
} label: {
|
} label: {
|
||||||
Text("All")
|
Text("All")
|
||||||
.font(.custom(FontFamily.Rubik.regular.name, size: 18))
|
.font(.custom(FontFamily.Rubik.regular.name, size: 18))
|
||||||
|
|
|
@ -34,7 +34,7 @@ class AppInitializationTests: XCTestCase {
|
||||||
validationWords: [
|
validationWords: [
|
||||||
.init(groupIndex: 2, word: "dizzy")
|
.init(groupIndex: 2, word: "dizzy")
|
||||||
],
|
],
|
||||||
route: nil
|
destination: nil
|
||||||
)
|
)
|
||||||
|
|
||||||
let recoveryPhraseRandomizer = RecoveryPhraseRandomizerClient(
|
let recoveryPhraseRandomizer = RecoveryPhraseRandomizerClient(
|
||||||
|
@ -122,9 +122,9 @@ class AppInitializationTests: XCTestCase {
|
||||||
await testScheduler.advance(by: 3.00)
|
await testScheduler.advance(by: 3.00)
|
||||||
|
|
||||||
// ad 5.
|
// ad 5.
|
||||||
await store.receive(.updateRoute(.phraseDisplay)) { state in
|
await store.receive(.updateDestination(.phraseDisplay)) { state in
|
||||||
state.prevRoute = .welcome
|
state.prevDestination = .welcome
|
||||||
state.internalRoute = .phraseDisplay
|
state.internalDestination = .phraseDisplay
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,9 +191,9 @@ class AppInitializationTests: XCTestCase {
|
||||||
store.receive(.respondToWalletInitializationState(.uninitialized))
|
store.receive(.respondToWalletInitializationState(.uninitialized))
|
||||||
|
|
||||||
// ad 3.
|
// ad 3.
|
||||||
store.receive(.updateRoute(.onboarding)) { state in
|
store.receive(.updateDestination(.onboarding)) { state in
|
||||||
state.prevRoute = .welcome
|
state.prevDestination = .welcome
|
||||||
state.internalRoute = .onboarding
|
state.internalDestination = .onboarding
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,8 +70,8 @@ class AppTests: XCTestCase {
|
||||||
|
|
||||||
Self.testScheduler.advance(by: 3)
|
Self.testScheduler.advance(by: 3)
|
||||||
|
|
||||||
store.receive(.updateRoute(.onboarding)) {
|
store.receive(.updateDestination(.onboarding)) {
|
||||||
$0.route = .onboarding
|
$0.destination = .onboarding
|
||||||
$0.appInitializationState = .uninitialized
|
$0.appInitializationState = .uninitialized
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,9 +12,9 @@ import ZcashLightClientKit
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
class DeeplinkTests: XCTestCase {
|
class DeeplinkTests: XCTestCase {
|
||||||
func testActionDeeplinkHome_SameRouteLevel() throws {
|
func testActionDeeplinkHome_SameDestinationLevel() throws {
|
||||||
var appState = AppReducer.State.placeholder
|
var appState = AppReducer.State.placeholder
|
||||||
appState.route = .welcome
|
appState.destination = .welcome
|
||||||
|
|
||||||
let store = TestStore(
|
let store = TestStore(
|
||||||
initialState: appState,
|
initialState: appState,
|
||||||
|
@ -22,14 +22,14 @@ class DeeplinkTests: XCTestCase {
|
||||||
)
|
)
|
||||||
|
|
||||||
store.send(.deeplinkHome) { state in
|
store.send(.deeplinkHome) { state in
|
||||||
state.route = .home
|
state.destination = .home
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func testActionDeeplinkHome_GeetingBack() throws {
|
func testActionDeeplinkHome_GeetingBack() throws {
|
||||||
var appState = AppReducer.State.placeholder
|
var appState = AppReducer.State.placeholder
|
||||||
appState.route = .home
|
appState.destination = .home
|
||||||
appState.homeState.route = .send
|
appState.homeState.destination = .send
|
||||||
|
|
||||||
let store = TestStore(
|
let store = TestStore(
|
||||||
initialState: appState,
|
initialState: appState,
|
||||||
|
@ -37,14 +37,14 @@ class DeeplinkTests: XCTestCase {
|
||||||
)
|
)
|
||||||
|
|
||||||
store.send(.deeplinkHome) { state in
|
store.send(.deeplinkHome) { state in
|
||||||
state.route = .home
|
state.destination = .home
|
||||||
state.homeState.route = nil
|
state.homeState.destination = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func testActionDeeplinkSend() throws {
|
func testActionDeeplinkSend() throws {
|
||||||
var appState = AppReducer.State.placeholder
|
var appState = AppReducer.State.placeholder
|
||||||
appState.route = .welcome
|
appState.destination = .welcome
|
||||||
|
|
||||||
let store = TestStore(
|
let store = TestStore(
|
||||||
initialState: appState,
|
initialState: appState,
|
||||||
|
@ -56,8 +56,8 @@ class DeeplinkTests: XCTestCase {
|
||||||
let memo = "testing some memo"
|
let memo = "testing some memo"
|
||||||
|
|
||||||
store.send(.deeplinkSend(amount, address, memo)) { state in
|
store.send(.deeplinkSend(amount, address, memo)) { state in
|
||||||
state.route = .home
|
state.destination = .home
|
||||||
state.homeState.route = .send
|
state.homeState.destination = .send
|
||||||
state.homeState.sendState.amount = amount
|
state.homeState.sendState.amount = amount
|
||||||
state.homeState.sendState.address = address
|
state.homeState.sendState.address = address
|
||||||
state.homeState.sendState.memoState.text = memo
|
state.homeState.sendState.memoState.text = memo
|
||||||
|
@ -71,12 +71,12 @@ class DeeplinkTests: XCTestCase {
|
||||||
|
|
||||||
let result = try Deeplink().resolveDeeplinkURL(url, isValidZcashAddress: { _ in false })
|
let result = try Deeplink().resolveDeeplinkURL(url, isValidZcashAddress: { _ in false })
|
||||||
|
|
||||||
XCTAssertEqual(result, Deeplink.Route.home)
|
XCTAssertEqual(result, Deeplink.Destination.home)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testDeeplinkRequest_Received_Home() async throws {
|
func testDeeplinkRequest_Received_Home() async throws {
|
||||||
var appState = AppReducer.State.placeholder
|
var appState = AppReducer.State.placeholder
|
||||||
appState.route = .welcome
|
appState.destination = .welcome
|
||||||
appState.appInitializationState = .initialized
|
appState.appInitializationState = .initialized
|
||||||
|
|
||||||
let store = TestStore(
|
let store = TestStore(
|
||||||
|
@ -84,7 +84,7 @@ class DeeplinkTests: XCTestCase {
|
||||||
reducer: AppReducer()
|
reducer: AppReducer()
|
||||||
) { dependencies in
|
) { dependencies in
|
||||||
dependencies.deeplink = DeeplinkClient(
|
dependencies.deeplink = DeeplinkClient(
|
||||||
resolveDeeplinkURL: { _, _ in Deeplink.Route.home }
|
resolveDeeplinkURL: { _, _ in Deeplink.Destination.home }
|
||||||
)
|
)
|
||||||
let synchronizer = NoopSDKSynchronizer()
|
let synchronizer = NoopSDKSynchronizer()
|
||||||
synchronizer.updateStateChanged(.synced)
|
synchronizer.updateStateChanged(.synced)
|
||||||
|
@ -98,7 +98,7 @@ class DeeplinkTests: XCTestCase {
|
||||||
_ = await store.send(.deeplink(url))
|
_ = await store.send(.deeplink(url))
|
||||||
|
|
||||||
await store.receive(.deeplinkHome) { state in
|
await store.receive(.deeplinkHome) { state in
|
||||||
state.route = .home
|
state.destination = .home
|
||||||
}
|
}
|
||||||
|
|
||||||
await store.finish()
|
await store.finish()
|
||||||
|
@ -111,7 +111,7 @@ class DeeplinkTests: XCTestCase {
|
||||||
|
|
||||||
let result = try Deeplink().resolveDeeplinkURL(url, isValidZcashAddress: { _ in false })
|
let result = try Deeplink().resolveDeeplinkURL(url, isValidZcashAddress: { _ in false })
|
||||||
|
|
||||||
XCTAssertEqual(result, Deeplink.Route.send(amount: 123_000_000, address: "address", memo: "some text"))
|
XCTAssertEqual(result, Deeplink.Destination.send(amount: 123_000_000, address: "address", memo: "some text"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func testDeeplinkRequest_Received_Send() async throws {
|
func testDeeplinkRequest_Received_Send() async throws {
|
||||||
|
@ -119,7 +119,7 @@ class DeeplinkTests: XCTestCase {
|
||||||
synchronizer.updateStateChanged(.synced)
|
synchronizer.updateStateChanged(.synced)
|
||||||
|
|
||||||
var appState = AppReducer.State.placeholder
|
var appState = AppReducer.State.placeholder
|
||||||
appState.route = .welcome
|
appState.destination = .welcome
|
||||||
appState.appInitializationState = .initialized
|
appState.appInitializationState = .initialized
|
||||||
|
|
||||||
let store = TestStore(
|
let store = TestStore(
|
||||||
|
@ -127,7 +127,7 @@ class DeeplinkTests: XCTestCase {
|
||||||
reducer: AppReducer()
|
reducer: AppReducer()
|
||||||
) { dependencies in
|
) { dependencies in
|
||||||
dependencies.deeplink = DeeplinkClient(
|
dependencies.deeplink = DeeplinkClient(
|
||||||
resolveDeeplinkURL: { _, _ in Deeplink.Route.send(amount: 123_000_000, address: "address", memo: "some text") }
|
resolveDeeplinkURL: { _, _ in Deeplink.Destination.send(amount: 123_000_000, address: "address", memo: "some text") }
|
||||||
)
|
)
|
||||||
dependencies.sdkSynchronizer = synchronizer
|
dependencies.sdkSynchronizer = synchronizer
|
||||||
}
|
}
|
||||||
|
@ -143,8 +143,8 @@ class DeeplinkTests: XCTestCase {
|
||||||
let memo = "some text"
|
let memo = "some text"
|
||||||
|
|
||||||
await store.receive(.deeplinkSend(amount, address, memo)) { state in
|
await store.receive(.deeplinkSend(amount, address, memo)) { state in
|
||||||
state.route = .home
|
state.destination = .home
|
||||||
state.homeState.route = .send
|
state.homeState.destination = .send
|
||||||
state.homeState.sendState.amount = amount
|
state.homeState.sendState.amount = amount
|
||||||
state.homeState.sendState.address = address
|
state.homeState.sendState.address = address
|
||||||
state.homeState.sendState.memoState.text = memo
|
state.homeState.sendState.memoState.text = memo
|
||||||
|
|
|
@ -85,8 +85,8 @@ class HomeTests: XCTestCase {
|
||||||
reducer: HomeReducer()
|
reducer: HomeReducer()
|
||||||
)
|
)
|
||||||
|
|
||||||
store.send(.walletEvents(.updateRoute(.all))) { state in
|
store.send(.walletEvents(.updateDestination(.all))) { state in
|
||||||
state.walletEventsState.route = .all
|
state.walletEventsState.destination = .all
|
||||||
}
|
}
|
||||||
|
|
||||||
store.receive(.updateDrawer(.full)) { state in
|
store.receive(.updateDrawer(.full)) { state in
|
||||||
|
@ -113,8 +113,8 @@ class HomeTests: XCTestCase {
|
||||||
reducer: HomeReducer()
|
reducer: HomeReducer()
|
||||||
)
|
)
|
||||||
|
|
||||||
store.send(.walletEvents(.updateRoute(.latest))) { state in
|
store.send(.walletEvents(.updateDestination(.latest))) { state in
|
||||||
state.walletEventsState.route = .latest
|
state.walletEventsState.destination = .latest
|
||||||
}
|
}
|
||||||
|
|
||||||
store.receive(.updateDrawer(.partial)) { state in
|
store.receive(.updateDrawer(.partial)) { state in
|
||||||
|
@ -138,7 +138,7 @@ class HomeTests: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
// expected side effects as a result of .onAppear registration
|
// expected side effects as a result of .onAppear registration
|
||||||
store.receive(.updateRoute(nil))
|
store.receive(.updateDestination(nil))
|
||||||
store.receive(.synchronizerStateChanged(.unknown))
|
store.receive(.synchronizerStateChanged(.unknown))
|
||||||
store.receive(.updateSynchronizerStatus)
|
store.receive(.updateSynchronizerStatus)
|
||||||
|
|
||||||
|
@ -160,8 +160,8 @@ class HomeTests: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
// expected side effects as a result of .onAppear registration
|
// expected side effects as a result of .onAppear registration
|
||||||
store.receive(.updateRoute(.notEnoughFreeDiskSpace)) { state in
|
store.receive(.updateDestination(.notEnoughFreeDiskSpace)) { state in
|
||||||
state.route = .notEnoughFreeDiskSpace
|
state.destination = .notEnoughFreeDiskSpace
|
||||||
}
|
}
|
||||||
|
|
||||||
// long-living (cancelable) effects need to be properly canceled.
|
// long-living (cancelable) effects need to be properly canceled.
|
||||||
|
@ -171,7 +171,7 @@ class HomeTests: XCTestCase {
|
||||||
|
|
||||||
@MainActor func testQuickRescan_ResetToHomeScreen() async throws {
|
@MainActor func testQuickRescan_ResetToHomeScreen() async throws {
|
||||||
let homeState = HomeReducer.State(
|
let homeState = HomeReducer.State(
|
||||||
route: .profile,
|
destination: .profile,
|
||||||
balanceBreakdownState: .placeholder,
|
balanceBreakdownState: .placeholder,
|
||||||
drawerOverlay: .full,
|
drawerOverlay: .full,
|
||||||
profileState: .placeholder,
|
profileState: .placeholder,
|
||||||
|
@ -189,7 +189,7 @@ class HomeTests: XCTestCase {
|
||||||
)
|
)
|
||||||
|
|
||||||
_ = await store.send(.profile(.settings(.quickRescan))) { state in
|
_ = await store.send(.profile(.settings(.quickRescan))) { state in
|
||||||
state.route = nil
|
state.destination = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
await store.receive(.rewindDone(true, .quickRescan))
|
await store.receive(.rewindDone(true, .quickRescan))
|
||||||
|
@ -197,7 +197,7 @@ class HomeTests: XCTestCase {
|
||||||
|
|
||||||
@MainActor func testFullRescan_ResetToHomeScreen() async throws {
|
@MainActor func testFullRescan_ResetToHomeScreen() async throws {
|
||||||
let homeState = HomeReducer.State(
|
let homeState = HomeReducer.State(
|
||||||
route: .profile,
|
destination: .profile,
|
||||||
balanceBreakdownState: .placeholder,
|
balanceBreakdownState: .placeholder,
|
||||||
drawerOverlay: .full,
|
drawerOverlay: .full,
|
||||||
profileState: .placeholder,
|
profileState: .placeholder,
|
||||||
|
@ -215,7 +215,7 @@ class HomeTests: XCTestCase {
|
||||||
)
|
)
|
||||||
|
|
||||||
_ = await store.send(.profile(.settings(.fullRescan))) { state in
|
_ = await store.send(.profile(.settings(.fullRescan))) { state in
|
||||||
state.route = nil
|
state.destination = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
await store.receive(.rewindDone(true, .fullRescan))
|
await store.receive(.rewindDone(true, .fullRescan))
|
||||||
|
|
|
@ -321,7 +321,7 @@ class RecoveryPhraseValidationTests: XCTestCase {
|
||||||
|
|
||||||
store.receive(.succeed) {
|
store.receive(.succeed) {
|
||||||
XCTAssertTrue($0.isComplete)
|
XCTAssertTrue($0.isComplete)
|
||||||
$0.route = .success
|
$0.destination = .success
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,7 +394,7 @@ class RecoveryPhraseValidationTests: XCTestCase {
|
||||||
store.receive(.failureFeedback)
|
store.receive(.failureFeedback)
|
||||||
|
|
||||||
store.receive(.fail) {
|
store.receive(.fail) {
|
||||||
$0.route = .failure
|
$0.destination = .failure
|
||||||
XCTAssertFalse($0.isValid)
|
XCTAssertFalse($0.isValid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -612,7 +612,7 @@ class RecoveryPhraseValidationTests: XCTestCase {
|
||||||
missingIndices: missingIndices,
|
missingIndices: missingIndices,
|
||||||
missingWordChips: phrase.words(fromMissingIndices: missingIndices),
|
missingWordChips: phrase.words(fromMissingIndices: missingIndices),
|
||||||
validationWords: completion,
|
validationWords: completion,
|
||||||
route: nil
|
destination: nil
|
||||||
)
|
)
|
||||||
|
|
||||||
XCTAssertTrue(result.isValid)
|
XCTAssertTrue(result.isValid)
|
||||||
|
@ -651,7 +651,7 @@ class RecoveryPhraseValidationTests: XCTestCase {
|
||||||
missingIndices: missingIndices,
|
missingIndices: missingIndices,
|
||||||
missingWordChips: phrase.words(fromMissingIndices: missingIndices),
|
missingWordChips: phrase.words(fromMissingIndices: missingIndices),
|
||||||
validationWords: completion,
|
validationWords: completion,
|
||||||
route: nil
|
destination: nil
|
||||||
)
|
)
|
||||||
|
|
||||||
XCTAssertFalse(result.isValid)
|
XCTAssertFalse(result.isValid)
|
||||||
|
|
|
@ -77,8 +77,8 @@ class SendTests: XCTestCase {
|
||||||
)
|
)
|
||||||
|
|
||||||
// first it's expected that progress screen is showed
|
// first it's expected that progress screen is showed
|
||||||
await store.receive(.updateRoute(.inProgress)) { state in
|
await store.receive(.updateDestination(.inProgress)) { state in
|
||||||
state.route = .inProgress
|
state.destination = .inProgress
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the success transaction to be received back
|
// check the success transaction to be received back
|
||||||
|
@ -89,8 +89,8 @@ class SendTests: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
// all went well, the success screen is triggered
|
// all went well, the success screen is triggered
|
||||||
await store.receive(.updateRoute(.success)) { state in
|
await store.receive(.updateDestination(.success)) { state in
|
||||||
state.route = .success
|
state.destination = .success
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,8 +145,8 @@ class SendTests: XCTestCase {
|
||||||
)
|
)
|
||||||
|
|
||||||
// first it's expected that progress screen is showed
|
// first it's expected that progress screen is showed
|
||||||
await store.receive(.updateRoute(.inProgress)) { state in
|
await store.receive(.updateDestination(.inProgress)) { state in
|
||||||
state.route = .inProgress
|
state.destination = .inProgress
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the success transaction to be received back
|
// check the success transaction to be received back
|
||||||
|
@ -157,8 +157,8 @@ class SendTests: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
// all went well, the success screen is triggered
|
// all went well, the success screen is triggered
|
||||||
await store.receive(.updateRoute(.success)) { state in
|
await store.receive(.updateDestination(.success)) { state in
|
||||||
state.route = .success
|
state.destination = .success
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,8 +198,8 @@ class SendTests: XCTestCase {
|
||||||
await testScheduler.advance(by: 0.01)
|
await testScheduler.advance(by: 0.01)
|
||||||
|
|
||||||
// first it's expected that progress screen is showed
|
// first it's expected that progress screen is showed
|
||||||
await store.receive(.updateRoute(.inProgress)) { state in
|
await store.receive(.updateDestination(.inProgress)) { state in
|
||||||
state.route = .inProgress
|
state.destination = .inProgress
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the failure transaction to be received back
|
// check the failure transaction to be received back
|
||||||
|
@ -210,8 +210,8 @@ class SendTests: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
// the failure screen is triggered as expected
|
// the failure screen is triggered as expected
|
||||||
await store.receive(.updateRoute(.failure)) { state in
|
await store.receive(.updateDestination(.failure)) { state in
|
||||||
state.route = .failure
|
state.destination = .failure
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,8 +59,8 @@ class SettingsTests: XCTestCase {
|
||||||
await store.receive(.backupWallet) { state in
|
await store.receive(.backupWallet) { state in
|
||||||
state.phraseDisplayState.phrase = RecoveryPhrase(words: mnemonic.components(separatedBy: " "))
|
state.phraseDisplayState.phrase = RecoveryPhrase(words: mnemonic.components(separatedBy: " "))
|
||||||
}
|
}
|
||||||
await store.receive(.updateRoute(.backupPhrase)) { state in
|
await store.receive(.updateDestination(.backupPhrase)) { state in
|
||||||
state.route = .backupPhrase
|
state.destination = .backupPhrase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ class SettingsTests: XCTestCase {
|
||||||
.cancel(TextState("Cancel"))
|
.cancel(TextState("Cancel"))
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
route: nil
|
destination: nil
|
||||||
),
|
),
|
||||||
reducer: SettingsReducer()
|
reducer: SettingsReducer()
|
||||||
)
|
)
|
||||||
|
@ -132,7 +132,7 @@ class SettingsTests: XCTestCase {
|
||||||
.cancel(TextState("Cancel"))
|
.cancel(TextState("Cancel"))
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
route: nil
|
destination: nil
|
||||||
),
|
),
|
||||||
reducer: SettingsReducer()
|
reducer: SettingsReducer()
|
||||||
)
|
)
|
||||||
|
@ -155,7 +155,7 @@ class SettingsTests: XCTestCase {
|
||||||
.cancel(TextState("Cancel"))
|
.cancel(TextState("Cancel"))
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
route: nil
|
destination: nil
|
||||||
),
|
),
|
||||||
reducer: SettingsReducer()
|
reducer: SettingsReducer()
|
||||||
)
|
)
|
||||||
|
|
|
@ -97,7 +97,7 @@ class WalletEventsSnapshotTests: XCTestCase {
|
||||||
reducer: HomeReducer()
|
reducer: HomeReducer()
|
||||||
)
|
)
|
||||||
|
|
||||||
ViewStore(store).send(.walletEvents(.updateRoute(.showWalletEvent(walletEvent))))
|
ViewStore(store).send(.walletEvents(.updateDestination(.showWalletEvent(walletEvent))))
|
||||||
let walletEventsStore = WalletEventsFlowStore(
|
let walletEventsStore = WalletEventsFlowStore(
|
||||||
initialState: .placeHolder,
|
initialState: .placeHolder,
|
||||||
reducer: WalletEventsFlowReducer()
|
reducer: WalletEventsFlowReducer()
|
||||||
|
@ -144,7 +144,7 @@ class WalletEventsSnapshotTests: XCTestCase {
|
||||||
reducer: HomeReducer()
|
reducer: HomeReducer()
|
||||||
)
|
)
|
||||||
|
|
||||||
ViewStore(store).send(.walletEvents(.updateRoute(.showWalletEvent(walletEvent))))
|
ViewStore(store).send(.walletEvents(.updateDestination(.showWalletEvent(walletEvent))))
|
||||||
let walletEventsStore = WalletEventsFlowStore(
|
let walletEventsStore = WalletEventsFlowStore(
|
||||||
initialState: .placeHolder,
|
initialState: .placeHolder,
|
||||||
reducer: WalletEventsFlowReducer()
|
reducer: WalletEventsFlowReducer()
|
||||||
|
@ -196,7 +196,7 @@ class WalletEventsSnapshotTests: XCTestCase {
|
||||||
walletEvents: .placeholder
|
walletEvents: .placeholder
|
||||||
)
|
)
|
||||||
|
|
||||||
ViewStore(store).send(.walletEvents(.updateRoute(.showWalletEvent(walletEvent))))
|
ViewStore(store).send(.walletEvents(.updateDestination(.showWalletEvent(walletEvent))))
|
||||||
let walletEventsStore = WalletEventsFlowStore(
|
let walletEventsStore = WalletEventsFlowStore(
|
||||||
initialState: walletEventsState,
|
initialState: walletEventsState,
|
||||||
reducer: WalletEventsFlowReducer()
|
reducer: WalletEventsFlowReducer()
|
||||||
|
@ -244,7 +244,7 @@ class WalletEventsSnapshotTests: XCTestCase {
|
||||||
reducer: HomeReducer()
|
reducer: HomeReducer()
|
||||||
)
|
)
|
||||||
|
|
||||||
ViewStore(store).send(.walletEvents(.updateRoute(.showWalletEvent(walletEvent))))
|
ViewStore(store).send(.walletEvents(.updateDestination(.showWalletEvent(walletEvent))))
|
||||||
let walletEventsStore = WalletEventsFlowStore(
|
let walletEventsStore = WalletEventsFlowStore(
|
||||||
initialState: .placeHolder,
|
initialState: .placeHolder,
|
||||||
reducer: WalletEventsFlowReducer()
|
reducer: WalletEventsFlowReducer()
|
||||||
|
|
|
@ -16,7 +16,7 @@ class WalletEventsTests: XCTestCase {
|
||||||
func testSynchronizerSubscription() throws {
|
func testSynchronizerSubscription() throws {
|
||||||
let store = TestStore(
|
let store = TestStore(
|
||||||
initialState: WalletEventsFlowReducer.State(
|
initialState: WalletEventsFlowReducer.State(
|
||||||
route: .latest,
|
destination: .latest,
|
||||||
isScrollable: true,
|
isScrollable: true,
|
||||||
walletEvents: []
|
walletEvents: []
|
||||||
),
|
),
|
||||||
|
@ -71,7 +71,7 @@ class WalletEventsTests: XCTestCase {
|
||||||
|
|
||||||
let store = TestStore(
|
let store = TestStore(
|
||||||
initialState: WalletEventsFlowReducer.State(
|
initialState: WalletEventsFlowReducer.State(
|
||||||
route: .latest,
|
destination: .latest,
|
||||||
isScrollable: true,
|
isScrollable: true,
|
||||||
walletEvents: identifiedWalletEvents
|
walletEvents: identifiedWalletEvents
|
||||||
),
|
),
|
||||||
|
@ -103,7 +103,7 @@ class WalletEventsTests: XCTestCase {
|
||||||
|
|
||||||
let store = TestStore(
|
let store = TestStore(
|
||||||
initialState: WalletEventsFlowReducer.State(
|
initialState: WalletEventsFlowReducer.State(
|
||||||
route: .latest,
|
destination: .latest,
|
||||||
isScrollable: true,
|
isScrollable: true,
|
||||||
walletEvents: []
|
walletEvents: []
|
||||||
),
|
),
|
||||||
|
|
Loading…
Reference in New Issue