parent
d6289afdd1
commit
330bc3256f
|
@ -101,9 +101,13 @@
|
||||||
9E4DC6E227C4C6B700E657F4 /* SecantButtonStyles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E4DC6E127C4C6B700E657F4 /* SecantButtonStyles.swift */; };
|
9E4DC6E227C4C6B700E657F4 /* SecantButtonStyles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E4DC6E127C4C6B700E657F4 /* SecantButtonStyles.swift */; };
|
||||||
9E69A24D27FB002800A55317 /* Welcome.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E69A24C27FB002800A55317 /* Welcome.swift */; };
|
9E69A24D27FB002800A55317 /* Welcome.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E69A24C27FB002800A55317 /* Welcome.swift */; };
|
||||||
9E80B47227E4B34B008FF493 /* UserPreferencesStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E80B47127E4B34B008FF493 /* UserPreferencesStorage.swift */; };
|
9E80B47227E4B34B008FF493 /* UserPreferencesStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E80B47127E4B34B008FF493 /* UserPreferencesStorage.swift */; };
|
||||||
|
9EAFEB822805793200199FC9 /* AppReducerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAFEB812805793200199FC9 /* AppReducerTests.swift */; };
|
||||||
9EAFEB84280597B700199FC9 /* WrappedSecItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAFEB83280597B700199FC9 /* WrappedSecItem.swift */; };
|
9EAFEB84280597B700199FC9 /* WrappedSecItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAFEB83280597B700199FC9 /* WrappedSecItem.swift */; };
|
||||||
9EAFEB862805A23100199FC9 /* WrappedSecItemTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAFEB852805A23100199FC9 /* WrappedSecItemTests.swift */; };
|
9EAFEB862805A23100199FC9 /* WrappedSecItemTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAFEB852805A23100199FC9 /* WrappedSecItemTests.swift */; };
|
||||||
9EAFEB822805793200199FC9 /* AppReducerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAFEB812805793200199FC9 /* AppReducerTests.swift */; };
|
9EAFEB8F2808183D00199FC9 /* SandboxView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAFEB8D2808183D00199FC9 /* SandboxView.swift */; };
|
||||||
|
9EAFEB902808183D00199FC9 /* SandboxStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAFEB8E2808183D00199FC9 /* SandboxStore.swift */; };
|
||||||
|
9EAFEB9128081E9400199FC9 /* HomeStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F93874ED273C4DE200F0E875 /* HomeStore.swift */; };
|
||||||
|
9EAFEB9228081E9400199FC9 /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F93874EF273C4DE200F0E875 /* HomeView.swift */; };
|
||||||
9EBEF87A27CE369800B4F343 /* RecoveryPhraseTestPreambleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EBEF87927CE369800B4F343 /* RecoveryPhraseTestPreambleView.swift */; };
|
9EBEF87A27CE369800B4F343 /* RecoveryPhraseTestPreambleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EBEF87927CE369800B4F343 /* RecoveryPhraseTestPreambleView.swift */; };
|
||||||
9ECAE56827FC713C0089A0EF /* DatabaseFiles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9ECAE56727FC713C0089A0EF /* DatabaseFiles.swift */; };
|
9ECAE56827FC713C0089A0EF /* DatabaseFiles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9ECAE56727FC713C0089A0EF /* DatabaseFiles.swift */; };
|
||||||
9EF8135C27ECC25E0075AF48 /* WalletStorageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EF8135A27ECC25E0075AF48 /* WalletStorageTests.swift */; };
|
9EF8135C27ECC25E0075AF48 /* WalletStorageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EF8135A27ECC25E0075AF48 /* WalletStorageTests.swift */; };
|
||||||
|
@ -114,8 +118,6 @@
|
||||||
9EF8139C27F47AED0075AF48 /* InitializationState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EF8139B27F47AED0075AF48 /* InitializationState.swift */; };
|
9EF8139C27F47AED0075AF48 /* InitializationState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EF8139B27F47AED0075AF48 /* InitializationState.swift */; };
|
||||||
F9322DC0273B555C00C105B5 /* NavigationLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9322DBF273B555C00C105B5 /* NavigationLinks.swift */; };
|
F9322DC0273B555C00C105B5 /* NavigationLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9322DBF273B555C00C105B5 /* NavigationLinks.swift */; };
|
||||||
F93673D62742CB840099C6AF /* Previews.swift in Sources */ = {isa = PBXBuildFile; fileRef = F93673D52742CB840099C6AF /* Previews.swift */; };
|
F93673D62742CB840099C6AF /* Previews.swift in Sources */ = {isa = PBXBuildFile; fileRef = F93673D52742CB840099C6AF /* Previews.swift */; };
|
||||||
F93874F0273C4DE200F0E875 /* HomeStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F93874ED273C4DE200F0E875 /* HomeStore.swift */; };
|
|
||||||
F93874F1273C4DE200F0E875 /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F93874EF273C4DE200F0E875 /* HomeView.swift */; };
|
|
||||||
F96B41E7273B501F0021B49A /* TransactionHistoryStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F96B41E3273B501F0021B49A /* TransactionHistoryStore.swift */; };
|
F96B41E7273B501F0021B49A /* TransactionHistoryStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F96B41E3273B501F0021B49A /* TransactionHistoryStore.swift */; };
|
||||||
F96B41E8273B501F0021B49A /* TransactionDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F96B41E5273B501F0021B49A /* TransactionDetailView.swift */; };
|
F96B41E8273B501F0021B49A /* TransactionDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F96B41E5273B501F0021B49A /* TransactionDetailView.swift */; };
|
||||||
F96B41E9273B501F0021B49A /* TransactionHistoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F96B41E6273B501F0021B49A /* TransactionHistoryView.swift */; };
|
F96B41E9273B501F0021B49A /* TransactionHistoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F96B41E6273B501F0021B49A /* TransactionHistoryView.swift */; };
|
||||||
|
@ -257,9 +259,11 @@
|
||||||
9E4DC6E127C4C6B700E657F4 /* SecantButtonStyles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecantButtonStyles.swift; sourceTree = "<group>"; };
|
9E4DC6E127C4C6B700E657F4 /* SecantButtonStyles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecantButtonStyles.swift; sourceTree = "<group>"; };
|
||||||
9E69A24C27FB002800A55317 /* Welcome.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Welcome.swift; sourceTree = "<group>"; };
|
9E69A24C27FB002800A55317 /* Welcome.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Welcome.swift; sourceTree = "<group>"; };
|
||||||
9E80B47127E4B34B008FF493 /* UserPreferencesStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserPreferencesStorage.swift; sourceTree = "<group>"; };
|
9E80B47127E4B34B008FF493 /* UserPreferencesStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserPreferencesStorage.swift; sourceTree = "<group>"; };
|
||||||
|
9EAFEB812805793200199FC9 /* AppReducerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppReducerTests.swift; sourceTree = "<group>"; };
|
||||||
9EAFEB83280597B700199FC9 /* WrappedSecItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WrappedSecItem.swift; sourceTree = "<group>"; };
|
9EAFEB83280597B700199FC9 /* WrappedSecItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WrappedSecItem.swift; sourceTree = "<group>"; };
|
||||||
9EAFEB852805A23100199FC9 /* WrappedSecItemTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WrappedSecItemTests.swift; sourceTree = "<group>"; };
|
9EAFEB852805A23100199FC9 /* WrappedSecItemTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WrappedSecItemTests.swift; sourceTree = "<group>"; };
|
||||||
9EAFEB812805793200199FC9 /* AppReducerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppReducerTests.swift; sourceTree = "<group>"; };
|
9EAFEB8D2808183D00199FC9 /* SandboxView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SandboxView.swift; sourceTree = "<group>"; };
|
||||||
|
9EAFEB8E2808183D00199FC9 /* SandboxStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SandboxStore.swift; sourceTree = "<group>"; };
|
||||||
9EBEF87927CE369800B4F343 /* RecoveryPhraseTestPreambleView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecoveryPhraseTestPreambleView.swift; sourceTree = "<group>"; };
|
9EBEF87927CE369800B4F343 /* RecoveryPhraseTestPreambleView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecoveryPhraseTestPreambleView.swift; sourceTree = "<group>"; };
|
||||||
9ECAE56727FC713C0089A0EF /* DatabaseFiles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatabaseFiles.swift; sourceTree = "<group>"; };
|
9ECAE56727FC713C0089A0EF /* DatabaseFiles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatabaseFiles.swift; sourceTree = "<group>"; };
|
||||||
9EF8135A27ECC25E0075AF48 /* WalletStorageTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletStorageTests.swift; sourceTree = "<group>"; };
|
9EF8135A27ECC25E0075AF48 /* WalletStorageTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletStorageTests.swift; sourceTree = "<group>"; };
|
||||||
|
@ -664,6 +668,7 @@
|
||||||
6654C73B2715A3F000901167 /* Features */ = {
|
6654C73B2715A3F000901167 /* Features */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
9EAFEB8B2808174900199FC9 /* Sandbox */,
|
||||||
0D0781C2278750C00083ACD7 /* Welcome */,
|
0D0781C2278750C00083ACD7 /* Welcome */,
|
||||||
F9971A4927680DC400A2DB75 /* App */,
|
F9971A4927680DC400A2DB75 /* App */,
|
||||||
F93874EC273C4DE200F0E875 /* Home */,
|
F93874EC273C4DE200F0E875 /* Home */,
|
||||||
|
@ -768,6 +773,23 @@
|
||||||
path = AppReducer;
|
path = AppReducer;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
9EAFEB8B2808174900199FC9 /* Sandbox */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
9EAFEB8E2808183D00199FC9 /* SandboxStore.swift */,
|
||||||
|
9EAFEB8C2808183D00199FC9 /* Views */,
|
||||||
|
);
|
||||||
|
path = Sandbox;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
9EAFEB8C2808183D00199FC9 /* Views */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
9EAFEB8D2808183D00199FC9 /* SandboxView.swift */,
|
||||||
|
);
|
||||||
|
path = Views;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
9EBEF87827CE365D00B4F343 /* Preamble */ = {
|
9EBEF87827CE365D00B4F343 /* Preamble */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -1149,6 +1171,7 @@
|
||||||
files = (
|
files = (
|
||||||
2EB660E02747EAB900A06A07 /* OnboardingScreen.swift in Sources */,
|
2EB660E02747EAB900A06A07 /* OnboardingScreen.swift in Sources */,
|
||||||
660558F8270C862F009D6954 /* XCAssets+Generated.swift in Sources */,
|
660558F8270C862F009D6954 /* XCAssets+Generated.swift in Sources */,
|
||||||
|
9EAFEB902808183D00199FC9 /* SandboxStore.swift in Sources */,
|
||||||
0D35CC46277A36E00074316A /* ScrollableWhenScaled.swift in Sources */,
|
0D35CC46277A36E00074316A /* ScrollableWhenScaled.swift in Sources */,
|
||||||
F96B41E9273B501F0021B49A /* TransactionHistoryView.swift in Sources */,
|
F96B41E9273B501F0021B49A /* TransactionHistoryView.swift in Sources */,
|
||||||
2EDA07A027EDE18C00D6F09B /* TextFieldInput.swift in Sources */,
|
2EDA07A027EDE18C00D6F09B /* TextFieldInput.swift in Sources */,
|
||||||
|
@ -1176,7 +1199,6 @@
|
||||||
0D6D628B276A528E002FB4CC /* DropDelegate.swift in Sources */,
|
0D6D628B276A528E002FB4CC /* DropDelegate.swift in Sources */,
|
||||||
9E2DF99D27CF704D00649636 /* ImportSeedEditor.swift in Sources */,
|
9E2DF99D27CF704D00649636 /* ImportSeedEditor.swift in Sources */,
|
||||||
F9971A5327680DD000A2DB75 /* Profile.swift in Sources */,
|
F9971A5327680DD000A2DB75 /* Profile.swift in Sources */,
|
||||||
F93874F0273C4DE200F0E875 /* HomeStore.swift in Sources */,
|
|
||||||
669FDAEB272C23C2007B9422 /* CircularFrameBadge.swift in Sources */,
|
669FDAEB272C23C2007B9422 /* CircularFrameBadge.swift in Sources */,
|
||||||
2E8719CD27FB0D3B0082C926 /* TransactionCurrencySelector.swift in Sources */,
|
2E8719CD27FB0D3B0082C926 /* TransactionCurrencySelector.swift in Sources */,
|
||||||
F9971A6C27680E1000A2DB75 /* WalletInfoView.swift in Sources */,
|
F9971A6C27680E1000A2DB75 /* WalletInfoView.swift in Sources */,
|
||||||
|
@ -1188,8 +1210,9 @@
|
||||||
665C963F272C26E600BC04FB /* CircularFrameBackground.swift in Sources */,
|
665C963F272C26E600BC04FB /* CircularFrameBackground.swift in Sources */,
|
||||||
0DB8AA81271DC7520035BC9D /* DesignGuide.swift in Sources */,
|
0DB8AA81271DC7520035BC9D /* DesignGuide.swift in Sources */,
|
||||||
F9971A4D27680DC400A2DB75 /* App.swift in Sources */,
|
F9971A4D27680DC400A2DB75 /* App.swift in Sources */,
|
||||||
|
9EAFEB9228081E9400199FC9 /* HomeView.swift in Sources */,
|
||||||
F9322DC0273B555C00C105B5 /* NavigationLinks.swift in Sources */,
|
F9322DC0273B555C00C105B5 /* NavigationLinks.swift in Sources */,
|
||||||
F93874F1273C4DE200F0E875 /* HomeView.swift in Sources */,
|
9EAFEB8F2808183D00199FC9 /* SandboxView.swift in Sources */,
|
||||||
0D7CE63427349B5D0020E050 /* View+WhenDraggable.swift in Sources */,
|
0D7CE63427349B5D0020E050 /* View+WhenDraggable.swift in Sources */,
|
||||||
0D3D04082728B3440032ABC1 /* RecoveryPhraseDisplayView.swift in Sources */,
|
0D3D04082728B3440032ABC1 /* RecoveryPhraseDisplayView.swift in Sources */,
|
||||||
F9971A5F27680DF600A2DB75 /* ScanView.swift in Sources */,
|
F9971A5F27680DF600A2DB75 /* ScanView.swift in Sources */,
|
||||||
|
@ -1203,6 +1226,7 @@
|
||||||
0D354A0926D5A9D000315F45 /* Services.swift in Sources */,
|
0D354A0926D5A9D000315F45 /* Services.swift in Sources */,
|
||||||
660558F7270C862F009D6954 /* Fonts+Generated.swift in Sources */,
|
660558F7270C862F009D6954 /* Fonts+Generated.swift in Sources */,
|
||||||
F96B41E7273B501F0021B49A /* TransactionHistoryStore.swift in Sources */,
|
F96B41E7273B501F0021B49A /* TransactionHistoryStore.swift in Sources */,
|
||||||
|
9EAFEB9128081E9400199FC9 /* HomeStore.swift in Sources */,
|
||||||
F9971A5A27680DDE00A2DB75 /* RequestView.swift in Sources */,
|
F9971A5A27680DDE00A2DB75 /* RequestView.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 */,
|
||||||
|
|
|
@ -6,19 +6,21 @@ struct AppState: Equatable {
|
||||||
case welcome
|
case welcome
|
||||||
case startup
|
case startup
|
||||||
case onboarding
|
case onboarding
|
||||||
|
case sandbox
|
||||||
case home
|
case home
|
||||||
case phraseValidation
|
case phraseValidation
|
||||||
case phraseDisplay
|
case phraseDisplay
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var appInitializationState: InitializationState = .uninitialized
|
||||||
var homeState: HomeState
|
var homeState: HomeState
|
||||||
var onboardingState: OnboardingState
|
var onboardingState: OnboardingState
|
||||||
var phraseValidationState: RecoveryPhraseValidationState
|
var phraseValidationState: RecoveryPhraseValidationState
|
||||||
var phraseDisplayState: RecoveryPhraseDisplayState
|
var phraseDisplayState: RecoveryPhraseDisplayState
|
||||||
var welcomeState: WelcomeState
|
|
||||||
var route: Route = .welcome
|
var route: Route = .welcome
|
||||||
|
var sandboxState: SandboxState
|
||||||
var storedWallet: StoredWallet?
|
var storedWallet: StoredWallet?
|
||||||
var appInitializationState: InitializationState = .uninitialized
|
var welcomeState: WelcomeState
|
||||||
}
|
}
|
||||||
|
|
||||||
enum AppAction: Equatable {
|
enum AppAction: Equatable {
|
||||||
|
@ -32,6 +34,7 @@ enum AppAction: Equatable {
|
||||||
case phraseDisplay(RecoveryPhraseDisplayAction)
|
case phraseDisplay(RecoveryPhraseDisplayAction)
|
||||||
case phraseValidation(RecoveryPhraseValidationAction)
|
case phraseValidation(RecoveryPhraseValidationAction)
|
||||||
case respondToWalletInitializationState(InitializationState)
|
case respondToWalletInitializationState(InitializationState)
|
||||||
|
case sandbox(SandboxAction)
|
||||||
case updateRoute(AppState.Route)
|
case updateRoute(AppState.Route)
|
||||||
case welcome(WelcomeAction)
|
case welcome(WelcomeAction)
|
||||||
}
|
}
|
||||||
|
@ -72,11 +75,12 @@ extension AppReducer {
|
||||||
static let `default` = AppReducer.combine(
|
static let `default` = AppReducer.combine(
|
||||||
[
|
[
|
||||||
appReducer,
|
appReducer,
|
||||||
routeReducer,
|
|
||||||
homeReducer,
|
homeReducer,
|
||||||
onboardingReducer,
|
onboardingReducer,
|
||||||
phraseValidationReducer,
|
phraseValidationReducer,
|
||||||
phraseDisplayReducer
|
phraseDisplayReducer,
|
||||||
|
routeReducer,
|
||||||
|
sandboxReducer
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
.debug()
|
.debug()
|
||||||
|
@ -136,7 +140,7 @@ extension AppReducer {
|
||||||
.cancellable(id: ListenerId(), cancelInFlight: true)
|
.cancellable(id: ListenerId(), cancelInFlight: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
var landingRoute: AppState.Route = .startup
|
var landingRoute: AppState.Route = .home
|
||||||
|
|
||||||
if !storedWallet.hasUserPassedPhraseBackupTest {
|
if !storedWallet.hasUserPassedPhraseBackupTest {
|
||||||
let phraseWords: [String]
|
let phraseWords: [String]
|
||||||
|
@ -195,12 +199,6 @@ extension AppReducer {
|
||||||
// TODO: - when DatabaseFiles dependency is merged, nukeFiles as well, issue #220 (https://github.com/zcash/secant-ios-wallet/issues/220)
|
// TODO: - when DatabaseFiles dependency is merged, nukeFiles as well, issue #220 (https://github.com/zcash/secant-ios-wallet/issues/220)
|
||||||
return .none
|
return .none
|
||||||
|
|
||||||
case .welcome(.debugMenuHome):
|
|
||||||
return .concatenate(
|
|
||||||
Effect.cancel(id: ListenerId()),
|
|
||||||
Effect(value: .updateRoute(.home))
|
|
||||||
)
|
|
||||||
|
|
||||||
case .welcome(.debugMenuStartup):
|
case .welcome(.debugMenuStartup):
|
||||||
return .concatenate(
|
return .concatenate(
|
||||||
Effect.cancel(id: ListenerId()),
|
Effect.cancel(id: ListenerId()),
|
||||||
|
@ -208,7 +206,7 @@ extension AppReducer {
|
||||||
)
|
)
|
||||||
|
|
||||||
case .onboarding(.importWallet(.successfullyRecovered)):
|
case .onboarding(.importWallet(.successfullyRecovered)):
|
||||||
return Effect(value: .updateRoute(.home))
|
return Effect(value: .updateRoute(.sandbox))
|
||||||
|
|
||||||
/// 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 `routeReducer` handling routes and this reducer is handling only actions. We don't here plenty of unused cases.
|
||||||
default:
|
default:
|
||||||
|
@ -221,7 +219,7 @@ extension AppReducer {
|
||||||
case let .updateRoute(route):
|
case let .updateRoute(route):
|
||||||
state.route = route
|
state.route = route
|
||||||
|
|
||||||
case .home(.reset):
|
case .sandbox(.reset):
|
||||||
state.route = .startup
|
state.route = .startup
|
||||||
|
|
||||||
case .onboarding(.createNewWallet):
|
case .onboarding(.createNewWallet):
|
||||||
|
@ -274,6 +272,12 @@ extension AppReducer {
|
||||||
environment: { _ in BackupPhraseEnvironment.demo }
|
environment: { _ in BackupPhraseEnvironment.demo }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private static let sandboxReducer: AppReducer = SandboxReducer.default.pullback(
|
||||||
|
state: \AppState.sandboxState,
|
||||||
|
action: /AppAction.sandbox,
|
||||||
|
environment: { _ in }
|
||||||
|
)
|
||||||
|
|
||||||
private static let welcomeReducer: AppReducer = WelcomeReducer.default.pullback(
|
private static let welcomeReducer: AppReducer = WelcomeReducer.default.pullback(
|
||||||
state: \AppState.welcomeState,
|
state: \AppState.welcomeState,
|
||||||
action: /AppAction.welcome,
|
action: /AppAction.welcome,
|
||||||
|
@ -356,6 +360,7 @@ extension AppState {
|
||||||
phraseDisplayState: RecoveryPhraseDisplayState(
|
phraseDisplayState: RecoveryPhraseDisplayState(
|
||||||
phrase: .placeholder
|
phrase: .placeholder
|
||||||
),
|
),
|
||||||
|
sandboxState: .placeholder,
|
||||||
welcomeState: .placeholder
|
welcomeState: .placeholder
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,11 +9,19 @@ struct AppView: View {
|
||||||
WithViewStore(store) { viewStore in
|
WithViewStore(store) { viewStore in
|
||||||
switch viewStore.route {
|
switch viewStore.route {
|
||||||
case .home:
|
case .home:
|
||||||
|
HomeView(
|
||||||
|
store: store.scope(
|
||||||
|
state: \.homeState,
|
||||||
|
action: AppAction.home
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
case .sandbox:
|
||||||
NavigationView {
|
NavigationView {
|
||||||
HomeView(
|
SandboxView(
|
||||||
store: store.scope(
|
store: store.scope(
|
||||||
state: \.homeState,
|
state: \.sandboxState,
|
||||||
action: AppAction.home
|
action: AppAction.sandbox
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -75,8 +83,8 @@ private struct StartupView: View {
|
||||||
var body: some View {
|
var body: some View {
|
||||||
List {
|
List {
|
||||||
Section(header: Text("Navigation Stack Routes")) {
|
Section(header: Text("Navigation Stack Routes")) {
|
||||||
Button("Go To Home") {
|
Button("Go To Sandbox (navigation proof)") {
|
||||||
sendAction(.updateRoute(.home))
|
sendAction(.updateRoute(.sandbox))
|
||||||
}
|
}
|
||||||
|
|
||||||
Button("Go To Onboarding") {
|
Button("Go To Onboarding") {
|
||||||
|
|
|
@ -2,24 +2,10 @@ import ComposableArchitecture
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct HomeState: Equatable {
|
struct HomeState: Equatable {
|
||||||
enum Route: Equatable, CaseIterable {
|
var balance: Double
|
||||||
case history
|
|
||||||
case send
|
|
||||||
case recoveryPhraseDisplay
|
|
||||||
case profile
|
|
||||||
case scan
|
|
||||||
case request
|
|
||||||
}
|
|
||||||
var transactionHistoryState: TransactionHistoryState
|
|
||||||
var profileState: ProfileState
|
|
||||||
var route: Route?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum HomeAction: Equatable {
|
enum HomeAction: Equatable {
|
||||||
case updateRoute(HomeState.Route?)
|
|
||||||
case transactionHistory(TransactionHistoryAction)
|
|
||||||
case profile(ProfileAction)
|
|
||||||
case reset
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - HomeReducer
|
// MARK: - HomeReducer
|
||||||
|
@ -27,30 +13,8 @@ enum HomeAction: Equatable {
|
||||||
typealias HomeReducer = Reducer<HomeState, HomeAction, Void>
|
typealias HomeReducer = Reducer<HomeState, HomeAction, Void>
|
||||||
|
|
||||||
extension HomeReducer {
|
extension HomeReducer {
|
||||||
static let `default` = HomeReducer { state, action, _ in
|
static let `default` = HomeReducer { _, _, _ in
|
||||||
switch action {
|
return .none
|
||||||
case let .updateRoute(route):
|
|
||||||
state.route = route
|
|
||||||
return .none
|
|
||||||
case let .transactionHistory(transactionHistoryAction):
|
|
||||||
return TransactionHistoryReducer
|
|
||||||
.default
|
|
||||||
.run(&state.transactionHistoryState, transactionHistoryAction, ())
|
|
||||||
.map(HomeAction.transactionHistory)
|
|
||||||
case let .profile(profileAction):
|
|
||||||
return ProfileReducer
|
|
||||||
.default
|
|
||||||
.pullback(
|
|
||||||
state: \.profileState,
|
|
||||||
action: /HomeAction.profile,
|
|
||||||
environment: { _ in
|
|
||||||
return ProfileEnvironment()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.run(&state, action, ())
|
|
||||||
case .reset:
|
|
||||||
return .none
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,58 +22,11 @@ extension HomeReducer {
|
||||||
|
|
||||||
typealias HomeStore = Store<HomeState, HomeAction>
|
typealias HomeStore = Store<HomeState, HomeAction>
|
||||||
|
|
||||||
extension HomeStore {
|
|
||||||
func historyStore() -> TransactionHistoryStore {
|
|
||||||
self.scope(
|
|
||||||
state: \.transactionHistoryState,
|
|
||||||
action: HomeAction.transactionHistory
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func profileStore() -> ProfileStore {
|
|
||||||
self.scope(
|
|
||||||
state: \.profileState,
|
|
||||||
action: HomeAction.profile
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - HomeViewStore
|
|
||||||
|
|
||||||
typealias HomeViewStore = ViewStore<HomeState, HomeAction>
|
|
||||||
|
|
||||||
extension HomeViewStore {
|
|
||||||
func toggleSelectedTransaction() {
|
|
||||||
let isAlreadySelected = (self.selectedTranactionID != nil)
|
|
||||||
let transcation = self.transactionHistoryState.transactions[5]
|
|
||||||
let newRoute = isAlreadySelected ? nil : TransactionHistoryState.Route.showTransaction(transcation)
|
|
||||||
send(.transactionHistory(.setRoute(newRoute)))
|
|
||||||
}
|
|
||||||
|
|
||||||
var selectedTranactionID: Int? {
|
|
||||||
self.transactionHistoryState
|
|
||||||
.route
|
|
||||||
.flatMap(/TransactionHistoryState.Route.showTransaction)
|
|
||||||
.map(\.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
func bindingForRoute(_ route: HomeState.Route) -> Binding<Bool> {
|
|
||||||
self.binding(
|
|
||||||
get: { $0.route == route },
|
|
||||||
send: { isActive in
|
|
||||||
return .updateRoute(isActive ? route : nil)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: PlaceHolders
|
// MARK: PlaceHolders
|
||||||
extension HomeState {
|
extension HomeState {
|
||||||
static var placeholder: Self {
|
static var placeholder: Self {
|
||||||
.init(
|
.init(
|
||||||
transactionHistoryState: .placeHolder,
|
balance: 1.2
|
||||||
profileState: .placeholder,
|
|
||||||
route: nil
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,113 +4,21 @@ import ComposableArchitecture
|
||||||
struct HomeView: View {
|
struct HomeView: View {
|
||||||
let store: Store<HomeState, HomeAction>
|
let store: Store<HomeState, HomeAction>
|
||||||
|
|
||||||
var navigationRouteValues: [RouteValue] = HomeState.Route.allCases
|
|
||||||
.enumerated()
|
|
||||||
.filter { $0.1 != .history }
|
|
||||||
.map { RouteValue(id: $0.0, route: $0.1) }
|
|
||||||
|
|
||||||
var modalRoutes: [RouteValue] = HomeState.Route.allCases
|
|
||||||
.enumerated()
|
|
||||||
.filter { $0.1 == .history }
|
|
||||||
.map { RouteValue(id: $0.0, route: $0.1) }
|
|
||||||
|
|
||||||
@ViewBuilder func view(for route: HomeState.Route) -> some View {
|
|
||||||
switch route {
|
|
||||||
case .history:
|
|
||||||
TransactionHistoryView(store: store.historyStore())
|
|
||||||
case .send:
|
|
||||||
SendView(
|
|
||||||
store: .init(
|
|
||||||
initialState: .placeholder,
|
|
||||||
reducer: SendReducer.default(
|
|
||||||
whenDone: { HomeViewStore(store).send(.updateRoute(nil)) }
|
|
||||||
)
|
|
||||||
.debug(),
|
|
||||||
environment: ()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
case .recoveryPhraseDisplay:
|
|
||||||
RecoveryPhraseDisplayView(store: .demo)
|
|
||||||
case .scan:
|
|
||||||
ScanView()
|
|
||||||
case .profile:
|
|
||||||
ProfileView(store: store.profileStore())
|
|
||||||
case .request:
|
|
||||||
RequestView()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
WithViewStore(store) { viewStore in
|
WithViewStore(store) { viewStore in
|
||||||
VStack {
|
VStack {
|
||||||
List {
|
Text("balance \(viewStore.balance)")
|
||||||
Section(header: Text("Navigation Stack Routes")) {
|
|
||||||
ForEach(navigationRouteValues) { routeValue in
|
|
||||||
Text("\(String(describing: routeValue.route))")
|
|
||||||
.navigationLink(
|
|
||||||
isActive: viewStore.bindingForRoute(routeValue.route),
|
|
||||||
destination: {
|
|
||||||
view(for: routeValue.route)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Section(header: Text("Modal Routes")) {
|
|
||||||
ForEach(modalRoutes) { routeValue in
|
|
||||||
Button(
|
|
||||||
action: { viewStore.send(.updateRoute(routeValue.route)) },
|
|
||||||
label: { Text("\(String(describing: routeValue.route))") }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Section(header: Text("Other Actions")) {
|
|
||||||
Button(
|
|
||||||
action: { viewStore.toggleSelectedTransaction() },
|
|
||||||
label: { Text("Toggle Selected Transaction") }
|
|
||||||
)
|
|
||||||
|
|
||||||
Button(
|
|
||||||
action: { viewStore.send(.reset) },
|
|
||||||
label: { Text("Reset (to startup)") }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.fullScreenCover(
|
|
||||||
isPresented: viewStore.bindingForRoute(.history),
|
|
||||||
content: {
|
|
||||||
NavigationView {
|
|
||||||
TransactionHistoryView(store: store.historyStore())
|
|
||||||
.toolbar {
|
|
||||||
ToolbarItem {
|
|
||||||
Button("Done") { viewStore.send(.updateRoute(nil)) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.navigationBarTitle("Home")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RouteValue: Identifiable {
|
|
||||||
let id: Int
|
|
||||||
let route: HomeState.Route
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Previews
|
// MARK: - Previews
|
||||||
|
|
||||||
extension HomeStore {
|
extension HomeStore {
|
||||||
static var placeholder: HomeStore {
|
static var placeholder: HomeStore {
|
||||||
HomeStore(
|
HomeStore(
|
||||||
initialState: HomeState(
|
initialState: .placeholder,
|
||||||
transactionHistoryState: .placeHolder,
|
|
||||||
profileState: .placeholder,
|
|
||||||
route: nil
|
|
||||||
),
|
|
||||||
reducer: .default.debug(),
|
reducer: .default.debug(),
|
||||||
environment: ()
|
environment: ()
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
import ComposableArchitecture
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct SandboxState: Equatable {
|
||||||
|
enum Route: Equatable, CaseIterable {
|
||||||
|
case history
|
||||||
|
case send
|
||||||
|
case recoveryPhraseDisplay
|
||||||
|
case profile
|
||||||
|
case scan
|
||||||
|
case request
|
||||||
|
}
|
||||||
|
var transactionHistoryState: TransactionHistoryState
|
||||||
|
var profileState: ProfileState
|
||||||
|
var route: Route?
|
||||||
|
}
|
||||||
|
|
||||||
|
enum SandboxAction: Equatable {
|
||||||
|
case updateRoute(SandboxState.Route?)
|
||||||
|
case transactionHistory(TransactionHistoryAction)
|
||||||
|
case profile(ProfileAction)
|
||||||
|
case reset
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - SandboxReducer
|
||||||
|
|
||||||
|
typealias SandboxReducer = Reducer<SandboxState, SandboxAction, Void>
|
||||||
|
|
||||||
|
extension SandboxReducer {
|
||||||
|
static let `default` = SandboxReducer { state, action, _ in
|
||||||
|
switch action {
|
||||||
|
case let .updateRoute(route):
|
||||||
|
state.route = route
|
||||||
|
return .none
|
||||||
|
case let .transactionHistory(transactionHistoryAction):
|
||||||
|
return TransactionHistoryReducer
|
||||||
|
.default
|
||||||
|
.run(&state.transactionHistoryState, transactionHistoryAction, ())
|
||||||
|
.map(SandboxAction.transactionHistory)
|
||||||
|
case let .profile(profileAction):
|
||||||
|
return ProfileReducer
|
||||||
|
.default
|
||||||
|
.pullback(
|
||||||
|
state: \.profileState,
|
||||||
|
action: /SandboxAction.profile,
|
||||||
|
environment: { _ in
|
||||||
|
return ProfileEnvironment()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.run(&state, action, ())
|
||||||
|
case .reset:
|
||||||
|
return .none
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - SandboxStore
|
||||||
|
|
||||||
|
typealias SandboxStore = Store<SandboxState, SandboxAction>
|
||||||
|
|
||||||
|
extension SandboxStore {
|
||||||
|
func historyStore() -> TransactionHistoryStore {
|
||||||
|
self.scope(
|
||||||
|
state: \.transactionHistoryState,
|
||||||
|
action: SandboxAction.transactionHistory
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func profileStore() -> ProfileStore {
|
||||||
|
self.scope(
|
||||||
|
state: \.profileState,
|
||||||
|
action: SandboxAction.profile
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - SandboxViewStore
|
||||||
|
|
||||||
|
typealias SandboxViewStore = ViewStore<SandboxState, SandboxAction>
|
||||||
|
|
||||||
|
extension SandboxViewStore {
|
||||||
|
func toggleSelectedTransaction() {
|
||||||
|
let isAlreadySelected = (self.selectedTranactionID != nil)
|
||||||
|
let transcation = self.transactionHistoryState.transactions[5]
|
||||||
|
let newRoute = isAlreadySelected ? nil : TransactionHistoryState.Route.showTransaction(transcation)
|
||||||
|
send(.transactionHistory(.setRoute(newRoute)))
|
||||||
|
}
|
||||||
|
|
||||||
|
var selectedTranactionID: Int? {
|
||||||
|
self.transactionHistoryState
|
||||||
|
.route
|
||||||
|
.flatMap(/TransactionHistoryState.Route.showTransaction)
|
||||||
|
.map(\.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func bindingForRoute(_ route: SandboxState.Route) -> Binding<Bool> {
|
||||||
|
self.binding(
|
||||||
|
get: { $0.route == route },
|
||||||
|
send: { isActive in
|
||||||
|
return .updateRoute(isActive ? route : nil)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: PlaceHolders
|
||||||
|
extension SandboxState {
|
||||||
|
static var placeholder: Self {
|
||||||
|
.init(
|
||||||
|
transactionHistoryState: .placeHolder,
|
||||||
|
profileState: .placeholder,
|
||||||
|
route: nil
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,126 @@
|
||||||
|
import SwiftUI
|
||||||
|
import ComposableArchitecture
|
||||||
|
|
||||||
|
struct SandboxView: View {
|
||||||
|
let store: Store<SandboxState, SandboxAction>
|
||||||
|
|
||||||
|
var navigationRouteValues: [SandboxRouteValue] = SandboxState.Route.allCases
|
||||||
|
.enumerated()
|
||||||
|
.filter { $0.1 != .history }
|
||||||
|
.map { SandboxRouteValue(id: $0.0, route: $0.1) }
|
||||||
|
|
||||||
|
var modalRoutes: [SandboxRouteValue] = SandboxState.Route.allCases
|
||||||
|
.enumerated()
|
||||||
|
.filter { $0.1 == .history }
|
||||||
|
.map { SandboxRouteValue(id: $0.0, route: $0.1) }
|
||||||
|
|
||||||
|
@ViewBuilder func view(for route: SandboxState.Route) -> some View {
|
||||||
|
switch route {
|
||||||
|
case .history:
|
||||||
|
TransactionHistoryView(store: store.historyStore())
|
||||||
|
case .send:
|
||||||
|
SendView(
|
||||||
|
store: .init(
|
||||||
|
initialState: .placeholder,
|
||||||
|
reducer: SendReducer.default(
|
||||||
|
whenDone: { SandboxViewStore(store).send(.updateRoute(nil)) }
|
||||||
|
)
|
||||||
|
.debug(),
|
||||||
|
environment: ()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
case .recoveryPhraseDisplay:
|
||||||
|
RecoveryPhraseDisplayView(store: .demo)
|
||||||
|
case .scan:
|
||||||
|
ScanView()
|
||||||
|
case .profile:
|
||||||
|
ProfileView(store: store.profileStore())
|
||||||
|
case .request:
|
||||||
|
RequestView()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
WithViewStore(store) { viewStore in
|
||||||
|
VStack {
|
||||||
|
List {
|
||||||
|
Section(header: Text("Navigation Stack Routes")) {
|
||||||
|
ForEach(navigationRouteValues) { routeValue in
|
||||||
|
Text("\(String(describing: routeValue.route))")
|
||||||
|
.navigationLink(
|
||||||
|
isActive: viewStore.bindingForRoute(routeValue.route),
|
||||||
|
destination: {
|
||||||
|
view(for: routeValue.route)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Section(header: Text("Modal Routes")) {
|
||||||
|
ForEach(modalRoutes) { routeValue in
|
||||||
|
Button(
|
||||||
|
action: { viewStore.send(.updateRoute(routeValue.route)) },
|
||||||
|
label: { Text("\(String(describing: routeValue.route))") }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Section(header: Text("Other Actions")) {
|
||||||
|
Button(
|
||||||
|
action: { viewStore.toggleSelectedTransaction() },
|
||||||
|
label: { Text("Toggle Selected Transaction") }
|
||||||
|
)
|
||||||
|
|
||||||
|
Button(
|
||||||
|
action: { viewStore.send(.reset) },
|
||||||
|
label: { Text("Reset (to startup)") }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.fullScreenCover(
|
||||||
|
isPresented: viewStore.bindingForRoute(.history),
|
||||||
|
content: {
|
||||||
|
NavigationView {
|
||||||
|
TransactionHistoryView(store: store.historyStore())
|
||||||
|
.toolbar {
|
||||||
|
ToolbarItem {
|
||||||
|
Button("Done") { viewStore.send(.updateRoute(nil)) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.navigationBarTitle("Sandbox")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SandboxRouteValue: Identifiable {
|
||||||
|
let id: Int
|
||||||
|
let route: SandboxState.Route
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Previews
|
||||||
|
|
||||||
|
extension SandboxStore {
|
||||||
|
static var placeholder: SandboxStore {
|
||||||
|
SandboxStore(
|
||||||
|
initialState: SandboxState(
|
||||||
|
transactionHistoryState: .placeHolder,
|
||||||
|
profileState: .placeholder,
|
||||||
|
route: nil
|
||||||
|
),
|
||||||
|
reducer: .default.debug(),
|
||||||
|
environment: ()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SandboxView_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
NavigationView {
|
||||||
|
SandboxView(store: .placeholder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,7 +16,6 @@ extension WelcomeState {
|
||||||
|
|
||||||
enum WelcomeAction: Equatable {
|
enum WelcomeAction: Equatable {
|
||||||
case debugMenuStartup
|
case debugMenuStartup
|
||||||
case debugMenuHome
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typealias WelcomeReducer = Reducer<WelcomeState, WelcomeAction, Void>
|
typealias WelcomeReducer = Reducer<WelcomeState, WelcomeAction, Void>
|
||||||
|
|
|
@ -41,9 +41,7 @@ struct WelcomeView: View {
|
||||||
.onEnded { value in
|
.onEnded { value in
|
||||||
guard case .second(true, let drag?) = value else { return }
|
guard case .second(true, let drag?) = value else { return }
|
||||||
|
|
||||||
if drag.translation.height < 0 {
|
if drag.translation.height > 0 {
|
||||||
ViewStore(store).send(.debugMenuHome)
|
|
||||||
} else {
|
|
||||||
ViewStore(store).send(.debugMenuStartup)
|
ViewStore(store).send(.debugMenuStartup)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue