Issue #145 - Single Line Text Field
* Single Line Text Field * add TODO comment to secant/Util/Strings.swift Issue #245 comments the changes needed Co-authored-by: Francisco Gindre <francisco.gindre@gmail.com>
|
@ -57,10 +57,20 @@
|
||||||
0DFE93E1272C9ECB000FCCA5 /* RecoveryPhraseBackupValidationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DFE93E0272C9ECB000FCCA5 /* RecoveryPhraseBackupValidationView.swift */; };
|
0DFE93E1272C9ECB000FCCA5 /* RecoveryPhraseBackupValidationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DFE93E0272C9ECB000FCCA5 /* RecoveryPhraseBackupValidationView.swift */; };
|
||||||
0DFE93E3272CA1AA000FCCA5 /* RecoveryPhraseValidation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DFE93E2272CA1AA000FCCA5 /* RecoveryPhraseValidation.swift */; };
|
0DFE93E3272CA1AA000FCCA5 /* RecoveryPhraseValidation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DFE93E2272CA1AA000FCCA5 /* RecoveryPhraseValidation.swift */; };
|
||||||
0DFE93E6272CB6F7000FCCA5 /* RecoveryPhraseValidationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DFE93E5272CB6F7000FCCA5 /* RecoveryPhraseValidationTests.swift */; };
|
0DFE93E6272CB6F7000FCCA5 /* RecoveryPhraseValidationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DFE93E5272CB6F7000FCCA5 /* RecoveryPhraseValidationTests.swift */; };
|
||||||
|
2E35F99227B28E7600EB79CD /* SingleLineTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E35F99127B28E7600EB79CD /* SingleLineTextField.swift */; };
|
||||||
|
2E35F99A27B3E99C00EB79CD /* TextFieldTitleAccessoryButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E35F99927B3E99C00EB79CD /* TextFieldTitleAccessoryButtonStyle.swift */; };
|
||||||
2E58E73B274679F000B2B84B /* OnboardingHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E58E73A274679F000B2B84B /* OnboardingHeaderView.swift */; };
|
2E58E73B274679F000B2B84B /* OnboardingHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E58E73A274679F000B2B84B /* OnboardingHeaderView.swift */; };
|
||||||
|
2E6CF8DD27D78319004DCD7A /* CurrencySelectionStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E6CF8DC27D78319004DCD7A /* CurrencySelectionStore.swift */; };
|
||||||
|
2E8719CB27FB09990082C926 /* TransactionTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E8719CA27FB09990082C926 /* TransactionTextField.swift */; };
|
||||||
|
2E8719CD27FB0D3B0082C926 /* TransactionCurrencySelector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E8719CC27FB0D3B0082C926 /* TransactionCurrencySelector.swift */; };
|
||||||
2EA11F5B27467EF800709571 /* OnboardingFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EA11F5A27467EF800709571 /* OnboardingFooterView.swift */; };
|
2EA11F5B27467EF800709571 /* OnboardingFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EA11F5A27467EF800709571 /* OnboardingFooterView.swift */; };
|
||||||
2EA11F5D27467F7700709571 /* OnboardingContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EA11F5C27467F7700709571 /* OnboardingContentView.swift */; };
|
2EA11F5D27467F7700709571 /* OnboardingContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EA11F5C27467F7700709571 /* OnboardingContentView.swift */; };
|
||||||
|
2EB1C5E827D77F6100BC43D7 /* TextFieldStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EB1C5E727D77F6100BC43D7 /* TextFieldStore.swift */; };
|
||||||
2EB660E02747EAB900A06A07 /* OnboardingScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E5C03802738C570008BFFD3 /* OnboardingScreen.swift */; };
|
2EB660E02747EAB900A06A07 /* OnboardingScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E5C03802738C570008BFFD3 /* OnboardingScreen.swift */; };
|
||||||
|
2EB7758727FC67FD00269373 /* TransactionInputStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EB7758627FC67FD00269373 /* TransactionInputStore.swift */; };
|
||||||
|
2EDA07A027EDE18C00D6F09B /* TextFieldInput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EDA079F27EDE18C00D6F09B /* TextFieldInput.swift */; };
|
||||||
|
2EDA07A227EDE1AE00D6F09B /* TextFieldFooter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EDA07A127EDE1AE00D6F09B /* TextFieldFooter.swift */; };
|
||||||
|
2EDA07A427EDE2A900D6F09B /* DebugFrame.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EDA07A327EDE2A900D6F09B /* DebugFrame.swift */; };
|
||||||
660558E9270C7A54009D6954 /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 660558E8270C7A54009D6954 /* Colors.xcassets */; };
|
660558E9270C7A54009D6954 /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 660558E8270C7A54009D6954 /* Colors.xcassets */; };
|
||||||
660558F7270C862F009D6954 /* Fonts+Generated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 660558F5270C862F009D6954 /* Fonts+Generated.swift */; };
|
660558F7270C862F009D6954 /* Fonts+Generated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 660558F5270C862F009D6954 /* Fonts+Generated.swift */; };
|
||||||
660558F8270C862F009D6954 /* XCAssets+Generated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 660558F6270C862F009D6954 /* XCAssets+Generated.swift */; };
|
660558F8270C862F009D6954 /* XCAssets+Generated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 660558F6270C862F009D6954 /* XCAssets+Generated.swift */; };
|
||||||
|
@ -92,9 +102,9 @@
|
||||||
9EF8135C27ECC25E0075AF48 /* WalletStorageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EF8135A27ECC25E0075AF48 /* WalletStorageTests.swift */; };
|
9EF8135C27ECC25E0075AF48 /* WalletStorageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EF8135A27ECC25E0075AF48 /* WalletStorageTests.swift */; };
|
||||||
9EF8135D27ECC25E0075AF48 /* UserPreferencesStorageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EF8135B27ECC25E0075AF48 /* UserPreferencesStorageTests.swift */; };
|
9EF8135D27ECC25E0075AF48 /* UserPreferencesStorageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EF8135B27ECC25E0075AF48 /* UserPreferencesStorageTests.swift */; };
|
||||||
9EF8136027F043CC0075AF48 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EF8135F27F043CC0075AF48 /* AppDelegate.swift */; };
|
9EF8136027F043CC0075AF48 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EF8135F27F043CC0075AF48 /* AppDelegate.swift */; };
|
||||||
9EF8139C27F47AED0075AF48 /* InitializationState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EF8139B27F47AED0075AF48 /* InitializationState.swift */; };
|
|
||||||
9EF8139127F191BF0075AF48 /* WalletStorageInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EF8139027F191BF0075AF48 /* WalletStorageInteractor.swift */; };
|
9EF8139127F191BF0075AF48 /* WalletStorageInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EF8139027F191BF0075AF48 /* WalletStorageInteractor.swift */; };
|
||||||
9EF8139827F1FAEC0075AF48 /* ZcashLightClientKit in Frameworks */ = {isa = PBXBuildFile; productRef = 9EF8139727F1FAEC0075AF48 /* ZcashLightClientKit */; };
|
9EF8139827F1FAEC0075AF48 /* ZcashLightClientKit in Frameworks */ = {isa = PBXBuildFile; productRef = 9EF8139727F1FAEC0075AF48 /* ZcashLightClientKit */; };
|
||||||
|
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 */; };
|
F93874F0273C4DE200F0E875 /* HomeStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F93874ED273C4DE200F0E875 /* HomeStore.swift */; };
|
||||||
|
@ -198,10 +208,20 @@
|
||||||
0DFE93E0272C9ECB000FCCA5 /* RecoveryPhraseBackupValidationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecoveryPhraseBackupValidationView.swift; sourceTree = "<group>"; };
|
0DFE93E0272C9ECB000FCCA5 /* RecoveryPhraseBackupValidationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecoveryPhraseBackupValidationView.swift; sourceTree = "<group>"; };
|
||||||
0DFE93E2272CA1AA000FCCA5 /* RecoveryPhraseValidation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecoveryPhraseValidation.swift; sourceTree = "<group>"; };
|
0DFE93E2272CA1AA000FCCA5 /* RecoveryPhraseValidation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecoveryPhraseValidation.swift; sourceTree = "<group>"; };
|
||||||
0DFE93E5272CB6F7000FCCA5 /* RecoveryPhraseValidationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecoveryPhraseValidationTests.swift; sourceTree = "<group>"; };
|
0DFE93E5272CB6F7000FCCA5 /* RecoveryPhraseValidationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecoveryPhraseValidationTests.swift; sourceTree = "<group>"; };
|
||||||
|
2E35F99127B28E7600EB79CD /* SingleLineTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleLineTextField.swift; sourceTree = "<group>"; };
|
||||||
|
2E35F99927B3E99C00EB79CD /* TextFieldTitleAccessoryButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFieldTitleAccessoryButtonStyle.swift; sourceTree = "<group>"; };
|
||||||
2E58E73A274679F000B2B84B /* OnboardingHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingHeaderView.swift; sourceTree = "<group>"; };
|
2E58E73A274679F000B2B84B /* OnboardingHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingHeaderView.swift; sourceTree = "<group>"; };
|
||||||
2E5C03802738C570008BFFD3 /* OnboardingScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingScreen.swift; sourceTree = "<group>"; };
|
2E5C03802738C570008BFFD3 /* OnboardingScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingScreen.swift; sourceTree = "<group>"; };
|
||||||
|
2E6CF8DC27D78319004DCD7A /* CurrencySelectionStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrencySelectionStore.swift; sourceTree = "<group>"; };
|
||||||
|
2E8719CA27FB09990082C926 /* TransactionTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionTextField.swift; sourceTree = "<group>"; };
|
||||||
|
2E8719CC27FB0D3B0082C926 /* TransactionCurrencySelector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionCurrencySelector.swift; sourceTree = "<group>"; };
|
||||||
2EA11F5A27467EF800709571 /* OnboardingFooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingFooterView.swift; sourceTree = "<group>"; };
|
2EA11F5A27467EF800709571 /* OnboardingFooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingFooterView.swift; sourceTree = "<group>"; };
|
||||||
2EA11F5C27467F7700709571 /* OnboardingContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingContentView.swift; sourceTree = "<group>"; };
|
2EA11F5C27467F7700709571 /* OnboardingContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingContentView.swift; sourceTree = "<group>"; };
|
||||||
|
2EB1C5E727D77F6100BC43D7 /* TextFieldStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFieldStore.swift; sourceTree = "<group>"; };
|
||||||
|
2EB7758627FC67FD00269373 /* TransactionInputStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionInputStore.swift; sourceTree = "<group>"; };
|
||||||
|
2EDA079F27EDE18C00D6F09B /* TextFieldInput.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFieldInput.swift; sourceTree = "<group>"; };
|
||||||
|
2EDA07A127EDE1AE00D6F09B /* TextFieldFooter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFieldFooter.swift; sourceTree = "<group>"; };
|
||||||
|
2EDA07A327EDE2A900D6F09B /* DebugFrame.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugFrame.swift; sourceTree = "<group>"; };
|
||||||
660558E8270C7A54009D6954 /* Colors.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Colors.xcassets; sourceTree = "<group>"; };
|
660558E8270C7A54009D6954 /* Colors.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Colors.xcassets; sourceTree = "<group>"; };
|
||||||
660558F5270C862F009D6954 /* Fonts+Generated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Fonts+Generated.swift"; sourceTree = "<group>"; };
|
660558F5270C862F009D6954 /* Fonts+Generated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Fonts+Generated.swift"; sourceTree = "<group>"; };
|
||||||
660558F6270C862F009D6954 /* XCAssets+Generated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "XCAssets+Generated.swift"; sourceTree = "<group>"; };
|
660558F6270C862F009D6954 /* XCAssets+Generated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "XCAssets+Generated.swift"; sourceTree = "<group>"; };
|
||||||
|
@ -232,8 +252,8 @@
|
||||||
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>"; };
|
||||||
9EF8135B27ECC25E0075AF48 /* UserPreferencesStorageTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserPreferencesStorageTests.swift; sourceTree = "<group>"; };
|
9EF8135B27ECC25E0075AF48 /* UserPreferencesStorageTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserPreferencesStorageTests.swift; sourceTree = "<group>"; };
|
||||||
9EF8135F27F043CC0075AF48 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
9EF8135F27F043CC0075AF48 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||||
9EF8139B27F47AED0075AF48 /* InitializationState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InitializationState.swift; sourceTree = "<group>"; };
|
|
||||||
9EF8139027F191BF0075AF48 /* WalletStorageInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletStorageInteractor.swift; sourceTree = "<group>"; };
|
9EF8139027F191BF0075AF48 /* WalletStorageInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletStorageInteractor.swift; sourceTree = "<group>"; };
|
||||||
|
9EF8139B27F47AED0075AF48 /* InitializationState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InitializationState.swift; sourceTree = "<group>"; };
|
||||||
F9322DBF273B555C00C105B5 /* NavigationLinks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationLinks.swift; sourceTree = "<group>"; };
|
F9322DBF273B555C00C105B5 /* NavigationLinks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationLinks.swift; sourceTree = "<group>"; };
|
||||||
F93673D52742CB840099C6AF /* Previews.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Previews.swift; sourceTree = "<group>"; };
|
F93673D52742CB840099C6AF /* Previews.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Previews.swift; sourceTree = "<group>"; };
|
||||||
F93874ED273C4DE200F0E875 /* HomeStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeStore.swift; sourceTree = "<group>"; };
|
F93874ED273C4DE200F0E875 /* HomeStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeStore.swift; sourceTree = "<group>"; };
|
||||||
|
@ -391,6 +411,8 @@
|
||||||
0D4E7A0726B364170058B01E /* secant */ = {
|
0D4E7A0726B364170058B01E /* secant */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
0D4E7A0826B364170058B01E /* SecantApp.swift */,
|
||||||
|
0D4E7A0A26B364170058B01E /* ContentView.swift */,
|
||||||
0DACFA7D27208CC80039EEA5 /* Util */,
|
0DACFA7D27208CC80039EEA5 /* Util */,
|
||||||
6654C73B2715A3F000901167 /* Features */,
|
6654C73B2715A3F000901167 /* Features */,
|
||||||
660558F4270C85F7009D6954 /* Generated */,
|
660558F4270C85F7009D6954 /* Generated */,
|
||||||
|
@ -481,6 +503,7 @@
|
||||||
0DA13C9126C15E1900E3B610 /* UIComponents */ = {
|
0DA13C9126C15E1900E3B610 /* UIComponents */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
2E35F99027B28E6800EB79CD /* TextFields */,
|
||||||
0D0781C5278776B90083ACD7 /* Shapes */,
|
0D0781C5278776B90083ACD7 /* Shapes */,
|
||||||
0D8A43C2272AEEA7005A6414 /* FontStyles */,
|
0D8A43C2272AEEA7005A6414 /* FontStyles */,
|
||||||
669FDAE7272C239D007B9422 /* CircularFrame */,
|
669FDAE7272C239D007B9422 /* CircularFrame */,
|
||||||
|
@ -513,6 +536,7 @@
|
||||||
F9EEB8152742C2210032EEB8 /* WithStateBinding.swift */,
|
F9EEB8152742C2210032EEB8 /* WithStateBinding.swift */,
|
||||||
F93673D52742CB840099C6AF /* Previews.swift */,
|
F93673D52742CB840099C6AF /* Previews.swift */,
|
||||||
0D35CC45277A36E00074316A /* ScrollableWhenScaled.swift */,
|
0D35CC45277A36E00074316A /* ScrollableWhenScaled.swift */,
|
||||||
|
2EDA07A327EDE2A900D6F09B /* DebugFrame.swift */,
|
||||||
9E2AC10027D8EF0B0042AA47 /* MnemonicSeedPhraseProvider.swift */,
|
9E2AC10027D8EF0B0042AA47 /* MnemonicSeedPhraseProvider.swift */,
|
||||||
9E2AC10227DA28200042AA47 /* WalletStorage.swift */,
|
9E2AC10227DA28200042AA47 /* WalletStorage.swift */,
|
||||||
9E80B47127E4B34B008FF493 /* UserPreferencesStorage.swift */,
|
9E80B47127E4B34B008FF493 /* UserPreferencesStorage.swift */,
|
||||||
|
@ -567,6 +591,18 @@
|
||||||
path = RecoveryPhraseValidationTests;
|
path = RecoveryPhraseValidationTests;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
2E35F99027B28E6800EB79CD /* TextFields */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
2E8719CA27FB09990082C926 /* TransactionTextField.swift */,
|
||||||
|
2E8719CC27FB0D3B0082C926 /* TransactionCurrencySelector.swift */,
|
||||||
|
2EB7758627FC67FD00269373 /* TransactionInputStore.swift */,
|
||||||
|
2E6CF8DC27D78319004DCD7A /* CurrencySelectionStore.swift */,
|
||||||
|
2EDA07A527EDE31100D6F09B /* Components */,
|
||||||
|
);
|
||||||
|
path = TextFields;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
2E5C037F2738C55F008BFFD3 /* Onboarding */ = {
|
2E5C037F2738C55F008BFFD3 /* Onboarding */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -578,6 +614,18 @@
|
||||||
path = Onboarding;
|
path = Onboarding;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
2EDA07A527EDE31100D6F09B /* Components */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
2E35F99127B28E7600EB79CD /* SingleLineTextField.swift */,
|
||||||
|
2EDA079F27EDE18C00D6F09B /* TextFieldInput.swift */,
|
||||||
|
2EDA07A127EDE1AE00D6F09B /* TextFieldFooter.swift */,
|
||||||
|
2E35F99927B3E99C00EB79CD /* TextFieldTitleAccessoryButtonStyle.swift */,
|
||||||
|
2EB1C5E727D77F6100BC43D7 /* TextFieldStore.swift */,
|
||||||
|
);
|
||||||
|
path = Components;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
660558F4270C85F7009D6954 /* Generated */ = {
|
660558F4270C85F7009D6954 /* Generated */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -1078,12 +1126,15 @@
|
||||||
660558F8270C862F009D6954 /* XCAssets+Generated.swift in Sources */,
|
660558F8270C862F009D6954 /* XCAssets+Generated.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 */,
|
||||||
|
2EB7758727FC67FD00269373 /* TransactionInputStore.swift in Sources */,
|
||||||
669FDAE9272C23B3007B9422 /* CircularFrame.swift in Sources */,
|
669FDAE9272C23B3007B9422 /* CircularFrame.swift in Sources */,
|
||||||
9EF8136027F043CC0075AF48 /* AppDelegate.swift in Sources */,
|
9EF8136027F043CC0075AF48 /* AppDelegate.swift in Sources */,
|
||||||
9E80B47227E4B34B008FF493 /* UserPreferencesStorage.swift in Sources */,
|
9E80B47227E4B34B008FF493 /* UserPreferencesStorage.swift in Sources */,
|
||||||
F96B41E8273B501F0021B49A /* TransactionDetailView.swift in Sources */,
|
F96B41E8273B501F0021B49A /* TransactionDetailView.swift in Sources */,
|
||||||
663FABA2271D876C00E495F8 /* SecondaryButton.swift in Sources */,
|
663FABA2271D876C00E495F8 /* SecondaryButton.swift in Sources */,
|
||||||
0DC487C32772574C00BE6A63 /* ValidationSucceededView.swift in Sources */,
|
0DC487C32772574C00BE6A63 /* ValidationSucceededView.swift in Sources */,
|
||||||
|
2EB1C5E827D77F6100BC43D7 /* TextFieldStore.swift in Sources */,
|
||||||
0D8A43C4272AEEDE005A6414 /* SecantTextStyles.swift in Sources */,
|
0D8A43C4272AEEDE005A6414 /* SecantTextStyles.swift in Sources */,
|
||||||
0D1922F226BDE29300052649 /* ZcashSDKStubs.swift in Sources */,
|
0D1922F226BDE29300052649 /* ZcashSDKStubs.swift in Sources */,
|
||||||
9E4DC6E027C409A100E657F4 /* NeumorphicDesignModifier.swift in Sources */,
|
9E4DC6E027C409A100E657F4 /* NeumorphicDesignModifier.swift in Sources */,
|
||||||
|
@ -1092,6 +1143,7 @@
|
||||||
9E2DF99E27CF704D00649636 /* ImportWalletView.swift in Sources */,
|
9E2DF99E27CF704D00649636 /* ImportWalletView.swift in Sources */,
|
||||||
0D535FE2271F9476009A9E3E /* EnumeratedChip.swift in Sources */,
|
0D535FE2271F9476009A9E3E /* EnumeratedChip.swift in Sources */,
|
||||||
6654C73E2715A41300901167 /* OnboardingStore.swift in Sources */,
|
6654C73E2715A41300901167 /* OnboardingStore.swift in Sources */,
|
||||||
|
2E6CF8DD27D78319004DCD7A /* CurrencySelectionStore.swift in Sources */,
|
||||||
9EBEF87A27CE369800B4F343 /* RecoveryPhraseTestPreambleView.swift in Sources */,
|
9EBEF87A27CE369800B4F343 /* RecoveryPhraseTestPreambleView.swift in Sources */,
|
||||||
9E4DC6E227C4C6B700E657F4 /* SecantButtonStyles.swift in Sources */,
|
9E4DC6E227C4C6B700E657F4 /* SecantButtonStyles.swift in Sources */,
|
||||||
0DDB6A5127737D4A0012A410 /* ValidationFailedView.swift in Sources */,
|
0DDB6A5127737D4A0012A410 /* ValidationFailedView.swift in Sources */,
|
||||||
|
@ -1100,6 +1152,7 @@
|
||||||
F9971A5327680DD000A2DB75 /* Profile.swift in Sources */,
|
F9971A5327680DD000A2DB75 /* Profile.swift in Sources */,
|
||||||
F93874F0273C4DE200F0E875 /* HomeStore.swift in Sources */,
|
F93874F0273C4DE200F0E875 /* HomeStore.swift in Sources */,
|
||||||
669FDAEB272C23C2007B9422 /* CircularFrameBadge.swift in Sources */,
|
669FDAEB272C23C2007B9422 /* CircularFrameBadge.swift in Sources */,
|
||||||
|
2E8719CD27FB0D3B0082C926 /* TransactionCurrencySelector.swift in Sources */,
|
||||||
F9971A6C27680E1000A2DB75 /* WalletInfoView.swift in Sources */,
|
F9971A6C27680E1000A2DB75 /* WalletInfoView.swift in Sources */,
|
||||||
F9EEB8162742C2210032EEB8 /* WithStateBinding.swift in Sources */,
|
F9EEB8162742C2210032EEB8 /* WithStateBinding.swift in Sources */,
|
||||||
F93673D62742CB840099C6AF /* Previews.swift in Sources */,
|
F93673D62742CB840099C6AF /* Previews.swift in Sources */,
|
||||||
|
@ -1118,6 +1171,7 @@
|
||||||
0DA13CA526C1963000E3B610 /* Balance.swift in Sources */,
|
0DA13CA526C1963000E3B610 /* Balance.swift in Sources */,
|
||||||
2EA11F5B27467EF800709571 /* OnboardingFooterView.swift in Sources */,
|
2EA11F5B27467EF800709571 /* OnboardingFooterView.swift in Sources */,
|
||||||
66D50668271D9B6100E51F0D /* NavigationButtonStyle.swift in Sources */,
|
66D50668271D9B6100E51F0D /* NavigationButtonStyle.swift in Sources */,
|
||||||
|
2EDA07A427EDE2A900D6F09B /* DebugFrame.swift in Sources */,
|
||||||
0D3D040A2728B3A10032ABC1 /* RecoveryPhraseDisplayStore.swift in Sources */,
|
0D3D040A2728B3A10032ABC1 /* RecoveryPhraseDisplayStore.swift in Sources */,
|
||||||
9E2AC10127D8EF0B0042AA47 /* MnemonicSeedPhraseProvider.swift in Sources */,
|
9E2AC10127D8EF0B0042AA47 /* MnemonicSeedPhraseProvider.swift in Sources */,
|
||||||
0D354A0926D5A9D000315F45 /* Services.swift in Sources */,
|
0D354A0926D5A9D000315F45 /* Services.swift in Sources */,
|
||||||
|
@ -1138,14 +1192,17 @@
|
||||||
0D185819272723FF0046B928 /* ColoredChip.swift in Sources */,
|
0D185819272723FF0046B928 /* ColoredChip.swift in Sources */,
|
||||||
2EA11F5D27467F7700709571 /* OnboardingContentView.swift in Sources */,
|
2EA11F5D27467F7700709571 /* OnboardingContentView.swift in Sources */,
|
||||||
2E58E73B274679F000B2B84B /* OnboardingHeaderView.swift in Sources */,
|
2E58E73B274679F000B2B84B /* OnboardingHeaderView.swift in Sources */,
|
||||||
|
2E35F99227B28E7600EB79CD /* SingleLineTextField.swift in Sources */,
|
||||||
0D8A43C6272B129C005A6414 /* WordChipGrid.swift in Sources */,
|
0D8A43C6272B129C005A6414 /* WordChipGrid.swift in Sources */,
|
||||||
66A0807B271993C500118B79 /* OnboardingProgressIndicator.swift in Sources */,
|
66A0807B271993C500118B79 /* OnboardingProgressIndicator.swift in Sources */,
|
||||||
0D7DF08C271DCC0E00530046 /* ScreenBackground.swift in Sources */,
|
0D7DF08C271DCC0E00530046 /* ScreenBackground.swift in Sources */,
|
||||||
F9C165C22740403600592F76 /* CreateView.swift in Sources */,
|
F9C165C22740403600592F76 /* CreateView.swift in Sources */,
|
||||||
F9C165B4274031F600592F76 /* Bindings.swift in Sources */,
|
F9C165B4274031F600592F76 /* Bindings.swift in Sources */,
|
||||||
|
2E35F99A27B3E99C00EB79CD /* TextFieldTitleAccessoryButtonStyle.swift in Sources */,
|
||||||
9E2DF99C27CF704D00649636 /* ImportWalletStore.swift in Sources */,
|
9E2DF99C27CF704D00649636 /* ImportWalletStore.swift in Sources */,
|
||||||
F9971A6627680DFE00A2DB75 /* SettingsView.swift in Sources */,
|
F9971A6627680DFE00A2DB75 /* SettingsView.swift in Sources */,
|
||||||
F96B41EB273B50520021B49A /* Strings.swift in Sources */,
|
F96B41EB273B50520021B49A /* Strings.swift in Sources */,
|
||||||
|
2EDA07A227EDE1AE00D6F09B /* TextFieldFooter.swift in Sources */,
|
||||||
F9971A5427680DD000A2DB75 /* ProfileView.swift in Sources */,
|
F9971A5427680DD000A2DB75 /* ProfileView.swift in Sources */,
|
||||||
F9971A6027680DF600A2DB75 /* Scan.swift in Sources */,
|
F9971A6027680DF600A2DB75 /* Scan.swift in Sources */,
|
||||||
9EF8139127F191BF0075AF48 /* WalletStorageInteractor.swift in Sources */,
|
9EF8139127F191BF0075AF48 /* WalletStorageInteractor.swift in Sources */,
|
||||||
|
@ -1156,6 +1213,7 @@
|
||||||
F9971A6527680DFE00A2DB75 /* Settings.swift in Sources */,
|
F9971A6527680DFE00A2DB75 /* Settings.swift in Sources */,
|
||||||
9EF8139C27F47AED0075AF48 /* InitializationState.swift in Sources */,
|
9EF8139C27F47AED0075AF48 /* InitializationState.swift in Sources */,
|
||||||
0D0781C9278776D20083ACD7 /* ZcashSymbol.swift in Sources */,
|
0D0781C9278776D20083ACD7 /* ZcashSymbol.swift in Sources */,
|
||||||
|
2E8719CB27FB09990082C926 /* TransactionTextField.swift in Sources */,
|
||||||
6654C7412715A47300901167 /* Onboarding.swift in Sources */,
|
6654C7412715A47300901167 /* Onboarding.swift in Sources */,
|
||||||
F9C165C42740403600592F76 /* SentView.swift in Sources */,
|
F9C165C42740403600592F76 /* SentView.swift in Sources */,
|
||||||
F9971A5927680DDE00A2DB75 /* Request.swift in Sources */,
|
F9971A5927680DDE00A2DB75 /* Request.swift in Sources */,
|
||||||
|
|
|
@ -69,8 +69,8 @@
|
||||||
"repositoryURL": "https://github.com/apple/swift-crypto.git",
|
"repositoryURL": "https://github.com/apple/swift-crypto.git",
|
||||||
"state": {
|
"state": {
|
||||||
"branch": null,
|
"branch": null,
|
||||||
"revision": "a8911e0fadc25aef1071d582355bd1037a176060",
|
"revision": "067254c79435de759aeef4a6a03e43d087d61312",
|
||||||
"version": "2.0.4"
|
"version": "2.0.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "qr_lighttheme.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"appearances" : [
|
||||||
|
{
|
||||||
|
"appearance" : "luminosity",
|
||||||
|
"value" : "dark"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"filename" : "qr_darktheme.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "qr_lighttheme@2x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"appearances" : [
|
||||||
|
{
|
||||||
|
"appearance" : "luminosity",
|
||||||
|
"value" : "dark"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"filename" : "qr_darktheme@2x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "qr_lighttheme@3x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"appearances" : [
|
||||||
|
{
|
||||||
|
"appearance" : "luminosity",
|
||||||
|
"value" : "dark"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"filename" : "qr_darktheme@3x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 494 B |
After Width: | Height: | Size: 733 B |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 546 B |
After Width: | Height: | Size: 715 B |
After Width: | Height: | Size: 770 B |
|
@ -0,0 +1,56 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "swapicon_lighttheme.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"appearances" : [
|
||||||
|
{
|
||||||
|
"appearance" : "luminosity",
|
||||||
|
"value" : "dark"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"filename" : "swapicon_darktheme.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "swapicon_lighttheme@2x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"appearances" : [
|
||||||
|
{
|
||||||
|
"appearance" : "luminosity",
|
||||||
|
"value" : "dark"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"filename" : "swapicon_darktheme@2x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "swapicon_lighttheme@3x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"appearances" : [
|
||||||
|
{
|
||||||
|
"appearance" : "luminosity",
|
||||||
|
"value" : "dark"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"filename" : "swapicon_darktheme@3x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 271 B |
After Width: | Height: | Size: 424 B |
After Width: | Height: | Size: 552 B |
After Width: | Height: | Size: 298 B |
After Width: | Height: | Size: 463 B |
After Width: | Height: | Size: 599 B |
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"colors" : [
|
||||||
|
{
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "srgb",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "0.171",
|
||||||
|
"green" : "0.138",
|
||||||
|
"red" : "0.126"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom" : "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"appearances" : [
|
||||||
|
{
|
||||||
|
"appearance" : "luminosity",
|
||||||
|
"value" : "dark"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "srgb",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "0.000",
|
||||||
|
"green" : "0.810",
|
||||||
|
"red" : "1.000"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"colors" : [
|
||||||
|
{
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "srgb",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "0.110",
|
||||||
|
"green" : "0.110",
|
||||||
|
"red" : "0.110"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom" : "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"appearances" : [
|
||||||
|
{
|
||||||
|
"appearance" : "luminosity",
|
||||||
|
"value" : "dark"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "srgb",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "0.110",
|
||||||
|
"green" : "0.110",
|
||||||
|
"red" : "0.110"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"colors" : [
|
||||||
|
{
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "srgb",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "0.226",
|
||||||
|
"green" : "0.226",
|
||||||
|
"red" : "0.226"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom" : "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"appearances" : [
|
||||||
|
{
|
||||||
|
"appearance" : "luminosity",
|
||||||
|
"value" : "dark"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "srgb",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "0.226",
|
||||||
|
"green" : "0.226",
|
||||||
|
"red" : "0.226"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"colors" : [
|
||||||
|
{
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "srgb",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "0.827",
|
||||||
|
"blue" : "0.623",
|
||||||
|
"green" : "0.589",
|
||||||
|
"red" : "0.560"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom" : "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"appearances" : [
|
||||||
|
{
|
||||||
|
"appearance" : "luminosity",
|
||||||
|
"value" : "dark"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "srgb",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "0.290",
|
||||||
|
"green" : "0.275",
|
||||||
|
"red" : "0.259"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"colors" : [
|
||||||
|
{
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "srgb",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "0.678",
|
||||||
|
"green" : "0.459",
|
||||||
|
"red" : "0.557"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom" : "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"appearances" : [
|
||||||
|
{
|
||||||
|
"appearance" : "luminosity",
|
||||||
|
"value" : "dark"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "srgb",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "0.678",
|
||||||
|
"green" : "0.459",
|
||||||
|
"red" : "0.557"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
|
@ -37,7 +37,9 @@ internal enum Asset {
|
||||||
internal static let bank = ImageAsset(name: "bank")
|
internal static let bank = ImageAsset(name: "bank")
|
||||||
internal static let list = ImageAsset(name: "list")
|
internal static let list = ImageAsset(name: "list")
|
||||||
internal static let profile = ImageAsset(name: "profile")
|
internal static let profile = ImageAsset(name: "profile")
|
||||||
|
internal static let qrCode = ImageAsset(name: "qr-code")
|
||||||
internal static let shield = ImageAsset(name: "shield")
|
internal static let shield = ImageAsset(name: "shield")
|
||||||
|
internal static let swap = ImageAsset(name: "swap")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
internal enum Colors {
|
internal enum Colors {
|
||||||
|
@ -61,6 +63,9 @@ internal enum Asset {
|
||||||
internal static let secondaryButton = ColorAsset(name: "SecondaryButton")
|
internal static let secondaryButton = ColorAsset(name: "SecondaryButton")
|
||||||
internal static let secondaryButtonPressed = ColorAsset(name: "SecondaryButtonPressed")
|
internal static let secondaryButtonPressed = ColorAsset(name: "SecondaryButtonPressed")
|
||||||
}
|
}
|
||||||
|
internal enum Cursor {
|
||||||
|
internal static let bar = ColorAsset(name: "Bar")
|
||||||
|
}
|
||||||
internal enum Onboarding {
|
internal enum Onboarding {
|
||||||
internal static let badgeShadow = ColorAsset(name: "BadgeShadow")
|
internal static let badgeShadow = ColorAsset(name: "BadgeShadow")
|
||||||
internal static let circularFrameDarkOutlineGradientEnd = ColorAsset(name: "CircularFrameDarkOutlineGradientEnd")
|
internal static let circularFrameDarkOutlineGradientEnd = ColorAsset(name: "CircularFrameDarkOutlineGradientEnd")
|
||||||
|
@ -104,6 +109,14 @@ internal enum Asset {
|
||||||
internal static let captionTextShadow = ColorAsset(name: "captionTextShadow")
|
internal static let captionTextShadow = ColorAsset(name: "captionTextShadow")
|
||||||
internal static let highlightedSuperscriptText = ColorAsset(name: "highlightedSuperscriptText")
|
internal static let highlightedSuperscriptText = ColorAsset(name: "highlightedSuperscriptText")
|
||||||
}
|
}
|
||||||
|
internal enum TextField {
|
||||||
|
internal static let titleAccessoryButton = ColorAsset(name: "TitleAccessoryButton")
|
||||||
|
internal static let titleAccessoryButtonPressed = ColorAsset(name: "TitleAccessoryButtonPressed")
|
||||||
|
internal enum Underline {
|
||||||
|
internal static let gray = ColorAsset(name: "Gray")
|
||||||
|
internal static let purple = ColorAsset(name: "Purple")
|
||||||
|
}
|
||||||
|
}
|
||||||
internal enum ZcashBadge {
|
internal enum ZcashBadge {
|
||||||
internal static let zcashLogoFill = ColorAsset(name: "ZcashLogoFill")
|
internal static let zcashLogoFill = ColorAsset(name: "ZcashLogoFill")
|
||||||
internal static let innerCircle = ColorAsset(name: "innerCircle")
|
internal static let innerCircle = ColorAsset(name: "innerCircle")
|
||||||
|
|
|
@ -0,0 +1,124 @@
|
||||||
|
//
|
||||||
|
// SingleLineTextField.swift
|
||||||
|
// secant-testnet
|
||||||
|
//
|
||||||
|
// Created by Adam Stener on 2/8/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
import ComposableArchitecture
|
||||||
|
|
||||||
|
struct SingleLineTextField<TitleAccessoryContent, InputAccessoryContent>: View
|
||||||
|
where TitleAccessoryContent: View, InputAccessoryContent: View {
|
||||||
|
let placeholderText: String
|
||||||
|
let title: String
|
||||||
|
let store: TextFieldStore
|
||||||
|
|
||||||
|
@ViewBuilder let titleAccessoryView: TitleAccessoryContent
|
||||||
|
@ViewBuilder let inputAccessoryView: InputAccessoryContent
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack(spacing: 0) {
|
||||||
|
HStack {
|
||||||
|
Text(title)
|
||||||
|
.lineLimit(1)
|
||||||
|
.truncationMode(.middle)
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
titleAccessoryView
|
||||||
|
}
|
||||||
|
|
||||||
|
HStack {
|
||||||
|
TextFieldInput(
|
||||||
|
placeholder: placeholderText,
|
||||||
|
store: store
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
inputAccessoryView
|
||||||
|
}
|
||||||
|
.frame(maxHeight: 50)
|
||||||
|
|
||||||
|
TextFieldFooter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SingleLineTextField_Previews: PreviewProvider {
|
||||||
|
struct TransactionPreview: View {
|
||||||
|
let store: TextFieldStore
|
||||||
|
let maxTransactionValue = 500.0
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
WithViewStore(store) { viewStore in
|
||||||
|
VStack {
|
||||||
|
SingleLineTextField(
|
||||||
|
placeholderText: "$0",
|
||||||
|
title: "How much?",
|
||||||
|
store: store,
|
||||||
|
titleAccessoryView: {
|
||||||
|
Button(
|
||||||
|
action: {
|
||||||
|
viewStore.send(.set("\(500)"))
|
||||||
|
},
|
||||||
|
label: { Text("Max") }
|
||||||
|
)
|
||||||
|
.textFieldTitleAccessoryButtonStyle
|
||||||
|
},
|
||||||
|
inputAccessoryView: { EmptyView() }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct UserPreview: View {
|
||||||
|
let store: TextFieldStore
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack {
|
||||||
|
SingleLineTextField(
|
||||||
|
placeholderText: "",
|
||||||
|
title: "Who would you like to deal with really long text today?",
|
||||||
|
store: store,
|
||||||
|
titleAccessoryView: { EmptyView() },
|
||||||
|
inputAccessoryView: { EmptyView() }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static var previews: some View {
|
||||||
|
TransactionPreview(
|
||||||
|
store: TextFieldStore(
|
||||||
|
initialState: .init(
|
||||||
|
validationType: .floatingPoint,
|
||||||
|
text: ""
|
||||||
|
),
|
||||||
|
reducer: .default,
|
||||||
|
environment: .init()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.preferredColorScheme(.dark)
|
||||||
|
.padding(.horizontal, 50)
|
||||||
|
.applyScreenBackground()
|
||||||
|
.previewLayout(.fixed(width: 500, height: 200))
|
||||||
|
|
||||||
|
UserPreview(
|
||||||
|
store: TextFieldStore(
|
||||||
|
initialState: .init(
|
||||||
|
validationType: .email,
|
||||||
|
text: ""
|
||||||
|
),
|
||||||
|
reducer: .default,
|
||||||
|
environment: .init()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.preferredColorScheme(.light)
|
||||||
|
.padding(.horizontal, 50)
|
||||||
|
.applyScreenBackground()
|
||||||
|
.previewLayout(.fixed(width: 500, height: 200))
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
//
|
||||||
|
// TextFieldFooter.swift
|
||||||
|
// secant-testnet
|
||||||
|
//
|
||||||
|
// Created by Adam Stener on 3/25/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
import ComposableArchitecture
|
||||||
|
|
||||||
|
struct TextFieldFooter: View {
|
||||||
|
var body: some View {
|
||||||
|
HStack(spacing: 0) {
|
||||||
|
Rectangle()
|
||||||
|
.frame(height: 1.5)
|
||||||
|
.foregroundColor(Asset.Colors.TextField.Underline.purple.color)
|
||||||
|
|
||||||
|
Rectangle()
|
||||||
|
.frame(height: 1.5)
|
||||||
|
.foregroundColor(Asset.Colors.TextField.Underline.gray.color)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
//
|
||||||
|
// TextFieldInput.swift
|
||||||
|
// secant-testnet
|
||||||
|
//
|
||||||
|
// Created by Adam Stener on 3/25/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
import ComposableArchitecture
|
||||||
|
|
||||||
|
struct TextFieldInput: View {
|
||||||
|
let placeholder: String
|
||||||
|
let store: TextFieldStore
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
WithViewStore(store) { viewStore in
|
||||||
|
TextField(
|
||||||
|
placeholder,
|
||||||
|
text: Binding(
|
||||||
|
get: { viewStore.state.text },
|
||||||
|
set: { viewStore.send(.set($0)) }
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.lineLimit(1)
|
||||||
|
.truncationMode(.middle)
|
||||||
|
.accentColor(Asset.Colors.Cursor.bar.color)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
//
|
||||||
|
// TextFieldStore.swift
|
||||||
|
// secant-testnet
|
||||||
|
//
|
||||||
|
// Created by Adam Stener on 3/8/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import ComposableArchitecture
|
||||||
|
|
||||||
|
typealias TextFieldReducer = Reducer<TextFieldState, TextFieldAction, TextFieldEnvironment>
|
||||||
|
typealias TextFieldStore = Store<TextFieldState, TextFieldAction>
|
||||||
|
|
||||||
|
struct TextFieldState: Equatable {
|
||||||
|
var validationType: String.ValidationType?
|
||||||
|
var text: String
|
||||||
|
var valid = false
|
||||||
|
|
||||||
|
init(validationType: String.ValidationType?, text: String) {
|
||||||
|
self.validationType = validationType
|
||||||
|
self.text = text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum TextFieldAction {
|
||||||
|
case apply((String) -> String)
|
||||||
|
case set(String)
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TextFieldEnvironment: Equatable { }
|
||||||
|
|
||||||
|
extension TextFieldReducer {
|
||||||
|
static let `default` = TextFieldReducer { state, action, _ in
|
||||||
|
switch action {
|
||||||
|
case .apply(let action):
|
||||||
|
state.text = action(state.text)
|
||||||
|
state.valid = state.text.isValid(for: state.validationType)
|
||||||
|
|
||||||
|
case .set(let text):
|
||||||
|
state.text = text
|
||||||
|
state.valid = state.text.isValid(for: state.validationType)
|
||||||
|
}
|
||||||
|
return .none
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension TextFieldStore {
|
||||||
|
static var transaction: Self {
|
||||||
|
.init(
|
||||||
|
initialState: .init(validationType: .floatingPoint, text: ""),
|
||||||
|
reducer: .default,
|
||||||
|
environment: .init()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
static var address: Self {
|
||||||
|
.init(
|
||||||
|
initialState: .init(validationType: .email, text: ""),
|
||||||
|
reducer: .default,
|
||||||
|
environment: .init()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
//
|
||||||
|
// TextFieldTitleAccessoryButtonStyle.swift
|
||||||
|
// secant-testnet
|
||||||
|
//
|
||||||
|
// Created by Adam Stener on 2/9/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct TextFieldTitleAccessoryButtonStyle: ButtonStyle {
|
||||||
|
func makeBody(configuration: Configuration) -> some View {
|
||||||
|
configuration.label
|
||||||
|
.padding(.horizontal, 10)
|
||||||
|
.padding(.vertical, 3)
|
||||||
|
.foregroundColor(.white)
|
||||||
|
.background(
|
||||||
|
configuration.isPressed ?
|
||||||
|
Asset.Colors.TextField.titleAccessoryButtonPressed.color :
|
||||||
|
Asset.Colors.TextField.titleAccessoryButton.color
|
||||||
|
)
|
||||||
|
.cornerRadius(6)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Button {
|
||||||
|
var textFieldTitleAccessoryButtonStyle: some View {
|
||||||
|
buttonStyle(TextFieldTitleAccessoryButtonStyle())
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
//
|
||||||
|
// ExchangeStore.swift
|
||||||
|
// secant-testnet
|
||||||
|
//
|
||||||
|
// Created by Adam Stener on 3/8/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import ComposableArchitecture
|
||||||
|
|
||||||
|
typealias CurrencySelectionReducer = Reducer<
|
||||||
|
CurrencySelectionState,
|
||||||
|
CurrencySelectionAction,
|
||||||
|
CurrencySelectionEnvironment
|
||||||
|
>
|
||||||
|
|
||||||
|
typealias CurrencySelectionStore = Store<CurrencySelectionState, CurrencySelectionAction>
|
||||||
|
|
||||||
|
struct CurrencySelectionState: Equatable {
|
||||||
|
enum Currency: Equatable {
|
||||||
|
case usd
|
||||||
|
case zec
|
||||||
|
|
||||||
|
var acronym: String {
|
||||||
|
switch self {
|
||||||
|
case .usd: return "USD"
|
||||||
|
case .zec: return "ZEC"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var currencyType: Currency = .zec
|
||||||
|
}
|
||||||
|
|
||||||
|
enum CurrencySelectionAction: Equatable {
|
||||||
|
case swapCurrencyType
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CurrencySelectionEnvironment: Equatable { }
|
||||||
|
|
||||||
|
extension CurrencySelectionReducer {
|
||||||
|
static var `default`: Self {
|
||||||
|
.init { state, action, _ in
|
||||||
|
switch action {
|
||||||
|
case .swapCurrencyType:
|
||||||
|
switch state.currencyType {
|
||||||
|
case .usd: state.currencyType = .zec
|
||||||
|
case .zec: state.currencyType = .usd
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return .none
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
//
|
||||||
|
// TransactionCurrencySelector.swift
|
||||||
|
// secant-testnet
|
||||||
|
//
|
||||||
|
// Created by Adam Stener on 4/4/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
import ComposableArchitecture
|
||||||
|
|
||||||
|
struct TransactionCurrencySelector: View {
|
||||||
|
let store: CurrencySelectionStore
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
WithViewStore(store) { viewStore in
|
||||||
|
Button(
|
||||||
|
action: { viewStore.send(.swapCurrencyType) },
|
||||||
|
label: {
|
||||||
|
HStack {
|
||||||
|
Text(CurrencySelectionState.Currency.usd.acronym)
|
||||||
|
.foregroundColor(
|
||||||
|
viewStore.currencyType == .usd ? .yellow : .white
|
||||||
|
)
|
||||||
|
|
||||||
|
Asset.Assets.Icons.swap.image
|
||||||
|
|
||||||
|
Text(CurrencySelectionState.Currency.zec.acronym)
|
||||||
|
.foregroundColor(
|
||||||
|
viewStore.currencyType == .zec ? .yellow : .white
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
//
|
||||||
|
// TransactionInputStore.swift
|
||||||
|
// secant-testnet
|
||||||
|
//
|
||||||
|
// Created by Adam Stener on 4/5/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import ComposableArchitecture
|
||||||
|
|
||||||
|
typealias TransactionInputReducer = Reducer<
|
||||||
|
TransactionInputState,
|
||||||
|
TransactionInputAction,
|
||||||
|
TransactionInputEnvironment
|
||||||
|
>
|
||||||
|
typealias TransactionReducerData = (inout TransactionInputState, TransactionInputAction) -> Void
|
||||||
|
typealias TransactionInputStore = Store<TransactionInputState, TransactionInputAction>
|
||||||
|
|
||||||
|
struct TransactionInputState: Equatable {
|
||||||
|
var textFieldState: TextFieldState
|
||||||
|
var currencySelectionState: CurrencySelectionState
|
||||||
|
}
|
||||||
|
|
||||||
|
enum TransactionInputAction {
|
||||||
|
case setMax(Double)
|
||||||
|
case textField(TextFieldAction)
|
||||||
|
case currencySelection(CurrencySelectionAction)
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TransactionInputEnvironment: Equatable {}
|
||||||
|
|
||||||
|
func maxOverride(_ reducer: @escaping (TransactionReducerData)) -> TransactionReducerData {
|
||||||
|
return { state, action in
|
||||||
|
switch action {
|
||||||
|
case .setMax(let value):
|
||||||
|
state.textFieldState.text = "\(value)"
|
||||||
|
state.currencySelectionState.currencyType = .usd
|
||||||
|
|
||||||
|
default: break
|
||||||
|
}
|
||||||
|
|
||||||
|
reducer(&state, action)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension TransactionInputReducer {
|
||||||
|
static let `default` = TransactionInputReducer.combine(
|
||||||
|
[
|
||||||
|
textFieldReducer,
|
||||||
|
currencySelectionReducer,
|
||||||
|
maxOverride,
|
||||||
|
currencyUpdate
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
static let maxOverride = TransactionInputReducer { state, action, _ in
|
||||||
|
switch action {
|
||||||
|
case .setMax(let value):
|
||||||
|
state.currencySelectionState.currencyType = .zec
|
||||||
|
state.textFieldState.text = "\(value)"
|
||||||
|
|
||||||
|
default: break
|
||||||
|
}
|
||||||
|
|
||||||
|
return .none
|
||||||
|
}
|
||||||
|
|
||||||
|
static let currencyUpdate = TransactionInputReducer { state, action, _ in
|
||||||
|
switch action {
|
||||||
|
case .currencySelection:
|
||||||
|
guard let currentDoubleValue = Double(state.textFieldState.text) else {
|
||||||
|
return .none
|
||||||
|
}
|
||||||
|
|
||||||
|
let currencyType = state.currencySelectionState.currencyType
|
||||||
|
|
||||||
|
// The 2100 is another hard coded value (🚀🌒) but the store could
|
||||||
|
// have a dependency injected that would be responsible for
|
||||||
|
// providing the current exchange rate.
|
||||||
|
let newValue = currencyType == .zec ?
|
||||||
|
currentDoubleValue / 2100 :
|
||||||
|
currentDoubleValue * 2100
|
||||||
|
state.textFieldState.text = "\(newValue)"
|
||||||
|
|
||||||
|
default: break
|
||||||
|
}
|
||||||
|
|
||||||
|
return .none
|
||||||
|
}
|
||||||
|
|
||||||
|
private static let textFieldReducer: TransactionInputReducer = TextFieldReducer.default.pullback(
|
||||||
|
state: \TransactionInputState.textFieldState,
|
||||||
|
action: /TransactionInputAction.textField,
|
||||||
|
environment: { _ in return .init() }
|
||||||
|
)
|
||||||
|
|
||||||
|
private static let currencySelectionReducer: TransactionInputReducer = CurrencySelectionReducer.default.pullback(
|
||||||
|
state: \TransactionInputState.currencySelectionState,
|
||||||
|
action: /TransactionInputAction.currencySelection,
|
||||||
|
environment: { _ in return .init() }
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
//
|
||||||
|
// TransactionTextField.swift
|
||||||
|
// secant-testnet
|
||||||
|
//
|
||||||
|
// Created by Adam Stener on 4/4/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
import ComposableArchitecture
|
||||||
|
|
||||||
|
struct TransactionTextField: View {
|
||||||
|
let store: TransactionInputStore
|
||||||
|
|
||||||
|
// Constant example used here, this could be injected by a dependency
|
||||||
|
// Access to this value could also be injected into the store as a dependency
|
||||||
|
// with a function to prouce this value.
|
||||||
|
let maxTransactionValue = 500.0
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
WithViewStore(store) { viewStore in
|
||||||
|
VStack {
|
||||||
|
SingleLineTextField(
|
||||||
|
placeholderText: "$0",
|
||||||
|
title: "How much?",
|
||||||
|
store: store.scope(
|
||||||
|
state: \.textFieldState,
|
||||||
|
action: TransactionInputAction.textField
|
||||||
|
),
|
||||||
|
titleAccessoryView: {
|
||||||
|
Button(
|
||||||
|
action: {
|
||||||
|
viewStore.send(.setMax(maxTransactionValue))
|
||||||
|
},
|
||||||
|
label: { Text("Max") }
|
||||||
|
)
|
||||||
|
.textFieldTitleAccessoryButtonStyle
|
||||||
|
},
|
||||||
|
inputAccessoryView: {
|
||||||
|
TransactionCurrencySelector(
|
||||||
|
store: store.scope(
|
||||||
|
state: \.currencySelectionState,
|
||||||
|
action: TransactionInputAction.currencySelection
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TransactionTextField_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
TransactionTextField(
|
||||||
|
store: TransactionInputStore(
|
||||||
|
initialState: .init(
|
||||||
|
textFieldState: .init(
|
||||||
|
validationType: .floatingPoint,
|
||||||
|
text: ""
|
||||||
|
),
|
||||||
|
currencySelectionState: .init(currencyType: .usd)
|
||||||
|
),
|
||||||
|
reducer: .default,
|
||||||
|
environment: .init()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.preferredColorScheme(.dark)
|
||||||
|
.padding(.horizontal, 50)
|
||||||
|
.applyScreenBackground()
|
||||||
|
.previewLayout(.fixed(width: 500, height: 200))
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
//
|
||||||
|
// DebugFrame.swift
|
||||||
|
// secant-testnet
|
||||||
|
//
|
||||||
|
// Created by Adam Stener on 3/25/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct DebugFrame: ViewModifier {
|
||||||
|
let color: Color
|
||||||
|
func body(content: Content) -> some View {
|
||||||
|
content
|
||||||
|
.overlay(
|
||||||
|
Rectangle()
|
||||||
|
.strokeBorder(
|
||||||
|
style: StrokeStyle(
|
||||||
|
lineWidth: 0.5,
|
||||||
|
dash: [3]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.foregroundColor(color)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension View {
|
||||||
|
func debug(_ color: Color) -> some View {
|
||||||
|
modifier(DebugFrame(color: color))
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,3 +8,57 @@ extension String {
|
||||||
self.init(stringLiteral: output)
|
self.init(stringLiteral: output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension String {
|
||||||
|
// TODO: Issue #245 Add Validation Regex that support localization
|
||||||
|
private static let floatingPointRegex = "^[0-9]*.?[0-9]+"
|
||||||
|
private static let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}"
|
||||||
|
private static let phoneRegex = "^^\\+(?:[0-9]?){6,14}[0-9]$"
|
||||||
|
|
||||||
|
public enum ValidationType: Equatable {
|
||||||
|
case custom(String)
|
||||||
|
case email
|
||||||
|
case floatingPoint
|
||||||
|
case maxLength(Int)
|
||||||
|
case minLength(Int)
|
||||||
|
case phoneNumber
|
||||||
|
|
||||||
|
func isValid(text: String) -> Bool {
|
||||||
|
switch self {
|
||||||
|
case .custom(let regex):
|
||||||
|
return text.validate(using: regex)
|
||||||
|
|
||||||
|
case .email:
|
||||||
|
return text.validate(using: .emailRegex)
|
||||||
|
|
||||||
|
case .floatingPoint:
|
||||||
|
return text.validate(using: .floatingPointRegex)
|
||||||
|
|
||||||
|
case .maxLength(let length):
|
||||||
|
return text.count <= length && !text.isEmpty
|
||||||
|
|
||||||
|
case .minLength(let length):
|
||||||
|
return text.count >= length
|
||||||
|
|
||||||
|
case .phoneNumber:
|
||||||
|
return text.validate(using: .phoneRegex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func validate(using regex: String) -> Bool {
|
||||||
|
guard let regex = try? NSRegularExpression(pattern: regex) else { return false }
|
||||||
|
|
||||||
|
return regex.firstMatch(
|
||||||
|
in: self,
|
||||||
|
options: [],
|
||||||
|
range: NSRange(location: 0, length: self.utf16.count)
|
||||||
|
) != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
public func isValid(for validationType: ValidationType?) -> Bool {
|
||||||
|
guard let validationType = validationType else { return true }
|
||||||
|
|
||||||
|
return validationType.isValid(text: self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|