diff --git a/secant.xcodeproj/project.pbxproj b/secant.xcodeproj/project.pbxproj index 0765707..b43afbe 100644 --- a/secant.xcodeproj/project.pbxproj +++ b/secant.xcodeproj/project.pbxproj @@ -7,27 +7,12 @@ objects = { /* Begin PBXBuildFile section */ - 0D170A7226BC802800EB6A46 /* Router.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D170A7126BC802800EB6A46 /* Router.swift */; }; 0D185819272723FF0046B928 /* BlueChip.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D185818272723FF0046B928 /* BlueChip.swift */; }; 0D18581B272728D60046B928 /* PhraseChip.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D18581A272728D60046B928 /* PhraseChip.swift */; }; - 0D1922EA26BDD96A00052649 /* ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D1922E926BDD96A00052649 /* ViewModel.swift */; }; - 0D1922ED26BDE0C600052649 /* AppRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D1922EC26BDE0C600052649 /* AppRouter.swift */; }; 0D1922F226BDE29300052649 /* ZcashSDKStubs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D1922F126BDE29300052649 /* ZcashSDKStubs.swift */; }; 0D1922F826BDEB3500052649 /* MockServices.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D1922F726BDEB3500052649 /* MockServices.swift */; }; 0D1C1AA327611EFD0004AF6A /* RecoveryPhraseDisplayReducerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D1C1AA227611EFD0004AF6A /* RecoveryPhraseDisplayReducerTests.swift */; }; 0D2ACE8026C2C67100D62E3C /* Zboto.otf in Resources */ = {isa = PBXBuildFile; fileRef = 0D2ACE7F26C2C67100D62E3C /* Zboto.otf */; }; - 0D32281926C5864B00262533 /* ProfileScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D32281726C5864B00262533 /* ProfileScreen.swift */; }; - 0D32281A26C5864B00262533 /* ProfileScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D32281826C5864B00262533 /* ProfileScreenViewModel.swift */; }; - 0D32281E26C5867D00262533 /* ScanQrScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D32281C26C5867D00262533 /* ScanQrScreen.swift */; }; - 0D32281F26C5867D00262533 /* ScanQrScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D32281D26C5867D00262533 /* ScanQrScreenViewModel.swift */; }; - 0D32282326C586A800262533 /* HistoryScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D32282126C586A800262533 /* HistoryScreen.swift */; }; - 0D32282426C586A800262533 /* HistoryScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D32282226C586A800262533 /* HistoryScreenViewModel.swift */; }; - 0D32282826C586E000262533 /* RequestZcashScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D32282626C586E000262533 /* RequestZcashScreen.swift */; }; - 0D32282926C586E000262533 /* RequestZcashScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D32282726C586E000262533 /* RequestZcashScreenViewModel.swift */; }; - 0D32282D26C5870B00262533 /* SendScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D32282B26C5870B00262533 /* SendScreen.swift */; }; - 0D32282E26C5870B00262533 /* SendScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D32282C26C5870B00262533 /* SendScreenViewModel.swift */; }; - 0D32283226C5877A00262533 /* BalanceScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D32283026C5877A00262533 /* BalanceScreen.swift */; }; - 0D32283326C5877A00262533 /* BalanceScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D32283126C5877A00262533 /* BalanceScreenViewModel.swift */; }; 0D354A0926D5A9D000315F45 /* Services.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D354A0626D5A9D000315F45 /* Services.swift */; }; 0D354A0A26D5A9D000315F45 /* KeyStoring.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D354A0726D5A9D000315F45 /* KeyStoring.swift */; }; 0D354A0B26D5A9D000315F45 /* MnemonicSeedPhraseHandling.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D354A0826D5A9D000315F45 /* MnemonicSeedPhraseHandling.swift */; }; @@ -44,21 +29,8 @@ 0D535FE2271F9476009A9E3E /* EnumeratedChip.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D535FE1271F9476009A9E3E /* EnumeratedChip.swift */; }; 0D5D16F526E24CCF00AD33D1 /* AppError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D5D16F426E24CCF00AD33D1 /* AppError.swift */; }; 0D7DF08C271DCC0E00530046 /* ScreenBackground.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D7DF08B271DCC0E00530046 /* ScreenBackground.swift */; }; - 0D864A0526E1546000A61879 /* LoadingScreenTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D864A0426E1546000A61879 /* LoadingScreenTests.swift */; }; - 0D864A0926E154FD00A61879 /* InitFailedScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D864A0726E154FD00A61879 /* InitFailedScreen.swift */; }; - 0D864A0A26E154FD00A61879 /* InitFailedScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D864A0826E154FD00A61879 /* InitFailedScreenViewModel.swift */; }; - 0D864A0E26E1583000A61879 /* LoadingScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D864A0C26E1583000A61879 /* LoadingScreen.swift */; }; - 0D864A0F26E1583000A61879 /* LoadingScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D864A0D26E1583000A61879 /* LoadingScreenViewModel.swift */; }; 0D8A43C4272AEEDE005A6414 /* SecantTextStyles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D8A43C3272AEEDE005A6414 /* SecantTextStyles.swift */; }; 0D8A43C6272B129C005A6414 /* WordChipGrid.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D8A43C5272B129C005A6414 /* WordChipGrid.swift */; }; - 0DA13C8F26C15D1D00E3B610 /* WelcomeScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DA13C8D26C15D1D00E3B610 /* WelcomeScreen.swift */; }; - 0DA13C9026C15D1D00E3B610 /* WelcomeScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DA13C8E26C15D1D00E3B610 /* WelcomeScreenViewModel.swift */; }; - 0DA13C9726C186FF00E3B610 /* RestoreWalletScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DA13C9526C186FF00E3B610 /* RestoreWalletScreen.swift */; }; - 0DA13C9826C186FF00E3B610 /* RestoreWalletScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DA13C9626C186FF00E3B610 /* RestoreWalletScreenViewModel.swift */; }; - 0DA13C9C26C1942100E3B610 /* BackupWalletScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DA13C9A26C1942100E3B610 /* BackupWalletScreen.swift */; }; - 0DA13C9D26C1942100E3B610 /* BackupWalletScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DA13C9B26C1942100E3B610 /* BackupWalletScreenViewModel.swift */; }; - 0DA13CA126C1955600E3B610 /* HomeScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DA13C9F26C1955600E3B610 /* HomeScreen.swift */; }; - 0DA13CA226C1955600E3B610 /* HomeScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DA13CA026C1955600E3B610 /* HomeScreenViewModel.swift */; }; 0DA13CA526C1963000E3B610 /* Balance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DA13CA426C1963000E3B610 /* Balance.swift */; }; 0DACFA7F27208CE00039EEA5 /* Clamped.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DACFA7E27208CE00039EEA5 /* Clamped.swift */; }; 0DACFA8127208D940039EEA5 /* UInt+SuperscriptText.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DACFA8027208D940039EEA5 /* UInt+SuperscriptText.swift */; }; @@ -107,6 +79,18 @@ F96B41E8273B501F0021B49A /* TransactionDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F96B41E5273B501F0021B49A /* TransactionDetailView.swift */; }; F96B41E9273B501F0021B49A /* TransactionHistoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F96B41E6273B501F0021B49A /* TransactionHistoryView.swift */; }; F96B41EB273B50520021B49A /* Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = F96B41EA273B50520021B49A /* Strings.swift */; }; + F9971A4D27680DC400A2DB75 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9971A4A27680DC400A2DB75 /* App.swift */; }; + F9971A4E27680DC400A2DB75 /* AppView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9971A4C27680DC400A2DB75 /* AppView.swift */; }; + F9971A5327680DD000A2DB75 /* Profile.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9971A5027680DD000A2DB75 /* Profile.swift */; }; + F9971A5427680DD000A2DB75 /* ProfileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9971A5227680DD000A2DB75 /* ProfileView.swift */; }; + F9971A5927680DDE00A2DB75 /* Request.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9971A5627680DDE00A2DB75 /* Request.swift */; }; + F9971A5A27680DDE00A2DB75 /* RequestView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9971A5827680DDE00A2DB75 /* RequestView.swift */; }; + F9971A5F27680DF600A2DB75 /* ScanView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9971A5D27680DF600A2DB75 /* ScanView.swift */; }; + F9971A6027680DF600A2DB75 /* Scan.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9971A5E27680DF600A2DB75 /* Scan.swift */; }; + F9971A6527680DFE00A2DB75 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9971A6227680DFE00A2DB75 /* Settings.swift */; }; + F9971A6627680DFE00A2DB75 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9971A6427680DFE00A2DB75 /* SettingsView.swift */; }; + F9971A6B27680E1000A2DB75 /* WalletInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9971A6827680E1000A2DB75 /* WalletInfo.swift */; }; + F9971A6C27680E1000A2DB75 /* WalletInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9971A6A27680E1000A2DB75 /* WalletInfoView.swift */; }; F9C165B4274031F600592F76 /* Bindings.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C165B3274031F600592F76 /* Bindings.swift */; }; F9C165BF2740403600592F76 /* SendStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C165B72740403600592F76 /* SendStore.swift */; }; F9C165C02740403600592F76 /* ApproveView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C165B92740403600592F76 /* ApproveView.swift */; }; @@ -134,27 +118,12 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 0D170A7126BC802800EB6A46 /* Router.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Router.swift; sourceTree = ""; }; 0D185818272723FF0046B928 /* BlueChip.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlueChip.swift; sourceTree = ""; }; 0D18581A272728D60046B928 /* PhraseChip.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhraseChip.swift; sourceTree = ""; }; - 0D1922E926BDD96A00052649 /* ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewModel.swift; sourceTree = ""; }; - 0D1922EC26BDE0C600052649 /* AppRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppRouter.swift; sourceTree = ""; }; 0D1922F126BDE29300052649 /* ZcashSDKStubs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZcashSDKStubs.swift; sourceTree = ""; }; 0D1922F726BDEB3500052649 /* MockServices.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockServices.swift; sourceTree = ""; }; 0D1C1AA227611EFD0004AF6A /* RecoveryPhraseDisplayReducerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecoveryPhraseDisplayReducerTests.swift; sourceTree = ""; }; 0D2ACE7F26C2C67100D62E3C /* Zboto.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = Zboto.otf; sourceTree = ""; }; - 0D32281726C5864B00262533 /* ProfileScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileScreen.swift; sourceTree = ""; }; - 0D32281826C5864B00262533 /* ProfileScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileScreenViewModel.swift; sourceTree = ""; }; - 0D32281C26C5867D00262533 /* ScanQrScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanQrScreen.swift; sourceTree = ""; }; - 0D32281D26C5867D00262533 /* ScanQrScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanQrScreenViewModel.swift; sourceTree = ""; }; - 0D32282126C586A800262533 /* HistoryScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryScreen.swift; sourceTree = ""; }; - 0D32282226C586A800262533 /* HistoryScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryScreenViewModel.swift; sourceTree = ""; }; - 0D32282626C586E000262533 /* RequestZcashScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RequestZcashScreen.swift; sourceTree = ""; }; - 0D32282726C586E000262533 /* RequestZcashScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RequestZcashScreenViewModel.swift; sourceTree = ""; }; - 0D32282B26C5870B00262533 /* SendScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendScreen.swift; sourceTree = ""; }; - 0D32282C26C5870B00262533 /* SendScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendScreenViewModel.swift; sourceTree = ""; }; - 0D32283026C5877A00262533 /* BalanceScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BalanceScreen.swift; sourceTree = ""; }; - 0D32283126C5877A00262533 /* BalanceScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BalanceScreenViewModel.swift; sourceTree = ""; }; 0D354A0626D5A9D000315F45 /* Services.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Services.swift; sourceTree = ""; }; 0D354A0726D5A9D000315F45 /* KeyStoring.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyStoring.swift; sourceTree = ""; }; 0D354A0826D5A9D000315F45 /* MnemonicSeedPhraseHandling.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MnemonicSeedPhraseHandling.swift; sourceTree = ""; }; @@ -177,21 +146,8 @@ 0D535FE1271F9476009A9E3E /* EnumeratedChip.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnumeratedChip.swift; sourceTree = ""; }; 0D5D16F426E24CCF00AD33D1 /* AppError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppError.swift; sourceTree = ""; }; 0D7DF08B271DCC0E00530046 /* ScreenBackground.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenBackground.swift; sourceTree = ""; }; - 0D864A0426E1546000A61879 /* LoadingScreenTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadingScreenTests.swift; sourceTree = ""; }; - 0D864A0726E154FD00A61879 /* InitFailedScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InitFailedScreen.swift; sourceTree = ""; }; - 0D864A0826E154FD00A61879 /* InitFailedScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InitFailedScreenViewModel.swift; sourceTree = ""; }; - 0D864A0C26E1583000A61879 /* LoadingScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadingScreen.swift; sourceTree = ""; }; - 0D864A0D26E1583000A61879 /* LoadingScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadingScreenViewModel.swift; sourceTree = ""; }; 0D8A43C3272AEEDE005A6414 /* SecantTextStyles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecantTextStyles.swift; sourceTree = ""; }; 0D8A43C5272B129C005A6414 /* WordChipGrid.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WordChipGrid.swift; sourceTree = ""; }; - 0DA13C8D26C15D1D00E3B610 /* WelcomeScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeScreen.swift; sourceTree = ""; }; - 0DA13C8E26C15D1D00E3B610 /* WelcomeScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeScreenViewModel.swift; sourceTree = ""; }; - 0DA13C9526C186FF00E3B610 /* RestoreWalletScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RestoreWalletScreen.swift; sourceTree = ""; }; - 0DA13C9626C186FF00E3B610 /* RestoreWalletScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RestoreWalletScreenViewModel.swift; sourceTree = ""; }; - 0DA13C9A26C1942100E3B610 /* BackupWalletScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackupWalletScreen.swift; sourceTree = ""; }; - 0DA13C9B26C1942100E3B610 /* BackupWalletScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackupWalletScreenViewModel.swift; sourceTree = ""; }; - 0DA13C9F26C1955600E3B610 /* HomeScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreen.swift; sourceTree = ""; }; - 0DA13CA026C1955600E3B610 /* HomeScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenViewModel.swift; sourceTree = ""; }; 0DA13CA426C1963000E3B610 /* Balance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Balance.swift; sourceTree = ""; }; 0DACFA7E27208CE00039EEA5 /* Clamped.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Clamped.swift; sourceTree = ""; }; 0DACFA8027208D940039EEA5 /* UInt+SuperscriptText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UInt+SuperscriptText.swift"; sourceTree = ""; }; @@ -240,6 +196,18 @@ F96B41E5273B501F0021B49A /* TransactionDetailView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionDetailView.swift; sourceTree = ""; }; F96B41E6273B501F0021B49A /* TransactionHistoryView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionHistoryView.swift; sourceTree = ""; }; F96B41EA273B50520021B49A /* Strings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Strings.swift; sourceTree = ""; }; + F9971A4A27680DC400A2DB75 /* App.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = ""; }; + F9971A4C27680DC400A2DB75 /* AppView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppView.swift; sourceTree = ""; }; + F9971A5027680DD000A2DB75 /* Profile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Profile.swift; sourceTree = ""; }; + F9971A5227680DD000A2DB75 /* ProfileView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProfileView.swift; sourceTree = ""; }; + F9971A5627680DDE00A2DB75 /* Request.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Request.swift; sourceTree = ""; }; + F9971A5827680DDE00A2DB75 /* RequestView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RequestView.swift; sourceTree = ""; }; + F9971A5D27680DF600A2DB75 /* ScanView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScanView.swift; sourceTree = ""; }; + F9971A5E27680DF600A2DB75 /* Scan.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Scan.swift; sourceTree = ""; }; + F9971A6227680DFE00A2DB75 /* Settings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Settings.swift; sourceTree = ""; }; + F9971A6427680DFE00A2DB75 /* SettingsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = ""; }; + F9971A6827680E1000A2DB75 /* WalletInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletInfo.swift; sourceTree = ""; }; + F9971A6A27680E1000A2DB75 /* WalletInfoView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletInfoView.swift; sourceTree = ""; }; F9C165B3274031F600592F76 /* Bindings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bindings.swift; sourceTree = ""; }; F9C165B72740403600592F76 /* SendStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SendStore.swift; sourceTree = ""; }; F9C165B92740403600592F76 /* ApproveView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApproveView.swift; sourceTree = ""; }; @@ -275,15 +243,7 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 0D170A7326BC802E00EB6A46 /* Routers */ = { - isa = PBXGroup; - children = ( - 0D1922EC26BDE0C600052649 /* AppRouter.swift */, - ); - path = Routers; - sourceTree = ""; - }; - 0D170A7426BC9B7500EB6A46 /* MockedDependencies */ = { + 0D170A7426BC9B7500EB6A46 /* Mocked Dependencies */ = { isa = PBXGroup; children = ( 0D354A0726D5A9D000315F45 /* KeyStoring.swift */, @@ -293,31 +253,10 @@ path = MockedDependencies; sourceTree = ""; }; - 0D1922E826BDD95000052649 /* Base */ = { - isa = PBXGroup; - children = ( - 0D170A7126BC802800EB6A46 /* Router.swift */, - 0D1922E926BDD96A00052649 /* ViewModel.swift */, - ); - path = Base; - sourceTree = ""; - }; 0D1922EB26BDD9A500052649 /* Screens */ = { isa = PBXGroup; children = ( 2E5C037F2738C55F008BFFD3 /* Onboarding */, - 0D864A0B26E1580700A61879 /* Loading */, - 0D864A0626E154D100A61879 /* Error */, - 0D32282F26C5874B00262533 /* Balance */, - 0D32282A26C586E700262533 /* Send ZEC */, - 0D32282526C586C600262533 /* Request ZEC */, - 0D32282026C5868F00262533 /* History */, - 0D32281B26C5865900262533 /* Scan */, - 0D32281526C5862400262533 /* Profile */, - 0DA13C9E26C1953F00E3B610 /* Home */, - 0DA13C9926C193FE00E3B610 /* Backup Wallet */, - 0DA13C9426C186B100E3B610 /* Restore Wallet */, - 0DA13C8C26C15CBE00E3B610 /* Welcome Screen */, ); path = Screens; sourceTree = ""; @@ -341,60 +280,6 @@ path = Fonts; sourceTree = ""; }; - 0D32281526C5862400262533 /* Profile */ = { - isa = PBXGroup; - children = ( - 0D32281726C5864B00262533 /* ProfileScreen.swift */, - 0D32281826C5864B00262533 /* ProfileScreenViewModel.swift */, - ); - path = Profile; - sourceTree = ""; - }; - 0D32281B26C5865900262533 /* Scan */ = { - isa = PBXGroup; - children = ( - 0D32281C26C5867D00262533 /* ScanQrScreen.swift */, - 0D32281D26C5867D00262533 /* ScanQrScreenViewModel.swift */, - ); - path = Scan; - sourceTree = ""; - }; - 0D32282026C5868F00262533 /* History */ = { - isa = PBXGroup; - children = ( - 0D32282126C586A800262533 /* HistoryScreen.swift */, - 0D32282226C586A800262533 /* HistoryScreenViewModel.swift */, - ); - path = History; - sourceTree = ""; - }; - 0D32282526C586C600262533 /* Request ZEC */ = { - isa = PBXGroup; - children = ( - 0D32282626C586E000262533 /* RequestZcashScreen.swift */, - 0D32282726C586E000262533 /* RequestZcashScreenViewModel.swift */, - ); - path = "Request ZEC"; - sourceTree = ""; - }; - 0D32282A26C586E700262533 /* Send ZEC */ = { - isa = PBXGroup; - children = ( - 0D32282B26C5870B00262533 /* SendScreen.swift */, - 0D32282C26C5870B00262533 /* SendScreenViewModel.swift */, - ); - path = "Send ZEC"; - sourceTree = ""; - }; - 0D32282F26C5874B00262533 /* Balance */ = { - isa = PBXGroup; - children = ( - 0D32283026C5877A00262533 /* BalanceScreen.swift */, - 0D32283126C5877A00262533 /* BalanceScreenViewModel.swift */, - ); - path = Balance; - sourceTree = ""; - }; 0D3D04052728B2D70032ABC1 /* BackupFlow */ = { isa = PBXGroup; children = ( @@ -446,15 +331,13 @@ 0DA13C9126C15E1900E3B610 /* UIComponents */, 0D1922F026BDE27D00052649 /* Stubs */, 0D1922EB26BDD9A500052649 /* Screens */, - 0D1922E826BDD95000052649 /* Base */, - 0D170A7426BC9B7500EB6A46 /* MockedDependencies */, + 0D170A7426BC9B7500EB6A46 /* Mocked Dependencies */, 0D4E7A0826B364170058B01E /* SecantApp.swift */, 0D4E7A0A26B364170058B01E /* ContentView.swift */, 0D4E7A0C26B364180058B01E /* Assets.xcassets */, 660558E8270C7A54009D6954 /* Colors.xcassets */, 0D4E7A1126B364180058B01E /* Info.plist */, 0D4E7A0E26B364180058B01E /* Preview Content */, - 0D170A7326BC802E00EB6A46 /* Routers */, ); path = secant; sourceTree = ""; @@ -474,7 +357,6 @@ 6654C7422715A48E00901167 /* OnboardingTests */, 0D4E7A1A26B364180058B01E /* secantTests.swift */, 0D4E7A1C26B364180058B01E /* Info.plist */, - 0D864A0426E1546000A61879 /* LoadingScreenTests.swift */, ); path = secantTests; sourceTree = ""; @@ -516,24 +398,6 @@ path = AppErrors; sourceTree = ""; }; - 0D864A0626E154D100A61879 /* Error */ = { - isa = PBXGroup; - children = ( - 0D864A0726E154FD00A61879 /* InitFailedScreen.swift */, - 0D864A0826E154FD00A61879 /* InitFailedScreenViewModel.swift */, - ); - path = Error; - sourceTree = ""; - }; - 0D864A0B26E1580700A61879 /* Loading */ = { - isa = PBXGroup; - children = ( - 0D864A0C26E1583000A61879 /* LoadingScreen.swift */, - 0D864A0D26E1583000A61879 /* LoadingScreenViewModel.swift */, - ); - path = Loading; - sourceTree = ""; - }; 0D8A43C2272AEEA7005A6414 /* FontStyles */ = { isa = PBXGroup; children = ( @@ -542,16 +406,7 @@ path = FontStyles; sourceTree = ""; }; - 0DA13C8C26C15CBE00E3B610 /* Welcome Screen */ = { - isa = PBXGroup; - children = ( - 0DA13C8D26C15D1D00E3B610 /* WelcomeScreen.swift */, - 0DA13C8E26C15D1D00E3B610 /* WelcomeScreenViewModel.swift */, - ); - path = "Welcome Screen"; - sourceTree = ""; - }; - 0DA13C9126C15E1900E3B610 /* UIComponents */ = { + 0DA13C9126C15E1900E3B610 /* UI Components */ = { isa = PBXGroup; children = ( 0D8A43C2272AEEA7005A6414 /* FontStyles */, @@ -566,33 +421,6 @@ path = UIComponents; sourceTree = ""; }; - 0DA13C9426C186B100E3B610 /* Restore Wallet */ = { - isa = PBXGroup; - children = ( - 0DA13C9526C186FF00E3B610 /* RestoreWalletScreen.swift */, - 0DA13C9626C186FF00E3B610 /* RestoreWalletScreenViewModel.swift */, - ); - path = "Restore Wallet"; - sourceTree = ""; - }; - 0DA13C9926C193FE00E3B610 /* Backup Wallet */ = { - isa = PBXGroup; - children = ( - 0DA13C9A26C1942100E3B610 /* BackupWalletScreen.swift */, - 0DA13C9B26C1942100E3B610 /* BackupWalletScreenViewModel.swift */, - ); - path = "Backup Wallet"; - sourceTree = ""; - }; - 0DA13C9E26C1953F00E3B610 /* Home */ = { - isa = PBXGroup; - children = ( - 0DA13C9F26C1955600E3B610 /* HomeScreen.swift */, - 0DA13CA026C1955600E3B610 /* HomeScreenViewModel.swift */, - ); - path = Home; - sourceTree = ""; - }; 0DA13CA326C1960A00E3B610 /* Models */ = { isa = PBXGroup; children = ( @@ -695,11 +523,17 @@ 6654C73B2715A3F000901167 /* Features */ = { isa = PBXGroup; children = ( + F9971A4927680DC400A2DB75 /* App */, F93874EC273C4DE200F0E875 /* Home */, + F9971A4F27680DD000A2DB75 /* Profile */, + F9971A5527680DDE00A2DB75 /* Request */, + F9971A5B27680DF600A2DB75 /* Scan */, F9C165B62740403600592F76 /* Send */, + F9971A6127680DFE00A2DB75 /* Settings */, F96B41E2273B501F0021B49A /* TransactionHistory */, 0D3D04052728B2D70032ABC1 /* BackupFlow */, 6654C73C2715A3FA00901167 /* Onboarding */, + F9971A6727680E1000A2DB75 /* WalletInfo */, ); path = Features; sourceTree = ""; @@ -790,6 +624,108 @@ path = Views; sourceTree = ""; }; + F9971A4927680DC400A2DB75 /* App */ = { + isa = PBXGroup; + children = ( + F9971A4A27680DC400A2DB75 /* App.swift */, + F9971A4B27680DC400A2DB75 /* Views */, + ); + path = App; + sourceTree = ""; + }; + F9971A4B27680DC400A2DB75 /* Views */ = { + isa = PBXGroup; + children = ( + F9971A4C27680DC400A2DB75 /* AppView.swift */, + ); + path = Views; + sourceTree = ""; + }; + F9971A4F27680DD000A2DB75 /* Profile */ = { + isa = PBXGroup; + children = ( + F9971A5027680DD000A2DB75 /* Profile.swift */, + F9971A5127680DD000A2DB75 /* Views */, + ); + path = Profile; + sourceTree = ""; + }; + F9971A5127680DD000A2DB75 /* Views */ = { + isa = PBXGroup; + children = ( + F9971A5227680DD000A2DB75 /* ProfileView.swift */, + ); + path = Views; + sourceTree = ""; + }; + F9971A5527680DDE00A2DB75 /* Request */ = { + isa = PBXGroup; + children = ( + F9971A5627680DDE00A2DB75 /* Request.swift */, + F9971A5727680DDE00A2DB75 /* Views */, + ); + path = Request; + sourceTree = ""; + }; + F9971A5727680DDE00A2DB75 /* Views */ = { + isa = PBXGroup; + children = ( + F9971A5827680DDE00A2DB75 /* RequestView.swift */, + ); + path = Views; + sourceTree = ""; + }; + F9971A5B27680DF600A2DB75 /* Scan */ = { + isa = PBXGroup; + children = ( + F9971A5C27680DF600A2DB75 /* Views */, + F9971A5E27680DF600A2DB75 /* Scan.swift */, + ); + path = Scan; + sourceTree = ""; + }; + F9971A5C27680DF600A2DB75 /* Views */ = { + isa = PBXGroup; + children = ( + F9971A5D27680DF600A2DB75 /* ScanView.swift */, + ); + path = Views; + sourceTree = ""; + }; + F9971A6127680DFE00A2DB75 /* Settings */ = { + isa = PBXGroup; + children = ( + F9971A6227680DFE00A2DB75 /* Settings.swift */, + F9971A6327680DFE00A2DB75 /* Views */, + ); + path = Settings; + sourceTree = ""; + }; + F9971A6327680DFE00A2DB75 /* Views */ = { + isa = PBXGroup; + children = ( + F9971A6427680DFE00A2DB75 /* SettingsView.swift */, + ); + path = Views; + sourceTree = ""; + }; + F9971A6727680E1000A2DB75 /* WalletInfo */ = { + isa = PBXGroup; + children = ( + F9971A6827680E1000A2DB75 /* WalletInfo.swift */, + F9971A6927680E1000A2DB75 /* Views */, + ); + path = WalletInfo; + sourceTree = ""; + }; + F9971A6927680E1000A2DB75 /* Views */ = { + isa = PBXGroup; + children = ( + F9971A6A27680E1000A2DB75 /* WalletInfoView.swift */, + ); + path = Views; + sourceTree = ""; + }; F9C165B62740403600592F76 /* Send */ = { isa = PBXGroup; children = ( @@ -1010,85 +946,70 @@ 2EB660E02747EAB900A06A07 /* OnboardingScreen.swift in Sources */, 660558F8270C862F009D6954 /* XCAssets+Generated.swift in Sources */, F96B41E9273B501F0021B49A /* TransactionHistoryView.swift in Sources */, - 0D32281F26C5867D00262533 /* ScanQrScreenViewModel.swift in Sources */, 669FDAE9272C23B3007B9422 /* CircularFrame.swift in Sources */, - 0D32282E26C5870B00262533 /* SendScreenViewModel.swift in Sources */, F96B41E8273B501F0021B49A /* TransactionDetailView.swift in Sources */, - 0D32282D26C5870B00262533 /* SendScreen.swift in Sources */, 663FABA2271D876C00E495F8 /* SecondaryButton.swift in Sources */, - 0D1922ED26BDE0C600052649 /* AppRouter.swift in Sources */, 0D8A43C4272AEEDE005A6414 /* SecantTextStyles.swift in Sources */, 0D1922F226BDE29300052649 /* ZcashSDKStubs.swift in Sources */, - 0DA13C9D26C1942100E3B610 /* BackupWalletScreenViewModel.swift in Sources */, 0DACFA7F27208CE00039EEA5 /* Clamped.swift in Sources */, 0D354A0B26D5A9D000315F45 /* MnemonicSeedPhraseHandling.swift in Sources */, 0D535FE2271F9476009A9E3E /* EnumeratedChip.swift in Sources */, 6654C73E2715A41300901167 /* OnboardingStore.swift in Sources */, - 0D32281E26C5867D00262533 /* ScanQrScreen.swift in Sources */, + F9971A5327680DD000A2DB75 /* Profile.swift in Sources */, F93874F0273C4DE200F0E875 /* HomeStore.swift in Sources */, 669FDAEB272C23C2007B9422 /* CircularFrameBadge.swift in Sources */, - 0D864A0E26E1583000A61879 /* LoadingScreen.swift in Sources */, - 0DA13C9C26C1942100E3B610 /* BackupWalletScreen.swift in Sources */, - 0DA13C9826C186FF00E3B610 /* RestoreWalletScreenViewModel.swift in Sources */, + F9971A6C27680E1000A2DB75 /* WalletInfoView.swift in Sources */, F9EEB8162742C2210032EEB8 /* WithStateBinding.swift in Sources */, F93673D62742CB840099C6AF /* Previews.swift in Sources */, - 0D32283326C5877A00262533 /* BalanceScreenViewModel.swift in Sources */, 0D5D16F526E24CCF00AD33D1 /* AppError.swift in Sources */, 0D18581B272728D60046B928 /* PhraseChip.swift in Sources */, 665C963F272C26E600BC04FB /* CircularFrameBackground.swift in Sources */, 0DB8AA81271DC7520035BC9D /* DesignGuide.swift in Sources */, + F9971A4D27680DC400A2DB75 /* App.swift in Sources */, F9322DC0273B555C00C105B5 /* NavigationLinks.swift in Sources */, F93874F1273C4DE200F0E875 /* HomeView.swift in Sources */, - 0D32282326C586A800262533 /* HistoryScreen.swift in Sources */, 0D3D04082728B3440032ABC1 /* RecoveryPhraseDisplayView.swift in Sources */, - 0D864A0A26E154FD00A61879 /* InitFailedScreenViewModel.swift in Sources */, + F9971A5F27680DF600A2DB75 /* ScanView.swift in Sources */, + F9971A4E27680DC400A2DB75 /* AppView.swift in Sources */, 0DA13CA526C1963000E3B610 /* Balance.swift in Sources */, 2EA11F5B27467EF800709571 /* OnboardingFooterView.swift in Sources */, 66D50668271D9B6100E51F0D /* NavigationButtonStyle.swift in Sources */, 0D1922F826BDEB3500052649 /* MockServices.swift in Sources */, 0D3D040A2728B3A10032ABC1 /* RecoveryPhraseDisplayStore.swift in Sources */, 0D4E7A0B26B364170058B01E /* ContentView.swift in Sources */, - 0D170A7226BC802800EB6A46 /* Router.swift in Sources */, 0D354A0926D5A9D000315F45 /* Services.swift in Sources */, 660558F7270C862F009D6954 /* Fonts+Generated.swift in Sources */, F96B41E7273B501F0021B49A /* TransactionHistoryStore.swift in Sources */, - 0DA13C9726C186FF00E3B610 /* RestoreWalletScreen.swift in Sources */, + F9971A5A27680DDE00A2DB75 /* RequestView.swift in Sources */, 0DACFA8127208D940039EEA5 /* UInt+SuperscriptText.swift in Sources */, 0DF2DC51272344E400FA31E2 /* EmptyChip.swift in Sources */, F9C165BF2740403600592F76 /* SendStore.swift in Sources */, - 0D1922EA26BDD96A00052649 /* ViewModel.swift in Sources */, 0D4E7A0926B364170058B01E /* SecantApp.swift in Sources */, 66DC733F271D88CC0053CBB6 /* StandardButtonStyle.swift in Sources */, - 0D864A0926E154FD00A61879 /* InitFailedScreen.swift in Sources */, 663FABA0271D876200E495F8 /* PrimaryButton.swift in Sources */, 663FAB9C271D874D00E495F8 /* ActiveButton.swift in Sources */, F9C165C02740403600592F76 /* ApproveView.swift in Sources */, 0DF2DC5427235E3E00FA31E2 /* View+InnerShadow.swift in Sources */, - 0D32281A26C5864B00262533 /* ProfileScreenViewModel.swift in Sources */, + F9971A6B27680E1000A2DB75 /* WalletInfo.swift in Sources */, 0D185819272723FF0046B928 /* BlueChip.swift in Sources */, - 0D864A0F26E1583000A61879 /* LoadingScreenViewModel.swift in Sources */, 2EA11F5D27467F7700709571 /* OnboardingContentView.swift in Sources */, - 0DA13CA126C1955600E3B610 /* HomeScreen.swift in Sources */, - 0DA13C9026C15D1D00E3B610 /* WelcomeScreenViewModel.swift in Sources */, 2E58E73B274679F000B2B84B /* OnboardingHeaderView.swift in Sources */, 0D8A43C6272B129C005A6414 /* WordChipGrid.swift in Sources */, 66A0807B271993C500118B79 /* OnboardingProgressIndicator.swift in Sources */, 663FAB9E271D875700E495F8 /* CreateButton.swift in Sources */, 0D7DF08C271DCC0E00530046 /* ScreenBackground.swift in Sources */, F9C165C22740403600592F76 /* CreateView.swift in Sources */, - 0DA13C8F26C15D1D00E3B610 /* WelcomeScreen.swift in Sources */, F9C165B4274031F600592F76 /* Bindings.swift in Sources */, - 0D32282826C586E000262533 /* RequestZcashScreen.swift in Sources */, + F9971A6627680DFE00A2DB75 /* SettingsView.swift in Sources */, F96B41EB273B50520021B49A /* Strings.swift in Sources */, - 0D32283226C5877A00262533 /* BalanceScreen.swift in Sources */, 0D354A0A26D5A9D000315F45 /* KeyStoring.swift in Sources */, - 0DA13CA226C1955600E3B610 /* HomeScreenViewModel.swift in Sources */, - 0D32282926C586E000262533 /* RequestZcashScreenViewModel.swift in Sources */, - 0D32281926C5864B00262533 /* ProfileScreen.swift in Sources */, + F9971A5427680DD000A2DB75 /* ProfileView.swift in Sources */, + F9971A6027680DF600A2DB75 /* Scan.swift in Sources */, F9C165CB2741AB5D00592F76 /* SendView.swift in Sources */, + F9971A6527680DFE00A2DB75 /* Settings.swift in Sources */, 6654C7412715A47300901167 /* Onboarding.swift in Sources */, - 0D32282426C586A800262533 /* HistoryScreenViewModel.swift in Sources */, F9C165C42740403600592F76 /* SentView.swift in Sources */, + F9971A5927680DDE00A2DB75 /* Request.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1097,7 +1018,6 @@ buildActionMask = 2147483647; files = ( 0DFE93DF272C6D4B000FCCA5 /* RecoveryFlowTests.swift in Sources */, - 0D864A0526E1546000A61879 /* LoadingScreenTests.swift in Sources */, 6654C7442715A4AC00901167 /* OnboardingStoreTests.swift in Sources */, 0D1C1AA327611EFD0004AF6A /* RecoveryPhraseDisplayReducerTests.swift in Sources */, 0D4E7A1B26B364180058B01E /* secantTests.swift in Sources */, diff --git a/secant/Base/Router.swift b/secant/Base/Router.swift deleted file mode 100644 index a4aee11..0000000 --- a/secant/Base/Router.swift +++ /dev/null @@ -1,15 +0,0 @@ -// -// Router.swift -// secant -// -// Created by Francisco Gindre on 8/5/21. -// - -import Foundation -import SwiftUI - -public protocol Router: ObservableObject { - associatedtype ViewOutput: View - - func rootView() -> ViewOutput -} diff --git a/secant/Base/ViewModel.swift b/secant/Base/ViewModel.swift deleted file mode 100644 index c467180..0000000 --- a/secant/Base/ViewModel.swift +++ /dev/null @@ -1,16 +0,0 @@ -// -// ViewModel.swift -// secant -// -// Created by Francisco Gindre on 8/6/21. -// - -import Foundation - -open class BaseViewModel { - public var services: S - - public init(services: S) { - self.services = services - } -} diff --git a/secant/Features/App/App.swift b/secant/Features/App/App.swift new file mode 100644 index 0000000..079b381 --- /dev/null +++ b/secant/Features/App/App.swift @@ -0,0 +1,86 @@ +import ComposableArchitecture + +struct AppState: Equatable { + enum Route { + case startup + case onboarding + case home + } + var homeState: HomeState + var onboardingState: OnboardingState + var route: Route = .startup +} + +enum AppAction: Equatable { + case updateRoute(AppState.Route) + case home(HomeAction) + case onboarding(OnboardingAction) +} + +struct AppEnvironment: Equatable { +} + +// MARK: - AppReducer + +typealias AppReducer = Reducer + +extension AppReducer { + static let `default` = AppReducer.combine( + [ + routeReducer, + homeReducer, + onboardingReducer + ] + ) + + private static let routeReducer = AppReducer { state, action, _ in + switch action { + case let .updateRoute(route): + state.route = route + case .home(.reset): + state.route = .startup + case .onboarding(.createNewWallet): + state.route = .home + default: + break + } + return .none + } + + private static let homeReducer: AppReducer = HomeReducer.default.pullback( + state: \AppState.homeState, + action: /AppAction.home, + environment: { _ in } + ) + + private static let onboardingReducer: AppReducer = OnboardingReducer.default.pullback( + state: \AppState.onboardingState, + action: /AppAction.onboarding, + environment: { _ in } + ) +} + +// MARK: - AppStore + +typealias AppStore = Store + +extension AppStore { +} + +// MARK: - AppViewStore + +typealias AppViewStore = ViewStore + +extension AppViewStore { +} + +// MARK: PlaceHolders + +extension AppState { + static var placeholder: Self { + .init( + homeState: .placeholder, + onboardingState: .init() + ) + } +} diff --git a/secant/Features/App/Views/AppView.swift b/secant/Features/App/Views/AppView.swift new file mode 100644 index 0000000..f1926c2 --- /dev/null +++ b/secant/Features/App/Views/AppView.swift @@ -0,0 +1,67 @@ +import SwiftUI +import StoreKit +import ComposableArchitecture + +struct AppView: View { + let store: AppStore + + var body: some View { + WithViewStore(store) { viewStore in + switch viewStore.route { + case .home: + NavigationView { + HomeView( + store: store.scope( + state: \.homeState, + action: AppAction.home + ) + ) + } + .navigationViewStyle(StackNavigationViewStyle()) + case .onboarding: + OnboardingScreen( + store: store.scope( + state: \.onboardingState, + action: AppAction.onboarding + ) + ) + case .startup: + ZStack(alignment: .topTrailing) { + StartupView(sendAction: viewStore.send) + } + } + } + } +} + +private struct StartupView: View { + var sendAction: (AppAction) -> Void + + var body: some View { + List { + Section(header: Text("Navigation Stack Routes")) { + Button("Go To Home") { + sendAction(.updateRoute(.home)) + } + Button("Go To Onboarding") { + sendAction(.updateRoute(.onboarding)) + } + } + } + .navigationBarTitle("Startup") + } +} + +struct AppView_Previews: PreviewProvider { + static var previews: some View { + NavigationView { + AppView( + store: AppStore( + initialState: .placeholder, + reducer: .default, + environment: .init() + ) + ) + } + } +} diff --git a/secant/Features/Home/HomeStore.swift b/secant/Features/Home/HomeStore.swift index 5c768ae..77c06d7 100644 --- a/secant/Features/Home/HomeStore.swift +++ b/secant/Features/Home/HomeStore.swift @@ -2,19 +2,24 @@ import ComposableArchitecture import SwiftUI struct HomeState: Equatable { - enum Route: Equatable { + enum Route: Equatable, CaseIterable { case history case send - case onboarding case recoveryPhraseDisplay + case profile + case scan + case request } var transactionHistoryState: TransactionHistoryState + var profileState: ProfileState var route: Route? } enum HomeAction: Equatable { case updateRoute(HomeState.Route?) case transactionHistory(TransactionHistoryAction) + case profile(ProfileAction) + case reset } // MARK: - HomeReducer @@ -32,6 +37,18 @@ extension HomeReducer { .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 } } } @@ -47,6 +64,13 @@ extension HomeStore { action: HomeAction.transactionHistory ) } + + func profileStore() -> ProfileStore { + self.scope( + state: \.profileState, + action: HomeAction.profile + ) + } } // MARK: - HomeViewStore @@ -83,6 +107,15 @@ extension HomeViewStore { .map(\.id) } + func bindingForRoute(_ route: HomeState.Route) -> Binding { + self.binding( + get: { $0.route == route }, + send: { isActive in + return .updateRoute(isActive ? route : nil) + } + ) + } + var showHistoryBinding: Binding { self.binding( get: { $0.route == .history }, @@ -110,12 +143,24 @@ extension HomeViewStore { ) } - var showOnboardingBinding: Binding { + var showProfileBinding: Binding { self.binding( - get: { $0.route == .onboarding }, + get: { $0.route == .profile }, send: { isActive in - return .updateRoute(isActive ? .onboarding : nil) + return .updateRoute(isActive ? .profile : nil) } ) } } + +// MARK: PlaceHolders + +extension HomeState { + static var placeholder: Self { + .init( + transactionHistoryState: .placeHolder, + profileState: .placeholder, + route: nil + ) + } +} diff --git a/secant/Features/Home/Views/HomeView.swift b/secant/Features/Home/Views/HomeView.swift index 96861cc..09f5c15 100644 --- a/secant/Features/Home/Views/HomeView.swift +++ b/secant/Features/Home/Views/HomeView.swift @@ -4,98 +4,70 @@ import ComposableArchitecture struct HomeView: View { let store: Store + 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 { WithViewStore(store) { viewStore in VStack { - Button( - action: { viewStore.toggleShowingHistory() }, - label: { Text(viewStore.historyToggleString()) } - ) - .primaryButtonStyle - .frame(height: 50) + 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) + } + ) + } + } - Button( - action: { viewStore.toggleSelectedTransaction() }, - label: { Text("Toggle Selected Transaction") } - ) - .primaryButtonStyle - .frame(height: 50) + Section(header: Text("Other Actions")) { + Button( + action: { viewStore.toggleSelectedTransaction() }, + label: { Text("Toggle Selected Transaction") } + ) - Button( - action: { viewStore.send(.updateRoute(.recoveryPhraseDisplay)) }, - label: { Text("Show Recovery Phrase Demo") } - ) - .primaryButtonStyle - .frame(height: 50) - - Button( - action: { viewStore.send(.updateRoute(.send)) }, - label: { Text("Go to Send") } - ) - .primaryButtonStyle - .frame(height: 50) - - Button( - action: { viewStore.send(.updateRoute(.onboarding)) }, - label: { Text("Show Onboarding") } - ) - .primaryButtonStyle - .frame(height: 50) - - Spacer() - - HStack { - VStack(alignment: .leading) { - Text("Route: \(String(dumping: viewStore.route))") - Text( - // swiftlint:disable:next line_length - "SelectedTransaction: \(String(dumping: viewStore.transactionHistoryState.route.map(/TransactionHistoryState.Route.showTransaction)))" + Button( + action: { viewStore.send(.reset) }, + label: { Text("Reset (to startup)") } ) } - .multilineTextAlignment(.leading) - .frame(maxWidth: .infinity, alignment: .leading) } - - Spacer() } - .padding(.horizontal, 30) - .navigationBarTitle("Home", displayMode: .inline) - .navigationLinkEmpty( - isActive: viewStore.showPhraseDisplayBinding, - destination: { - RecoveryPhraseDisplayView(store: .demo) - } - ) - .navigationLinkEmpty( - isActive: viewStore.showSendBinding, - destination: { - SendView( - store: .init( - initialState: .init( - transaction: .demo, - route: nil - ), - reducer: SendReducer.default( - whenDone: { viewStore.send(.updateRoute(nil)) } - ) - .debug(), - environment: () - ) - ) - } - ) - .navigationLinkEmpty( - isActive: viewStore.showOnboardingBinding, - destination: { - OnboardingScreen( - store: Store( - initialState: OnboardingState(), - reducer: .default, - environment: () - ) - ) - } - ) .fullScreenCover( isPresented: viewStore.showHistoryBinding, content: { @@ -109,18 +81,24 @@ struct HomeView: View { } } ) + .navigationBarTitle("Home") } } } +struct RouteValue: Identifiable { + let id: Int + let route: HomeState.Route +} + +// MARK: - Previews + extension HomeStore { - static var demo: HomeStore { + static var placeholder: HomeStore { HomeStore( initialState: HomeState( - transactionHistoryState: .init( - transactions: .demo, - route: nil - ), + transactionHistoryState: .placeHolder, + profileState: .placeholder, route: nil ), reducer: .default.debug(), @@ -134,7 +112,7 @@ extension HomeStore { struct HomeView_Previews: PreviewProvider { static var previews: some View { NavigationView { - HomeView(store: .demo) + HomeView(store: .placeholder) } } } diff --git a/secant/Features/Profile/Profile.swift b/secant/Features/Profile/Profile.swift new file mode 100644 index 0000000..170e671 --- /dev/null +++ b/secant/Features/Profile/Profile.swift @@ -0,0 +1,80 @@ +import ComposableArchitecture +import SwiftUI + +struct ProfileState: Equatable { + enum Route { + case settings + case walletInfo + } + + var walletInfoState: WalletInfoState + var settingsState: SettingsState + var route: Route? +} + +enum ProfileAction: Equatable { + case updateRoute(ProfileState.Route?) +} + +struct ProfileEnvironment { +} + +// MARK: - ProfileReducer + +typealias ProfileReducer = Reducer + +extension ProfileReducer { + static let `default` = ProfileReducer { state, action, _ in + switch action { + case let .updateRoute(route): + state.route = route + return .none + } + } +} + +// MARK: - ProfileStore + +typealias ProfileStore = Store + +extension ProfileStore { +} + +// MARK: - ProfileViewStore + +typealias ProfileViewStore = ViewStore + +extension ProfileViewStore { + var routeBinding: Binding { + self.binding( + get: \.route, + send: ProfileAction.updateRoute + ) + } + + var bindingForWalletInfo: Binding { + self.routeBinding.map( + extract: { $0 == .walletInfo }, + embed: { $0 ? .walletInfo : nil } + ) + } + + var bindingForSettings: Binding { + self.routeBinding.map( + extract: { $0 == .settings }, + embed: { $0 ? .settings : nil } + ) + } +} + +// MARK: PlaceHolders + +extension ProfileState { + static var placeholder: Self { + .init( + walletInfoState: .init(), + settingsState: .init(), + route: nil + ) + } +} diff --git a/secant/Features/Profile/Views/ProfileView.swift b/secant/Features/Profile/Views/ProfileView.swift new file mode 100644 index 0000000..a0d573e --- /dev/null +++ b/secant/Features/Profile/Views/ProfileView.swift @@ -0,0 +1,46 @@ +import ComposableArchitecture +import SwiftUI + +struct ProfileView: View { + let store: ProfileStore + + var body: some View { + WithViewStore(store) { viewStore in + List { + Text("Go To Wallet Info") + .navigationLink( + isActive: viewStore.bindingForWalletInfo, + destination: { + Text("Wallet") + } + ) + + Text("Go To Settings") + .navigationLink( + isActive: viewStore.bindingForSettings, + destination: { + Text("Settings") + } + ) + } + .navigationTitle(Text("\(String(describing: Self.self))")) + } + } +} + +struct ProfileView_Previews: PreviewProvider { + static var previews: some View { + NavigationView { + ProfileView( + store: .init( + initialState: .init( + walletInfoState: .init(), + settingsState: .init() + ), + reducer: .default, + environment: .init() + ) + ) + } + } +} diff --git a/secant/Features/Request/Request.swift b/secant/Features/Request/Request.swift new file mode 100644 index 0000000..89beb84 --- /dev/null +++ b/secant/Features/Request/Request.swift @@ -0,0 +1,38 @@ +import ComposableArchitecture + +struct RequestState: Equatable { +} + +enum RequestAction: Equatable { + case noOp +} + +struct RequestEnvironment: Equatable { +} + +// MARK: - RequestReducer + +typealias RequestReducer = Reducer + +extension RequestReducer { + static let `default` = RequestReducer { _, action, _ in + switch action { + default: + return .none + } + } +} + +// MARK: - RequestStore + +typealias RequestStore = Store + +extension RequestStore { +} + +// MARK: - RequestViewStore + +typealias RequestViewStore = ViewStore + +extension RequestViewStore { +} diff --git a/secant/Features/Request/Views/RequestView.swift b/secant/Features/Request/Views/RequestView.swift new file mode 100644 index 0000000..cb89f28 --- /dev/null +++ b/secant/Features/Request/Views/RequestView.swift @@ -0,0 +1,13 @@ +import SwiftUI + +struct RequestView: View { + var body: some View { + Text("\(String(describing: Self.self)) PlaceHolder") + } +} + +struct RequestView_Previews: PreviewProvider { + static var previews: some View { + RequestView() + } +} diff --git a/secant/Features/Scan/Scan.swift b/secant/Features/Scan/Scan.swift new file mode 100644 index 0000000..3f745e4 --- /dev/null +++ b/secant/Features/Scan/Scan.swift @@ -0,0 +1,38 @@ +import ComposableArchitecture + +struct ScanState: Equatable { +} + +enum ScanAction: Equatable { + case noOp +} + +struct ScanEnvironment: Equatable { +} + +// MARK: - ScanReducer + +typealias ScanReducer = Reducer + +extension ScanReducer { + static let `default` = ScanReducer { _, action, _ in + switch action { + default: + return .none + } + } +} + +// MARK: - ScanStore + +typealias ScanStore = Store + +extension ScanStore { +} + +// MARK: - ScanViewStore + +typealias ScanViewStore = ViewStore + +extension ScanViewStore { +} diff --git a/secant/Features/Scan/Views/ScanView.swift b/secant/Features/Scan/Views/ScanView.swift new file mode 100644 index 0000000..5974a1b --- /dev/null +++ b/secant/Features/Scan/Views/ScanView.swift @@ -0,0 +1,13 @@ +import SwiftUI + +struct ScanView: View { + var body: some View { + Text("\(String(describing: Self.self)) PlaceHolder") + } +} + +struct ScanView_Previews: PreviewProvider { + static var previews: some View { + ScanView() + } +} diff --git a/secant/Features/Send/SendStore.swift b/secant/Features/Send/SendStore.swift index 095bdbb..50eebd2 100644 --- a/secant/Features/Send/SendStore.swift +++ b/secant/Features/Send/SendStore.swift @@ -85,3 +85,11 @@ extension SendViewStore { ) } } + +// MARK: PlaceHolders + +extension SendState { + static var placeholder: Self { + .init(transaction: .placeholder, route: nil) + } +} diff --git a/secant/Features/Send/Views/ApproveView.swift b/secant/Features/Send/Views/ApproveView.swift index 852df4e..c1eecaf 100644 --- a/secant/Features/Send/Views/ApproveView.swift +++ b/secant/Features/Send/Views/ApproveView.swift @@ -27,7 +27,7 @@ struct Approve: View { struct Approve_Previews: PreviewProvider { static var previews: some View { NavigationView { - StateContainer(initialState: (Transaction.demo, false)) { + StateContainer(initialState: (Transaction.placeholder, false)) { Approve( transaction: $0.0.wrappedValue, isComplete: $0.1 diff --git a/secant/Features/Send/Views/CreateView.swift b/secant/Features/Send/Views/CreateView.swift index 9e0c704..e77c7cc 100644 --- a/secant/Features/Send/Views/CreateView.swift +++ b/secant/Features/Send/Views/CreateView.swift @@ -46,7 +46,7 @@ struct Create: View { struct Create_Previews: PreviewProvider { static var previews: some View { NavigationView { - StateContainer(initialState: (Transaction.demo, false)) { + StateContainer(initialState: (Transaction.placeholder, false)) { Create( transaction: $0.0, isComplete: $0.1 @@ -59,10 +59,10 @@ struct Create_Previews: PreviewProvider { #if DEBUG extension SendStore { - static var demo: SendStore { + static var placeholder: SendStore { return SendStore( initialState: .init( - transaction: .demo, + transaction: .placeholder, route: nil ), reducer: .default, diff --git a/secant/Features/Send/Views/SendView.swift b/secant/Features/Send/Views/SendView.swift index 72c6a35..7a92281 100644 --- a/secant/Features/Send/Views/SendView.swift +++ b/secant/Features/Send/Views/SendView.swift @@ -44,7 +44,7 @@ struct SendView_Previews: PreviewProvider { SendView( store: .init( initialState: .init( - transaction: .demo, + transaction: .placeholder, route: nil ), reducer: .default, diff --git a/secant/Features/Send/Views/SentView.swift b/secant/Features/Send/Views/SentView.swift index cb3a74e..a352e5c 100644 --- a/secant/Features/Send/Views/SentView.swift +++ b/secant/Features/Send/Views/SentView.swift @@ -28,6 +28,6 @@ struct Sent: View { struct Done_Previews: PreviewProvider { static var previews: some View { - Sent(transaction: .demo, isComplete: .constant(false)) + Sent(transaction: .placeholder, isComplete: .constant(false)) } } diff --git a/secant/Features/Settings/Settings.swift b/secant/Features/Settings/Settings.swift new file mode 100644 index 0000000..e24750b --- /dev/null +++ b/secant/Features/Settings/Settings.swift @@ -0,0 +1,38 @@ +import ComposableArchitecture + +struct SettingsState: Equatable { +} + +enum SettingsAction: Equatable { + case noOp +} + +struct SettingsEnvironment: Equatable { +} + +// MARK: - SettingsStateReducer + +typealias SettingsReducer = Reducer + +extension SettingsReducer { + static let `default` = SettingsReducer { _, action, _ in + switch action { + default: + return .none + } + } +} + +// MARK: - SettingsStore + +typealias SettingsStore = Store + +extension SettingsStore { +} + +// MARK: - SettingsViewStore + +typealias SettingsViewStore = ViewStore + +extension SettingsViewStore { +} diff --git a/secant/Features/Settings/Views/SettingsView.swift b/secant/Features/Settings/Views/SettingsView.swift new file mode 100644 index 0000000..4fcecea --- /dev/null +++ b/secant/Features/Settings/Views/SettingsView.swift @@ -0,0 +1,13 @@ +import SwiftUI + +struct SettingsView: View { + var body: some View { + Text("\(String(describing: Self.self)) PlaceHolder") + } +} + +struct SettingsView_Previews: PreviewProvider { + static var previews: some View { + SettingsView() + } +} diff --git a/secant/Features/TransactionHistory/TransactionHistoryStore.swift b/secant/Features/TransactionHistory/TransactionHistoryStore.swift index e0e15ed..6549858 100644 --- a/secant/Features/TransactionHistory/TransactionHistoryStore.swift +++ b/secant/Features/TransactionHistory/TransactionHistoryStore.swift @@ -56,3 +56,61 @@ extension TransactionHistoryViewStore { ) } } + +// MARK: PlaceHolders + +extension Transaction { + static var placeholder: Self { + .init( + id: 2, + amount: 123, + memo: "defaultMemo", + toAddress: "ToAddress", + fromAddress: "FromAddress" + ) + } +} + +extension TransactionHistoryState { + static var placeHolder: Self { + .init(transactions: .placeholder, route: nil) + } +} + +extension TransactionHistoryStore { + static var placeholder: Store { + return Store( + initialState: .placeHolder, + reducer: .default, + environment: () + ) + } + + static var demoWithSelectedTransaction: Store { + let transactions = IdentifiedArrayOf.placeholder + return Store( + initialState: TransactionHistoryState( + transactions: transactions, + route: .showTransaction(transactions[3]) + ), + reducer: .default.debug(), + environment: () + ) + } +} + +extension IdentifiedArrayOf where Element == Transaction { + static var placeholder: IdentifiedArrayOf { + return .init( + uniqueElements: (0..<10).map { + Transaction( + id: $0, + amount: 25, + memo: "defaultMemo", + toAddress: "ToAddress", + fromAddress: "FromAddress" + ) + } + ) + } +} diff --git a/secant/Features/TransactionHistory/Views/TransactionDetailView.swift b/secant/Features/TransactionHistory/Views/TransactionDetailView.swift index ec87b4c..bfdaf2c 100644 --- a/secant/Features/TransactionHistory/Views/TransactionDetailView.swift +++ b/secant/Features/TransactionHistory/Views/TransactionDetailView.swift @@ -8,25 +8,10 @@ struct TransactionDetailView: View { .navigationTitle("Transaction: \(transaction.id)") } } - -extension Transaction { - static var demo: Self { - .init( - id: 2, - amount: 123, - memo: "defaultMemo", - toAddress: "ToAddress", - fromAddress: "FromAddress" - ) - } -} - -#if DEBUG struct TransactionDetail_Previews: PreviewProvider { static var previews: some View { NavigationView { - TransactionDetailView(transaction: .demo) + TransactionDetailView(transaction: .placeholder) } } } -#endif diff --git a/secant/Features/TransactionHistory/Views/TransactionHistoryView.swift b/secant/Features/TransactionHistory/Views/TransactionHistoryView.swift index d7a02ef..aa26f34 100644 --- a/secant/Features/TransactionHistory/Views/TransactionHistoryView.swift +++ b/secant/Features/TransactionHistory/Views/TransactionHistoryView.swift @@ -22,57 +22,10 @@ struct TransactionHistoryView: View { } } -extension TransactionHistoryStore { - static var demo: Store { - return Store( - initialState: TransactionHistoryState( - transactions: .demo, - route: nil - ), - reducer: .default, - environment: () - ) - } - - static var demoWithSelectedTransaction: Store { - let transactions = IdentifiedArrayOf.demo - return Store( - initialState: TransactionHistoryState( - transactions: transactions, - route: .showTransaction(transactions[3]) - ), - reducer: .default.debug(), - environment: () - ) - } -} - -extension IdentifiedArrayOf where Element == Transaction { - static var demo: IdentifiedArrayOf { - return .init( - uniqueElements: (0..<10).map { - Transaction( - id: $0, - amount: 25, - memo: "defaultMemo", - toAddress: "ToAddress", - fromAddress: "FromAddress" - ) - } - ) - } -} - struct TransactionView_Previews: PreviewProvider { static var previews: some View { NavigationView { - TransactionHistoryView(store: .demo) - .navigationBarTitleDisplayMode(.inline) - } - - NavigationView { - TransactionHistoryView(store: .demoWithSelectedTransaction) - .navigationBarTitleDisplayMode(.inline) + TransactionHistoryView(store: .placeholder) } } } diff --git a/secant/Features/WalletInfo/Views/WalletInfoView.swift b/secant/Features/WalletInfo/Views/WalletInfoView.swift new file mode 100644 index 0000000..b2d2335 --- /dev/null +++ b/secant/Features/WalletInfo/Views/WalletInfoView.swift @@ -0,0 +1,13 @@ +import SwiftUI + +struct WalletInfoView: View { + var body: some View { + Text("\(String(describing: Self.self)) PlaceHolder") + } +} + +struct WalletInfoView_Previews: PreviewProvider { + static var previews: some View { + WalletInfoView() + } +} diff --git a/secant/Features/WalletInfo/WalletInfo.swift b/secant/Features/WalletInfo/WalletInfo.swift new file mode 100644 index 0000000..9a9a413 --- /dev/null +++ b/secant/Features/WalletInfo/WalletInfo.swift @@ -0,0 +1,38 @@ +import ComposableArchitecture + +struct WalletInfoState: Equatable { +} + +enum WalletInfoAction: Equatable { + case noOp +} + +struct WalletInfoEnvironment: Equatable { +} + +// MARK: - WalletInfoReducer + +typealias WalletInfoReducer = Reducer + +extension WalletInfoReducer { + static let `default` = WalletInfoReducer { _, action, _ in + switch action { + default: + return .none + } + } +} + +// MARK: - WalletInfoStore + +typealias WalletInfoStore = Store + +extension WalletInfoStore { +} + +// MARK: - WalletInfoViewStore + +typealias WalletInfoViewStore = ViewStore + +extension WalletInfoViewStore { +} diff --git a/secant/Routers/AppRouter.swift b/secant/Routers/AppRouter.swift deleted file mode 100644 index 4bddba4..0000000 --- a/secant/Routers/AppRouter.swift +++ /dev/null @@ -1,94 +0,0 @@ -// -// AppRouterRouter.swift -// secant -// -// Created by Francisco Gindre on 8/6/21. -// - -import Foundation -import SwiftUI - -enum AppRouterScreen { - case appLoading - case createRestoreWallet - case home - case loadingFailed - case designGuide -} - -class AppRouter: Router { - @Published var screen: AppRouterScreen = .appLoading - - var services: Services - - init(services: Services) { - self.services = services - } - - @ViewBuilder func rootView() -> some View { - // Add your content here - NavigationView { - AppRouterView(router: self) - } - .onTapGesture(count: 10) { - self.screen = .designGuide - } - } - - @ViewBuilder func createNew() -> some View { - Text("Create New") - } - - @ViewBuilder func home() -> some View { - Text("Home Screen") - } - - @ViewBuilder func loadingScreen() -> some View { - LoadingScreen( - viewModel: LoadingScreenViewModel(services: self.services), - router: self - ) - } - - @ViewBuilder func loadingFailedScreen() -> some View { - Text("loading failed") - } - - @ViewBuilder func designGuide() -> some View { - DesignGuide() - } -} - -struct AppRouterView: View { - @StateObject var router: AppRouter - - var body: some View { - viewForScreen(router.screen) - .applyScreenBackground() - } - - @ViewBuilder func viewForScreen(_ screen: AppRouterScreen) -> some View { - switch router.screen { - case .appLoading: router.loadingScreen() - case .createRestoreWallet: router.createNew() - case .home: router.home() - case .loadingFailed: router.loadingFailedScreen() - case .designGuide: router.designGuide() - } - } -} - -extension AppRouter: LoadingScreenRouter { - func proceedToWelcome() { - self.screen = .createRestoreWallet - } - - func proceedToHome() { - self.screen = .home - } - - // TODO: handle Errors - func failWithError() { - self.screen = .loadingFailed - } -} diff --git a/secant/Screens/Backup Wallet/BackupWalletScreen.swift b/secant/Screens/Backup Wallet/BackupWalletScreen.swift deleted file mode 100644 index d67ab5c..0000000 --- a/secant/Screens/Backup Wallet/BackupWalletScreen.swift +++ /dev/null @@ -1,26 +0,0 @@ -// -// BackupWalletScreen.swift -// secant -// -// Created by Francisco Gindre on 8/9/21. -// - -import SwiftUI - -protocol BackupWalletScreenRouter: AnyObject {} - -struct BackupWalletScreen: View { - @ObservedObject var viewModel: BackupWalletScreenViewModel - - @State var router: BackupWalletScreenRouter? - - var body: some View { - Text("Hello, World!") - } -} - -struct BackupWalletScreenPreviews: PreviewProvider { - static var previews: some View { - BackupWalletScreen(viewModel: BackupWalletScreenViewModel(services: MockServices())) - } -} diff --git a/secant/Screens/Backup Wallet/BackupWalletScreenViewModel.swift b/secant/Screens/Backup Wallet/BackupWalletScreenViewModel.swift deleted file mode 100644 index 85b0d61..0000000 --- a/secant/Screens/Backup Wallet/BackupWalletScreenViewModel.swift +++ /dev/null @@ -1,11 +0,0 @@ -// -// BackupWalletScreenViewModel.swift -// secant -// -// Created by Francisco Gindre on 8/9/21. -// - -import Combine -import Foundation - -class BackupWalletScreenViewModel: BaseViewModel, ObservableObject {} diff --git a/secant/Screens/Balance/BalanceScreen.swift b/secant/Screens/Balance/BalanceScreen.swift deleted file mode 100644 index 324a7e4..0000000 --- a/secant/Screens/Balance/BalanceScreen.swift +++ /dev/null @@ -1,26 +0,0 @@ -// -// BalanceScreenScreen.swift -// secant -// -// Created by Francisco Gindre on 8/12/21. -// - -import SwiftUI - -protocol BalanceScreenRouter: AnyObject {} - -struct BalanceScreen: View { - @ObservedObject var viewModel: BalanceScreenViewModel - - @State var router: BalanceScreenRouter? - - var body: some View { - Text("Hello, World!") - } -} - -struct BalanceScreenPreviews: PreviewProvider { - static var previews: some View { - BalanceScreen(viewModel: BalanceScreenViewModel(services: MockServices())) - } -} diff --git a/secant/Screens/Balance/BalanceScreenViewModel.swift b/secant/Screens/Balance/BalanceScreenViewModel.swift deleted file mode 100644 index b0666e0..0000000 --- a/secant/Screens/Balance/BalanceScreenViewModel.swift +++ /dev/null @@ -1,11 +0,0 @@ -// -// BalanceScreenScreenViewModel.swift -// secant -// -// Created by Francisco Gindre on 8/12/21. -// - -import Combine -import Foundation - -class BalanceScreenViewModel: BaseViewModel, ObservableObject {} diff --git a/secant/Screens/Error/InitFailedScreen.swift b/secant/Screens/Error/InitFailedScreen.swift deleted file mode 100644 index 7d4aa3c..0000000 --- a/secant/Screens/Error/InitFailedScreen.swift +++ /dev/null @@ -1,27 +0,0 @@ -// -// InitFailedScreen.swift -// secant-testnet -// -// Created by Francisco Gindre on 9/2/21. -// - -import SwiftUI - -protocol InitFailedScreenRouter: AnyObject { -} - -struct InitFailedScreen: View { - @State var router: InitFailedScreenRouter? - - @ObservedObject var viewModel: InitFailedScreenViewModel - - var body: some View { - Text("Hello, World!") - } -} - -struct InitFailedScreenPreviews: PreviewProvider { - static var previews: some View { - InitFailedScreen(viewModel: InitFailedScreenViewModel(services: MockServices())) - } -} diff --git a/secant/Screens/Error/InitFailedScreenViewModel.swift b/secant/Screens/Error/InitFailedScreenViewModel.swift deleted file mode 100644 index a532604..0000000 --- a/secant/Screens/Error/InitFailedScreenViewModel.swift +++ /dev/null @@ -1,11 +0,0 @@ -// -// InitFailedScreenViewModel.swift -// secant-testnet -// -// Created by Francisco Gindre on 9/2/21. -// - -import Foundation -import Combine - -class InitFailedScreenViewModel: BaseViewModel, ObservableObject {} diff --git a/secant/Screens/History/HistoryScreen.swift b/secant/Screens/History/HistoryScreen.swift deleted file mode 100644 index 0d1a76c..0000000 --- a/secant/Screens/History/HistoryScreen.swift +++ /dev/null @@ -1,26 +0,0 @@ -// -// HistoryScreen.swift -// secant -// -// Created by Francisco Gindre on 8/12/21. -// - -import SwiftUI - -protocol HistoryScreenRouter: AnyObject {} - -struct HistoryScreen: View { - @ObservedObject var viewModel: HistoryScreenViewModel - - @State var router: HistoryScreenRouter? - - var body: some View { - Text("Hello, World!") - } -} - -struct HistoryScreenPreviews: PreviewProvider { - static var previews: some View { - HistoryScreen(viewModel: HistoryScreenViewModel(services: MockServices())) - } -} diff --git a/secant/Screens/History/HistoryScreenViewModel.swift b/secant/Screens/History/HistoryScreenViewModel.swift deleted file mode 100644 index 710c5d5..0000000 --- a/secant/Screens/History/HistoryScreenViewModel.swift +++ /dev/null @@ -1,11 +0,0 @@ -// -// HistoryScreenScreenViewModel.swift -// secant -// -// Created by Francisco Gindre on 8/12/21. -// - -import Combine -import Foundation - -class HistoryScreenViewModel: BaseViewModel, ObservableObject {} diff --git a/secant/Screens/Home/HomeScreen.swift b/secant/Screens/Home/HomeScreen.swift deleted file mode 100644 index fe64fec..0000000 --- a/secant/Screens/Home/HomeScreen.swift +++ /dev/null @@ -1,109 +0,0 @@ -// -// HomeScreen.swift -// secant -// -// Created by Francisco Gindre on 8/9/21. -// - -import SwiftUI - -protocol HomeScreenRouter: AnyObject { - func homeScreenScanQrScreen() -> ScanQrScreen - func homeScreenProfileScreen() -> ProfileScreen - func homeScreenHistoryScreen() -> HistoryScreen - func homeScreenBalanceScreen() -> BalanceScreen - func homeScreenRequestScreen() -> RequestZcashScreen - func homeScreenSendScreen() -> SendScreen -} - -struct HomeScreen: View { - @ObservedObject var viewModel: HomeScreenViewModel - - @State var router: HomeScreenRouter? - - var body: some View { - VStack { - Text("Hello, World!") - sendButton - requestButton - historyButton - } - .padding(.horizontal, 30) - .navigationBarTitle("", displayMode: .inline) - .navigationBarItems( - leading: qrCodeButton, - trailing: profileButton - ) - } - - @ViewBuilder var qrCodeButton: some View { - Button(action: {}, label: { - Image(systemName: "qrcode.viewfinder") - .frame(width: 20, height: 20, alignment: .center) - }) - .contentShape(Circle()) - } - - @ViewBuilder var profileButton: some View { - Button(action: {}, label: { - Image(systemName: "person.crop.circle") - .frame(width: 20, height: 20, alignment: .center) - }) - .contentShape(Circle()) - } - - @ViewBuilder var requestButton: some View { - Button(action: {}, label: { - Text("Request ZEC") - }) - .primaryButtonStyle - .frame(height: 50) - } - - @ViewBuilder var sendButton: some View { - Button(action: {}, label: { - Text("Send ZEC") - }) - .primaryButtonStyle - .frame(height: 50) - } - - @ViewBuilder var historyButton: some View { - Button(action: {}, label: { - Text("History") - }) - .primaryButtonStyle - .frame(height: 50) - } -} - -// MARK: - Previews - -struct HomeScreenPreviews: PreviewProvider { - static var previews: some View { - NavigationView { - HomeScreen( - viewModel: HomeScreenViewModel.mockWithValues( - services: MockServices(), - status: .offline, - balance: mockBalance, - fiatConversion: 1.12453 - ) - ) - } - } - - static var mockBalance: WalletBalance { - Balance( - transaparent: ZcashFunds.noFunds, - sapling: ZcashFunds( - confirmed: 123456790, - unconfirmed: 0 - ), - orchard: ZcashFunds( - confirmed: 0, - unconfirmed: 0 - ) - ) - } -} diff --git a/secant/Screens/Home/HomeScreenViewModel.swift b/secant/Screens/Home/HomeScreenViewModel.swift deleted file mode 100644 index 28cb475..0000000 --- a/secant/Screens/Home/HomeScreenViewModel.swift +++ /dev/null @@ -1,37 +0,0 @@ -// -// HomeScreenViewModel.swift -// secant -// -// Created by Francisco Gindre on 8/9/21. -// - -import Combine -import Foundation - -class HomeScreenViewModel: BaseViewModel, ObservableObject { - enum Status { - case syncing(progress: Float) - case offline - case error(error: Error) - } - - @Published var balance: WalletBalance = Balance.nullBalance - @Published var fiatConversion: Decimal = 0 - @Published var status = Status.offline -} - -extension HomeScreenViewModel { - static func mockWithValues( - services: Services, - status: Status, - balance: WalletBalance, - fiatConversion: Decimal - ) -> HomeScreenViewModel { - let viewModel = HomeScreenViewModel(services: services) - viewModel.status = status - viewModel.balance = balance - viewModel.fiatConversion = fiatConversion - - return viewModel - } -} diff --git a/secant/Screens/Loading/LoadingScreen.swift b/secant/Screens/Loading/LoadingScreen.swift deleted file mode 100644 index 33df485..0000000 --- a/secant/Screens/Loading/LoadingScreen.swift +++ /dev/null @@ -1,67 +0,0 @@ -// -// LoadingScreen.swift -// secant-testnet -// -// Created by Francisco Gindre on 9/2/21. -// - -import SwiftUI - -protocol LoadingScreenRouter: AnyObject { - func proceedToHome() - func failWithError() - func proceedToWelcome() -} - -struct LoadingScreen: View { - @StateObject var viewModel: LoadingScreenViewModel - - @State var router: LoadingScreenRouter? - - var body: some View { - Text("Loading") - .onReceive( - viewModel.$loadingResult, - perform: { result in - guard - let loadingResult = result, - let router = self.router - else { return } - - viewModel.callRouter(router, with: loadingResult) - } - ) - .onAppear { - DispatchQueue.main.asyncAfter(deadline: .now() + 4) { - viewModel.loadAsync() - } - } - } -} - -// MARK: Routing - -extension LoadingScreenViewModel { - func callRouter( - _ router: LoadingScreenRouter, - with loadingResult: Result - ) { - switch loadingResult { - case .success(let result): - switch result { - case .credentialsFound: - router.proceedToHome() - case .newWallet: - router.proceedToWelcome() - } - case .failure: - router.failWithError() - } - } -} - -struct LoadingScreenPreviews: PreviewProvider { - static var previews: some View { - LoadingScreen(viewModel: LoadingScreenViewModel(services: MockServices())) - } -} diff --git a/secant/Screens/Loading/LoadingScreenViewModel.swift b/secant/Screens/Loading/LoadingScreenViewModel.swift deleted file mode 100644 index e560753..0000000 --- a/secant/Screens/Loading/LoadingScreenViewModel.swift +++ /dev/null @@ -1,37 +0,0 @@ -// -// LoadingScreenViewModel.swift -// secant-testnet -// -// Created by Francisco Gindre on 9/2/21. -// - -import Foundation -import Combine - -class LoadingScreenViewModel: BaseViewModel, ObservableObject { - enum LoadingResult { - case newWallet - case credentialsFound - } - - @Published var loadingResult: Result? - - func loadAsync () { - // TODO: Make a special queue for the app - DispatchQueue.global(qos: .userInitiated) - .async { [weak self] in - guard let result = self?.load() else { return } - DispatchQueue.main.async { - self?.loadingResult = result - } - } - } - - internal func load() -> Result { - do { - return (try services.keyStorage.areKeysPresent()) ? .success(.credentialsFound) : .success(.newWallet) - } catch { - return .failure(error) - } - } -} diff --git a/secant/Screens/Profile/ProfileScreen.swift b/secant/Screens/Profile/ProfileScreen.swift deleted file mode 100644 index 5c47256..0000000 --- a/secant/Screens/Profile/ProfileScreen.swift +++ /dev/null @@ -1,26 +0,0 @@ -// -// ProfileScreenScreen.swift -// secant -// -// Created by Francisco Gindre on 8/12/21. -// - -import SwiftUI - -protocol ProfileScreenRouter: AnyObject {} - -struct ProfileScreen: View { - @ObservedObject var viewModel: ProfileScreenViewModel - - @State var router: ProfileScreenRouter? - - var body: some View { - Text("Hello, World!") - } -} - -struct ProfileScreenPreviews: PreviewProvider { - static var previews: some View { - ProfileScreen(viewModel: ProfileScreenViewModel(services: MockServices())) - } -} diff --git a/secant/Screens/Profile/ProfileScreenViewModel.swift b/secant/Screens/Profile/ProfileScreenViewModel.swift deleted file mode 100644 index bbad7c9..0000000 --- a/secant/Screens/Profile/ProfileScreenViewModel.swift +++ /dev/null @@ -1,11 +0,0 @@ -// -// ProfileScreenScreenViewModel.swift -// secant -// -// Created by Francisco Gindre on 8/12/21. -// - -import Combine -import Foundation - -class ProfileScreenViewModel: BaseViewModel, ObservableObject {} diff --git a/secant/Screens/Request ZEC/RequestZcashScreen.swift b/secant/Screens/Request ZEC/RequestZcashScreen.swift deleted file mode 100644 index 6936b82..0000000 --- a/secant/Screens/Request ZEC/RequestZcashScreen.swift +++ /dev/null @@ -1,26 +0,0 @@ -// -// RequestZcashScreen.swift -// secant -// -// Created by Francisco Gindre on 8/12/21. -// - -import SwiftUI - -protocol RequestZcashScreenRouter: AnyObject {} - -struct RequestZcashScreen: View { - @ObservedObject var viewModel: RequestZcashScreenViewModel - - @State var router: RequestZcashScreenRouter? - - var body: some View { - Text("Hello, World!") - } -} - -struct RequestZcashScreenPreviews: PreviewProvider { - static var previews: some View { - RequestZcashScreen(viewModel: RequestZcashScreenViewModel(services: MockServices())) - } -} diff --git a/secant/Screens/Request ZEC/RequestZcashScreenViewModel.swift b/secant/Screens/Request ZEC/RequestZcashScreenViewModel.swift deleted file mode 100644 index de1f33f..0000000 --- a/secant/Screens/Request ZEC/RequestZcashScreenViewModel.swift +++ /dev/null @@ -1,11 +0,0 @@ -// -// RequestZcashScreenScreenViewModel.swift -// secant -// -// Created by Francisco Gindre on 8/12/21. -// - -import Combine -import Foundation - -class RequestZcashScreenViewModel: BaseViewModel, ObservableObject {} diff --git a/secant/Screens/Restore Wallet/RestoreWalletScreen.swift b/secant/Screens/Restore Wallet/RestoreWalletScreen.swift deleted file mode 100644 index 722757d..0000000 --- a/secant/Screens/Restore Wallet/RestoreWalletScreen.swift +++ /dev/null @@ -1,39 +0,0 @@ -// -// RestoreWalletScreen.swift -// secant -// -// Created by Francisco Gindre on 8/9/21. -// - -import SwiftUI - -protocol RestoreWalletScreenRouter: AnyObject {} - -struct RestoreWalletScreen: View { - @ObservedObject var viewModel: RestoreWalletScreenViewModel - - @State var router: RestoreWalletScreenRouter? - - var body: some View { - VStack { - Text("Enter Seed Phrase") - - TextEditor(text: $viewModel.seedText) - - Button(action: {}, label: { - Text("Restore Seed Phrase") - }) - .primaryButtonStyle - .frame(height: 50) - } - .padding(.horizontal, 30) - .padding(.vertical) - .navigationBarTitle(Text("Restore Wallet"), displayMode: .inline) - } -} - -struct RestoreWalletScreenPreviews: PreviewProvider { - static var previews: some View { - RestoreWalletScreen(viewModel: RestoreWalletScreenViewModel(services: MockServices())) - } -} diff --git a/secant/Screens/Restore Wallet/RestoreWalletScreenViewModel.swift b/secant/Screens/Restore Wallet/RestoreWalletScreenViewModel.swift deleted file mode 100644 index c775926..0000000 --- a/secant/Screens/Restore Wallet/RestoreWalletScreenViewModel.swift +++ /dev/null @@ -1,15 +0,0 @@ -// -// RestoreWalletScreenViewModel.swift -// secant -// -// Created by Francisco Gindre on 8/9/21. -// - -import Combine -import Foundation - -class RestoreWalletScreenViewModel: BaseViewModel, ObservableObject { - @Published var seedText: String = "" - - func restore() {} -} diff --git a/secant/Screens/Scan/ScanQrScreen.swift b/secant/Screens/Scan/ScanQrScreen.swift deleted file mode 100644 index efbc638..0000000 --- a/secant/Screens/Scan/ScanQrScreen.swift +++ /dev/null @@ -1,26 +0,0 @@ -// -// ScanQrScreenScreen.swift -// secant -// -// Created by Francisco Gindre on 8/12/21. -// - -import SwiftUI - -protocol ScanQrScreenRouter: AnyObject {} - -struct ScanQrScreen: View { - @ObservedObject var viewModel: ScanQrScreenViewModel - - @State var router: ScanQrScreenRouter? - - var body: some View { - Text("Hello, World!") - } -} - -struct ScanQrScreenScreenPreviews: PreviewProvider { - static var previews: some View { - ScanQrScreen(viewModel: ScanQrScreenViewModel(services: MockServices())) - } -} diff --git a/secant/Screens/Scan/ScanQrScreenViewModel.swift b/secant/Screens/Scan/ScanQrScreenViewModel.swift deleted file mode 100644 index 71df046..0000000 --- a/secant/Screens/Scan/ScanQrScreenViewModel.swift +++ /dev/null @@ -1,11 +0,0 @@ -// -// ScanQrScreenViewModel.swift -// secant -// -// Created by Francisco Gindre on 8/12/21. -// - -import Combine -import Foundation - -class ScanQrScreenViewModel: BaseViewModel, ObservableObject {} diff --git a/secant/Screens/Send ZEC/SendScreen.swift b/secant/Screens/Send ZEC/SendScreen.swift deleted file mode 100644 index a8f2b11..0000000 --- a/secant/Screens/Send ZEC/SendScreen.swift +++ /dev/null @@ -1,26 +0,0 @@ -// -// SendScreenScreen.swift -// secant -// -// Created by Francisco Gindre on 8/12/21. -// - -import SwiftUI - -protocol SendScreenRouter: AnyObject {} - -struct SendScreen: View { - @ObservedObject var viewModel: SendScreenViewModel - - @State var router: SendScreenRouter? - - var body: some View { - Text("Hello, World!") - } -} - -struct SendScreenScreenPreviews: PreviewProvider { - static var previews: some View { - SendScreen(viewModel: SendScreenViewModel(services: MockServices())) - } -} diff --git a/secant/Screens/Send ZEC/SendScreenViewModel.swift b/secant/Screens/Send ZEC/SendScreenViewModel.swift deleted file mode 100644 index 8ece18e..0000000 --- a/secant/Screens/Send ZEC/SendScreenViewModel.swift +++ /dev/null @@ -1,11 +0,0 @@ -// -// SendScreenScreenViewModel.swift -// secant -// -// Created by Francisco Gindre on 8/12/21. -// - -import Combine -import Foundation - -class SendScreenViewModel: BaseViewModel, ObservableObject {} diff --git a/secant/Screens/Welcome Screen/WelcomeScreen.swift b/secant/Screens/Welcome Screen/WelcomeScreen.swift deleted file mode 100644 index b4ab3b7..0000000 --- a/secant/Screens/Welcome Screen/WelcomeScreen.swift +++ /dev/null @@ -1,51 +0,0 @@ -// -// CreateNewWalletScreen.swift -// secant -// -// Created by Francisco Gindre on 8/9/21. -// - -import SwiftUI - -protocol WelcomeScreenRouter: AnyObject {} - -struct WelcomeScreen: View { - @ObservedObject var viewModel: WelcomeScreenViewModel - - @State var router: WelcomeScreenRouter? - - var body: some View { - VStack { - Spacer() - - Text("Welcome and Onboarding") - - Spacer() - - VStack(alignment: .center, spacing: 16) { - Button(action: { - self.viewModel.restoreWallet() - }, label: { - Text("RESTORE WALLET") - }) - .primaryButtonStyle - .frame(height: 50) - - Button(action: { - self.viewModel.createNew() - }, label: { - Text("CREATE NEW WALLET") - }) - .primaryButtonStyle - .frame(height: 50) - } - } - .padding() - } -} - -struct CreateNewWalletScreenPreviews: PreviewProvider { - static var previews: some View { - WelcomeScreen(viewModel: WelcomeScreenViewModel(services: MockServices())) - } -} diff --git a/secant/Screens/Welcome Screen/WelcomeScreenViewModel.swift b/secant/Screens/Welcome Screen/WelcomeScreenViewModel.swift deleted file mode 100644 index bf1d028..0000000 --- a/secant/Screens/Welcome Screen/WelcomeScreenViewModel.swift +++ /dev/null @@ -1,14 +0,0 @@ -// -// CreateNewWalletScreenViewModel.swift -// secant -// -// Created by Francisco Gindre on 8/9/21. -// - -import Combine -import Foundation - -class WelcomeScreenViewModel: BaseViewModel, ObservableObject { - func createNew() {} - func restoreWallet() {} -} diff --git a/secant/SecantApp.swift b/secant/SecantApp.swift index a4ac974..0313c28 100644 --- a/secant/SecantApp.swift +++ b/secant/SecantApp.swift @@ -9,13 +9,21 @@ import SwiftUI @main struct SecantApp: App { - var homeStore: HomeStore = .demo + var appStore: AppStore = .placeholder + var body: some Scene { WindowGroup { - NavigationView { - HomeView(store: homeStore) - } - .navigationViewStyle(StackNavigationViewStyle()) + AppView(store: appStore) } } } + +extension AppStore { + static var placeholder: AppStore { + AppStore( + initialState: .placeholder, + reducer: .default, + environment: .init() + ) + } +} diff --git a/secantTests/LoadingScreenTests.swift b/secantTests/LoadingScreenTests.swift deleted file mode 100644 index 388c2b7..0000000 --- a/secantTests/LoadingScreenTests.swift +++ /dev/null @@ -1,239 +0,0 @@ -// -// AppRouterNavigationTests.swift -// secantTests -// -// Created by Francisco Gindre on 9/2/21. -// - -import XCTest -@testable import secant_testnet -import Foundation -import Combine -class LoadingScreenTests: XCTestCase { - var cancellables: [AnyCancellable] = [] - - // MARK: LoadingScreenViewModel Tests - - func testCredentialsFoundIsPublishedWhenCredentialsArePresent() throws { - let mockServices = MockServices() - let stub = KeysPresentStub(returnBlock: { - true - }) - mockServices.keyStorage = stub - let loadingViewModel = LoadingScreenViewModel(services: mockServices) - // swiftlint:disable:next line_length - let testExpectation = XCTestExpectation(description: "LoadingViewModel Publishes .credentialsFound when credentials are present and there's no failure") - let expected = LoadingScreenViewModel.LoadingResult.credentialsFound - - loadingViewModel.$loadingResult - .dropFirst() - .sink { loadingResult in - testExpectation.fulfill() - - XCTAssertTrue(stub.called) - switch loadingResult { - case .success(let result): - XCTAssertEqual(result, expected) - case .failure(let error): - XCTFail("found error \(error.localizedDescription)") - case .none: - XCTFail("found None when expected a value") - } - } - .store(in: &cancellables) - loadingViewModel.loadAsync() - wait(for: [testExpectation], timeout: 0.1) - } - - func testNewWalletLoadingResultPublishedWhenNoCredentialsFound() throws { - let mockServices = MockServices() - let stub = KeysPresentStub(returnBlock: { - false - }) - mockServices.keyStorage = stub - let loadingViewModel = LoadingScreenViewModel(services: mockServices) - let testExpectation = XCTestExpectation( - description: "LoadingViewModel Publishes .newWallet when no credentials are present and there's no failure" - ) - let expected = LoadingScreenViewModel.LoadingResult.newWallet - - loadingViewModel.$loadingResult - .dropFirst() - .sink { loadingResult in - testExpectation.fulfill() - - XCTAssertTrue(stub.called) - switch loadingResult { - case .success(let result): - XCTAssertEqual(result, expected) - case .failure(let error): - XCTFail("found error \(error.localizedDescription)") - case .none: - XCTFail("found None when expected a value") - } - } - .store(in: &cancellables) - loadingViewModel.loadAsync() - wait(for: [testExpectation], timeout: 0.1) - } - - func testFailureIsPublishedWhenWalletFailsToInitialize() throws { - let mockServices = MockServices() - let stub = KeysPresentStub(returnBlock: { - throw KeyStoringError.alreadyImported - }) - mockServices.keyStorage = stub - let loadingViewModel = LoadingScreenViewModel(services: mockServices) - let testExpectation = XCTestExpectation(description: "LoadingViewModel Publishes .failure when there's a failure") - - loadingViewModel.$loadingResult - .dropFirst() - .sink { loadingResult in - testExpectation.fulfill() - - XCTAssertTrue(stub.called) - switch loadingResult { - case .success(let result): - XCTFail("found result: \(result) but expected a failure") - case .failure: - XCTAssertTrue(true) // fails when expected - case .none: - XCTFail("found None when expected a failure") - } - } - .store(in: &cancellables) - loadingViewModel.loadAsync() - wait(for: [testExpectation], timeout: 0.1) - } - - func testNewWalletLoadingResultReturnedWhenCredentialsAreNotPresent() throws { - let mockServices = MockServices() - let stub = KeysPresentStub(returnBlock: { - false - }) - mockServices.keyStorage = stub - let loadingViewModel = LoadingScreenViewModel(services: mockServices) - - let expected = LoadingScreenViewModel.LoadingResult.newWallet - let result = loadingViewModel.load() - - XCTAssertTrue(stub.called) - switch result { - case .failure(let error): - XCTFail("found error \(error.localizedDescription)") - case .success(let res): - XCTAssertEqual(expected, res) - } - } - - func testCredentialsFoundReturnedWhenCredentialsArePresent() throws { - let mockServices = MockServices() - let stub = KeysPresentStub(returnBlock: { - true - }) - mockServices.keyStorage = stub - let loadingViewModel = LoadingScreenViewModel(services: mockServices) - - let expected = LoadingScreenViewModel.LoadingResult.credentialsFound - let result = loadingViewModel.load() - - XCTAssertTrue(stub.called) - switch result { - case .failure(let error): - XCTFail("found error \(error.localizedDescription)") - case .success(let res): - XCTAssertEqual(expected, res) - } - } - - func testLoadReturnsErrorWhenLoadingFails() throws { - let mockServices = MockServices() - let stub = KeysPresentStub(returnBlock: { - throw KeyStoringError.uninitializedWallet - }) - mockServices.keyStorage = stub - let loadingViewModel = LoadingScreenViewModel(services: mockServices) - - let result = loadingViewModel.load() - XCTAssertTrue(stub.called) - switch result { - case .failure: - XCTAssertTrue(true) - case .success(let res): - XCTFail("case succeeded when testing failure - result: \(res)") - } - } - - // MARK: LoadingScreen View Tests - - func testProceedToHomeIsCalledWhenCredentialsAreFound() throws { - let loadingViewModel = LoadingScreenViewModelHelper.loadingViewModelWith { - true - } - - let spyRouter = LoadingScreenRouterSpy(fulfillment: { - }) - - loadingViewModel.callRouter(spyRouter, with: loadingViewModel.load()) - XCTAssertTrue(spyRouter.proceedToHomeCalled) - } - - func testProceedToWelcomeIsCalledWhenCredentialsAreNotFound() throws { - let loadingViewModel = LoadingScreenViewModelHelper.loadingViewModelWith { - false - } - - let spyRouter = LoadingScreenRouterSpy(fulfillment: { - }) - - loadingViewModel.callRouter(spyRouter, with: loadingViewModel.load()) - XCTAssertTrue(spyRouter.proceedToWelcomeCalled) - } - - func testFailWithErrorIsCalledWhenKeyStoringFails() throws { - let loadingViewModel = LoadingScreenViewModelHelper.loadingViewModelWith { - throw KeyStoringError.alreadyImported - } - - let spyRouter = LoadingScreenRouterSpy(fulfillment: { - }) - - loadingViewModel.callRouter(spyRouter, with: loadingViewModel.load()) - XCTAssertTrue(spyRouter.failWithErrorCalled) - } -} - -class LoadingScreenRouterSpy: LoadingScreenRouter { - var fulfillmentBlock: () -> Void - var proceedToHomeCalled = false - var failWithErrorCalled = false - var proceedToWelcomeCalled = false - - init(fulfillment: @escaping () -> Void) { - self.fulfillmentBlock = fulfillment - } - - func proceedToHome() { - proceedToHomeCalled = true - fulfillmentBlock() - } - - func failWithError() { - failWithErrorCalled = true - fulfillmentBlock() - } - - func proceedToWelcome() { - proceedToWelcomeCalled = true - fulfillmentBlock() - } -} - -enum LoadingScreenViewModelHelper { - static func loadingViewModelWith(keysPresentStubBlock: @escaping () throws -> Bool) -> LoadingScreenViewModel { - let mockServices = MockServices() - let stub = KeysPresentStub(returnBlock: keysPresentStubBlock) - mockServices.keyStorage = stub - return LoadingScreenViewModel(services: mockServices) - } -}