Merge pull request #187 from LukasKorba/147_phrase_preamble_screen
147 phrase preamble screen
This commit is contained in:
commit
16da312d71
|
@ -82,12 +82,13 @@
|
||||||
66A0807B271993C500118B79 /* OnboardingProgressIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66A0807A271993C500118B79 /* OnboardingProgressIndicator.swift */; };
|
66A0807B271993C500118B79 /* OnboardingProgressIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66A0807A271993C500118B79 /* OnboardingProgressIndicator.swift */; };
|
||||||
66D50668271D9B6100E51F0D /* NavigationButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66D50667271D9B6100E51F0D /* NavigationButtonStyle.swift */; };
|
66D50668271D9B6100E51F0D /* NavigationButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66D50667271D9B6100E51F0D /* NavigationButtonStyle.swift */; };
|
||||||
66DC733F271D88CC0053CBB6 /* StandardButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66DC733E271D88CC0053CBB6 /* StandardButtonStyle.swift */; };
|
66DC733F271D88CC0053CBB6 /* StandardButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66DC733E271D88CC0053CBB6 /* StandardButtonStyle.swift */; };
|
||||||
9E0FD7A027C910C000357DF0 /* ImportWalletStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E0FD79F27C910C000357DF0 /* ImportWalletStore.swift */; };
|
9E2DF99C27CF704D00649636 /* ImportWalletStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2DF99827CF704D00649636 /* ImportWalletStore.swift */; };
|
||||||
9E0FD7A327C910D500357DF0 /* ImportWalletView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E0FD7A227C910D500357DF0 /* ImportWalletView.swift */; };
|
9E2DF99D27CF704D00649636 /* ImportSeedEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2DF99A27CF704D00649636 /* ImportSeedEditor.swift */; };
|
||||||
9E0FD7A527C9163900357DF0 /* ImportSeedEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E0FD7A427C9163900357DF0 /* ImportSeedEditor.swift */; };
|
9E2DF99E27CF704D00649636 /* ImportWalletView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2DF99B27CF704D00649636 /* ImportWalletView.swift */; };
|
||||||
9E0FD7AF27CE0E2900357DF0 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9E0FD7AE27CE0E2900357DF0 /* Localizable.strings */; };
|
9E37A2B827C8F59F00AE57B3 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9E37A2B727C8F59F00AE57B3 /* Localizable.strings */; };
|
||||||
9E4DC6E027C409A100E657F4 /* NeumorphicDesignModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E4DC6DF27C409A100E657F4 /* NeumorphicDesignModifier.swift */; };
|
9E4DC6E027C409A100E657F4 /* NeumorphicDesignModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E4DC6DF27C409A100E657F4 /* NeumorphicDesignModifier.swift */; };
|
||||||
9E4DC6E227C4C6B700E657F4 /* SecantButtonStyles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E4DC6E127C4C6B700E657F4 /* SecantButtonStyles.swift */; };
|
9E4DC6E227C4C6B700E657F4 /* SecantButtonStyles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E4DC6E127C4C6B700E657F4 /* SecantButtonStyles.swift */; };
|
||||||
|
9EBEF87A27CE369800B4F343 /* RecoveryPhraseTestPreambleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EBEF87927CE369800B4F343 /* RecoveryPhraseTestPreambleView.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 */; };
|
||||||
|
@ -215,12 +216,13 @@
|
||||||
66A0807A271993C500118B79 /* OnboardingProgressIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingProgressIndicator.swift; sourceTree = "<group>"; };
|
66A0807A271993C500118B79 /* OnboardingProgressIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingProgressIndicator.swift; sourceTree = "<group>"; };
|
||||||
66D50667271D9B6100E51F0D /* NavigationButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationButtonStyle.swift; sourceTree = "<group>"; };
|
66D50667271D9B6100E51F0D /* NavigationButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationButtonStyle.swift; sourceTree = "<group>"; };
|
||||||
66DC733E271D88CC0053CBB6 /* StandardButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StandardButtonStyle.swift; sourceTree = "<group>"; };
|
66DC733E271D88CC0053CBB6 /* StandardButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StandardButtonStyle.swift; sourceTree = "<group>"; };
|
||||||
9E0FD79F27C910C000357DF0 /* ImportWalletStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImportWalletStore.swift; sourceTree = "<group>"; };
|
9E2DF99827CF704D00649636 /* ImportWalletStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImportWalletStore.swift; sourceTree = "<group>"; };
|
||||||
9E0FD7A227C910D500357DF0 /* ImportWalletView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImportWalletView.swift; sourceTree = "<group>"; };
|
9E2DF99A27CF704D00649636 /* ImportSeedEditor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImportSeedEditor.swift; sourceTree = "<group>"; };
|
||||||
9E0FD7A427C9163900357DF0 /* ImportSeedEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImportSeedEditor.swift; sourceTree = "<group>"; };
|
9E2DF99B27CF704D00649636 /* ImportWalletView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImportWalletView.swift; sourceTree = "<group>"; };
|
||||||
9E0FD7AE27CE0E2900357DF0 /* Localizable.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; path = Localizable.strings; sourceTree = "<group>"; };
|
9E37A2B727C8F59F00AE57B3 /* Localizable.strings */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; path = Localizable.strings; sourceTree = "<group>"; };
|
||||||
9E4DC6DF27C409A100E657F4 /* NeumorphicDesignModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NeumorphicDesignModifier.swift; sourceTree = "<group>"; };
|
9E4DC6DF27C409A100E657F4 /* NeumorphicDesignModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NeumorphicDesignModifier.swift; sourceTree = "<group>"; };
|
||||||
9E4DC6E127C4C6B700E657F4 /* SecantButtonStyles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecantButtonStyles.swift; sourceTree = "<group>"; };
|
9E4DC6E127C4C6B700E657F4 /* SecantButtonStyles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecantButtonStyles.swift; sourceTree = "<group>"; };
|
||||||
|
9EBEF87927CE369800B4F343 /* RecoveryPhraseTestPreambleView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecoveryPhraseTestPreambleView.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>"; };
|
||||||
|
@ -332,6 +334,7 @@
|
||||||
0D3D04052728B2D70032ABC1 /* BackupFlow */ = {
|
0D3D04052728B2D70032ABC1 /* BackupFlow */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
9EBEF87827CE365D00B4F343 /* Preamble */,
|
||||||
0D6D628A276A528D002FB4CC /* DropDelegate.swift */,
|
0D6D628A276A528D002FB4CC /* DropDelegate.swift */,
|
||||||
0D3D04062728B2EC0032ABC1 /* Views */,
|
0D3D04062728B2EC0032ABC1 /* Views */,
|
||||||
0D3D04092728B3A10032ABC1 /* RecoveryPhraseDisplayStore.swift */,
|
0D3D04092728B3A10032ABC1 /* RecoveryPhraseDisplayStore.swift */,
|
||||||
|
@ -390,7 +393,7 @@
|
||||||
0D4E7A0A26B364170058B01E /* ContentView.swift */,
|
0D4E7A0A26B364170058B01E /* ContentView.swift */,
|
||||||
0D4E7A0C26B364180058B01E /* Assets.xcassets */,
|
0D4E7A0C26B364180058B01E /* Assets.xcassets */,
|
||||||
660558E8270C7A54009D6954 /* Colors.xcassets */,
|
660558E8270C7A54009D6954 /* Colors.xcassets */,
|
||||||
9E0FD7AE27CE0E2900357DF0 /* Localizable.strings */,
|
9E37A2B727C8F59F00AE57B3 /* Localizable.strings */,
|
||||||
0D4E7A1126B364180058B01E /* Info.plist */,
|
0D4E7A1126B364180058B01E /* Info.plist */,
|
||||||
0D4E7A0E26B364180058B01E /* Preview Content */,
|
0D4E7A0E26B364180058B01E /* Preview Content */,
|
||||||
);
|
);
|
||||||
|
@ -596,7 +599,7 @@
|
||||||
0D3D04052728B2D70032ABC1 /* BackupFlow */,
|
0D3D04052728B2D70032ABC1 /* BackupFlow */,
|
||||||
6654C73C2715A3FA00901167 /* Onboarding */,
|
6654C73C2715A3FA00901167 /* Onboarding */,
|
||||||
F9971A6727680E1000A2DB75 /* WalletInfo */,
|
F9971A6727680E1000A2DB75 /* WalletInfo */,
|
||||||
9E0FD79E27C910AE00357DF0 /* ImportWallet */,
|
9E2DF99727CF704D00649636 /* ImportWallet */,
|
||||||
);
|
);
|
||||||
path = Features;
|
path = Features;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -652,24 +655,32 @@
|
||||||
path = CircularFrame;
|
path = CircularFrame;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
9E0FD79E27C910AE00357DF0 /* ImportWallet */ = {
|
9E2DF99727CF704D00649636 /* ImportWallet */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
9E0FD79F27C910C000357DF0 /* ImportWalletStore.swift */,
|
9E2DF99827CF704D00649636 /* ImportWalletStore.swift */,
|
||||||
9E0FD7A127C910C300357DF0 /* Views */,
|
9E2DF99927CF704D00649636 /* Views */,
|
||||||
);
|
);
|
||||||
path = ImportWallet;
|
path = ImportWallet;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
9E0FD7A127C910C300357DF0 /* Views */ = {
|
9E2DF99927CF704D00649636 /* Views */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
9E0FD7A227C910D500357DF0 /* ImportWalletView.swift */,
|
9E2DF99A27CF704D00649636 /* ImportSeedEditor.swift */,
|
||||||
9E0FD7A427C9163900357DF0 /* ImportSeedEditor.swift */,
|
9E2DF99B27CF704D00649636 /* ImportWalletView.swift */,
|
||||||
);
|
);
|
||||||
path = Views;
|
path = Views;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
9EBEF87827CE365D00B4F343 /* Preamble */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
9EBEF87927CE369800B4F343 /* RecoveryPhraseTestPreambleView.swift */,
|
||||||
|
);
|
||||||
|
path = Preamble;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
F93874EC273C4DE200F0E875 /* Home */ = {
|
F93874EC273C4DE200F0E875 /* Home */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -954,7 +965,7 @@
|
||||||
0D4E7A0D26B364180058B01E /* Assets.xcassets in Resources */,
|
0D4E7A0D26B364180058B01E /* Assets.xcassets in Resources */,
|
||||||
0DACFA9727209FA70039EEA5 /* Roboto-Black.ttf in Resources */,
|
0DACFA9727209FA70039EEA5 /* Roboto-Black.ttf in Resources */,
|
||||||
0DACFA9C27209FA70039EEA5 /* Roboto-ThinItalic.ttf in Resources */,
|
0DACFA9C27209FA70039EEA5 /* Roboto-ThinItalic.ttf in Resources */,
|
||||||
9E0FD7AF27CE0E2900357DF0 /* Localizable.strings in Resources */,
|
9E37A2B827C8F59F00AE57B3 /* Localizable.strings in Resources */,
|
||||||
0DACFA9627209FA70039EEA5 /* Roboto-Thin.ttf in Resources */,
|
0DACFA9627209FA70039EEA5 /* Roboto-Thin.ttf in Resources */,
|
||||||
0D2ACE8026C2C67100D62E3C /* Zboto.otf in Resources */,
|
0D2ACE8026C2C67100D62E3C /* Zboto.otf in Resources */,
|
||||||
);
|
);
|
||||||
|
@ -1028,7 +1039,6 @@
|
||||||
2EB660E02747EAB900A06A07 /* OnboardingScreen.swift in Sources */,
|
2EB660E02747EAB900A06A07 /* OnboardingScreen.swift in Sources */,
|
||||||
660558F8270C862F009D6954 /* XCAssets+Generated.swift in Sources */,
|
660558F8270C862F009D6954 /* XCAssets+Generated.swift in Sources */,
|
||||||
0D35CC46277A36E00074316A /* ScrollableWhenScaled.swift in Sources */,
|
0D35CC46277A36E00074316A /* ScrollableWhenScaled.swift in Sources */,
|
||||||
9E0FD7A027C910C000357DF0 /* ImportWalletStore.swift in Sources */,
|
|
||||||
F96B41E9273B501F0021B49A /* TransactionHistoryView.swift in Sources */,
|
F96B41E9273B501F0021B49A /* TransactionHistoryView.swift in Sources */,
|
||||||
669FDAE9272C23B3007B9422 /* CircularFrame.swift in Sources */,
|
669FDAE9272C23B3007B9422 /* CircularFrame.swift in Sources */,
|
||||||
F96B41E8273B501F0021B49A /* TransactionDetailView.swift in Sources */,
|
F96B41E8273B501F0021B49A /* TransactionDetailView.swift in Sources */,
|
||||||
|
@ -1039,13 +1049,15 @@
|
||||||
9E4DC6E027C409A100E657F4 /* NeumorphicDesignModifier.swift in Sources */,
|
9E4DC6E027C409A100E657F4 /* NeumorphicDesignModifier.swift in Sources */,
|
||||||
0DACFA7F27208CE00039EEA5 /* Clamped.swift in Sources */,
|
0DACFA7F27208CE00039EEA5 /* Clamped.swift in Sources */,
|
||||||
0DFE93E3272CA1AA000FCCA5 /* RecoveryPhraseValidation.swift in Sources */,
|
0DFE93E3272CA1AA000FCCA5 /* RecoveryPhraseValidation.swift in Sources */,
|
||||||
|
9E2DF99E27CF704D00649636 /* ImportWalletView.swift in Sources */,
|
||||||
0D354A0B26D5A9D000315F45 /* MnemonicSeedPhraseHandling.swift in Sources */,
|
0D354A0B26D5A9D000315F45 /* MnemonicSeedPhraseHandling.swift in Sources */,
|
||||||
9E0FD7A527C9163900357DF0 /* ImportSeedEditor.swift in Sources */,
|
|
||||||
0D535FE2271F9476009A9E3E /* EnumeratedChip.swift in Sources */,
|
0D535FE2271F9476009A9E3E /* EnumeratedChip.swift in Sources */,
|
||||||
6654C73E2715A41300901167 /* OnboardingStore.swift in Sources */,
|
6654C73E2715A41300901167 /* OnboardingStore.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 */,
|
||||||
0D6D628B276A528E002FB4CC /* DropDelegate.swift in Sources */,
|
0D6D628B276A528E002FB4CC /* DropDelegate.swift in Sources */,
|
||||||
|
9E2DF99D27CF704D00649636 /* ImportSeedEditor.swift in Sources */,
|
||||||
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 */,
|
||||||
|
@ -1093,7 +1105,7 @@
|
||||||
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 */,
|
||||||
9E0FD7A327C910D500357DF0 /* ImportWalletView.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 */,
|
||||||
0D354A0A26D5A9D000315F45 /* KeyStoring.swift in Sources */,
|
0D354A0A26D5A9D000315F45 /* KeyStoring.swift in Sources */,
|
||||||
|
|
22
secant/Assets.xcassets/Backgrounds/calloutBackupFlow1.imageset/Contents.json
vendored
Normal file
22
secant/Assets.xcassets/Backgrounds/calloutBackupFlow1.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "calloutBackupFlow1.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "calloutBackupFlow1@2x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
secant/Assets.xcassets/Backgrounds/calloutBackupFlow1.imageset/calloutBackupFlow1.png
vendored
Normal file
BIN
secant/Assets.xcassets/Backgrounds/calloutBackupFlow1.imageset/calloutBackupFlow1.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 205 KiB |
BIN
secant/Assets.xcassets/Backgrounds/calloutBackupFlow1.imageset/calloutBackupFlow1@2x.png
vendored
Normal file
BIN
secant/Assets.xcassets/Backgrounds/calloutBackupFlow1.imageset/calloutBackupFlow1@2x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 710 KiB |
|
@ -37,10 +37,11 @@ extension AppReducer {
|
||||||
routeReducer,
|
routeReducer,
|
||||||
homeReducer,
|
homeReducer,
|
||||||
onboardingReducer,
|
onboardingReducer,
|
||||||
phraseValidationReducer.debug(),
|
phraseValidationReducer,
|
||||||
phraseDisplayReducer.debug()
|
phraseDisplayReducer
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
.debug()
|
||||||
|
|
||||||
private static let routeReducer = AppReducer { state, action, _ in
|
private static let routeReducer = AppReducer { state, action, _ in
|
||||||
switch action {
|
switch action {
|
||||||
|
|
|
@ -38,25 +38,12 @@ struct AppView: View {
|
||||||
|
|
||||||
case .phraseValidation:
|
case .phraseValidation:
|
||||||
NavigationView {
|
NavigationView {
|
||||||
RecoveryPhraseBackupValidationView(
|
RecoveryPhraseTestPreambleView(
|
||||||
store: store.scope(
|
store: store.scope(
|
||||||
state: \.phraseValidationState,
|
state: \.phraseValidationState,
|
||||||
action: AppAction.phraseValidation
|
action: AppAction.phraseValidation
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.toolbar(
|
|
||||||
content: {
|
|
||||||
ToolbarItem(
|
|
||||||
placement: .navigationBarLeading,
|
|
||||||
content: {
|
|
||||||
Button(
|
|
||||||
action: { viewStore.send(.updateRoute(.startup)) },
|
|
||||||
label: { Text("Back") }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.navigationViewStyle(StackNavigationViewStyle())
|
.navigationViewStyle(StackNavigationViewStyle())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,124 @@
|
||||||
|
//
|
||||||
|
// RecoveryPhraseTestPreambleView.swift
|
||||||
|
// secant-testnet
|
||||||
|
//
|
||||||
|
// Created by Lukáš Korba on 03/01/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
import ComposableArchitecture
|
||||||
|
|
||||||
|
struct RecoveryPhraseTestPreambleView: View {
|
||||||
|
var store: RecoveryPhraseValidationStore
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
WithViewStore(store) { viewStore in
|
||||||
|
GeometryReader { proxy in
|
||||||
|
VStack {
|
||||||
|
VStack(alignment: .center, spacing: 20) {
|
||||||
|
Text("recoveryPhraseTestPreamble.title")
|
||||||
|
.titleText()
|
||||||
|
.multilineTextAlignment(.center)
|
||||||
|
|
||||||
|
Text("recoveryPhraseTestPreamble.paragraph1")
|
||||||
|
.paragraphText()
|
||||||
|
.multilineTextAlignment(.center)
|
||||||
|
.padding(.horizontal, 44)
|
||||||
|
.opacity(0.53)
|
||||||
|
}
|
||||||
|
.padding(.bottom, 20)
|
||||||
|
|
||||||
|
CircularFrame()
|
||||||
|
.backgroundImage(
|
||||||
|
Asset.Assets.Backgrounds.calloutBackupFlow1.image
|
||||||
|
)
|
||||||
|
.frame(
|
||||||
|
width: circularFrameUniformSize(width: proxy.size.width, height: proxy.size.height),
|
||||||
|
height: circularFrameUniformSize(width: proxy.size.width, height: proxy.size.height)
|
||||||
|
)
|
||||||
|
.badgeIcon(.person)
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
VStack(alignment: .center, spacing: 40) {
|
||||||
|
VStack(alignment: .center, spacing: 20) {
|
||||||
|
Text("recoveryPhraseTestPreamble.paragraph2")
|
||||||
|
.paragraphText()
|
||||||
|
.multilineTextAlignment(.center)
|
||||||
|
.opacity(0.53)
|
||||||
|
|
||||||
|
Text("recoveryPhraseTestPreamble.paragraph3")
|
||||||
|
.paragraphText()
|
||||||
|
.multilineTextAlignment(.center)
|
||||||
|
.padding(.horizontal, 10)
|
||||||
|
.opacity(0.53)
|
||||||
|
}
|
||||||
|
|
||||||
|
Button(
|
||||||
|
action: { viewStore.send(.updateRoute(.validation)) },
|
||||||
|
label: { Text("recoveryPhraseTestPreamble.button.goNext") }
|
||||||
|
)
|
||||||
|
.activeButtonStyle
|
||||||
|
.frame(
|
||||||
|
minWidth: 0,
|
||||||
|
maxWidth: .infinity,
|
||||||
|
minHeight: 64,
|
||||||
|
maxHeight: .infinity,
|
||||||
|
alignment: .center
|
||||||
|
)
|
||||||
|
.fixedSize(horizontal: false, vertical: true)
|
||||||
|
}
|
||||||
|
.padding()
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.frame(width: proxy.size.width)
|
||||||
|
.scrollableWhenScaledUp()
|
||||||
|
.navigationLinkEmpty(
|
||||||
|
isActive: viewStore.bindingForValidation,
|
||||||
|
destination: {
|
||||||
|
RecoveryPhraseBackupValidationView(store: store)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.padding()
|
||||||
|
.navigationBarHidden(true)
|
||||||
|
.applyScreenBackground()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Following computations are necessary to handle properly sizing and positioning of elements
|
||||||
|
/// on different devices (apects). iPhone SE and iPhone 8 are similar aspect family devices
|
||||||
|
/// while iPhone X, 11, etc are different family devices, capable to use more of the space.
|
||||||
|
extension RecoveryPhraseTestPreambleView {
|
||||||
|
func circularFrameUniformSize(width: CGFloat, height: CGFloat) -> CGFloat {
|
||||||
|
var deviceMultiplier = 1.0
|
||||||
|
|
||||||
|
if width > 0.0 {
|
||||||
|
let aspect = height / width
|
||||||
|
deviceMultiplier = 1.0 + (((aspect / 1.51) - 1.0) * 2.8)
|
||||||
|
}
|
||||||
|
|
||||||
|
return width * 0.4 * deviceMultiplier
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct RecoveryPhraseTestPreambleView_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
Group {
|
||||||
|
NavigationView {
|
||||||
|
RecoveryPhraseTestPreambleView(store: .demo)
|
||||||
|
}
|
||||||
|
|
||||||
|
RecoveryPhraseTestPreambleView(store: .demo)
|
||||||
|
.preferredColorScheme(.dark)
|
||||||
|
|
||||||
|
RecoveryPhraseTestPreambleView(store: .demo)
|
||||||
|
.previewDevice(PreviewDevice(rawValue: "iPhone SE (2nd generation)"))
|
||||||
|
|
||||||
|
RecoveryPhraseTestPreambleView(store: .demo)
|
||||||
|
.environment(\.sizeCategory, .accessibilityLarge)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,8 +19,11 @@ struct ValidationWord: Equatable {
|
||||||
var word: String
|
var word: String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - State
|
||||||
|
|
||||||
struct RecoveryPhraseValidationState: Equatable {
|
struct RecoveryPhraseValidationState: Equatable {
|
||||||
enum Route: Equatable, CaseIterable {
|
enum Route: Equatable, CaseIterable {
|
||||||
|
case validation
|
||||||
case success
|
case success
|
||||||
case failure
|
case failure
|
||||||
}
|
}
|
||||||
|
@ -44,17 +47,6 @@ struct RecoveryPhraseValidationState: Equatable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension RecoveryPhraseValidationViewStore {
|
|
||||||
func bindingForRoute(_ route: RecoveryPhraseValidationState.Route) -> Binding<Bool> {
|
|
||||||
self.binding(
|
|
||||||
get: { $0.route == route },
|
|
||||||
send: { isActive in
|
|
||||||
return .updateRoute(isActive ? route : nil)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension RecoveryPhraseValidationState {
|
extension RecoveryPhraseValidationState {
|
||||||
/// creates an initial `RecoveryPhraseValidationState` with no completions and random missing indices.
|
/// creates an initial `RecoveryPhraseValidationState` with no completions and random missing indices.
|
||||||
/// - Note: Use this function to create a random validation puzzle for a given phrase.
|
/// - Note: Use this function to create a random validation puzzle for a given phrase.
|
||||||
|
@ -127,6 +119,8 @@ extension RecoveryPhrase.Group {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Action
|
||||||
|
|
||||||
enum RecoveryPhraseValidationAction: Equatable {
|
enum RecoveryPhraseValidationAction: Equatable {
|
||||||
case updateRoute(RecoveryPhraseValidationState.Route?)
|
case updateRoute(RecoveryPhraseValidationState.Route?)
|
||||||
case reset
|
case reset
|
||||||
|
@ -138,6 +132,8 @@ enum RecoveryPhraseValidationAction: Equatable {
|
||||||
case displayBackedUpPhrase
|
case displayBackedUpPhrase
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Reducer
|
||||||
|
|
||||||
typealias RecoveryPhraseValidationReducer = Reducer<RecoveryPhraseValidationState, RecoveryPhraseValidationAction, BackupPhraseEnvironment>
|
typealias RecoveryPhraseValidationReducer = Reducer<RecoveryPhraseValidationState, RecoveryPhraseValidationAction, BackupPhraseEnvironment>
|
||||||
|
|
||||||
extension RecoveryPhraseValidationReducer {
|
extension RecoveryPhraseValidationReducer {
|
||||||
|
@ -145,6 +141,8 @@ extension RecoveryPhraseValidationReducer {
|
||||||
switch action {
|
switch action {
|
||||||
case .reset:
|
case .reset:
|
||||||
state = RecoveryPhraseValidationState.random(phrase: state.phrase)
|
state = RecoveryPhraseValidationState.random(phrase: state.phrase)
|
||||||
|
state.route = .validation
|
||||||
|
// FIXME: Resetting causes route to be nil = preamble screen, hence setting the .validation. The transition back is not animated though (issue 186)
|
||||||
|
|
||||||
case let .move(wordChip, group):
|
case let .move(wordChip, group):
|
||||||
guard
|
guard
|
||||||
|
@ -160,7 +158,7 @@ extension RecoveryPhraseValidationReducer {
|
||||||
let effect = Effect<RecoveryPhraseValidationAction, Never>(value: value)
|
let effect = Effect<RecoveryPhraseValidationAction, Never>(value: value)
|
||||||
.delay(for: 1, scheduler: environment.mainQueue)
|
.delay(for: 1, scheduler: environment.mainQueue)
|
||||||
.eraseToEffect()
|
.eraseToEffect()
|
||||||
|
|
||||||
if value == .succeed {
|
if value == .succeed {
|
||||||
return effect
|
return effect
|
||||||
} else {
|
} else {
|
||||||
|
@ -182,6 +180,10 @@ extension RecoveryPhraseValidationReducer {
|
||||||
environment.feedbackGenerator.generateFeedback()
|
environment.feedbackGenerator.generateFeedback()
|
||||||
|
|
||||||
case .updateRoute(let route):
|
case .updateRoute(let route):
|
||||||
|
guard let route = route else {
|
||||||
|
state = RecoveryPhraseValidationState.random(phrase: state.phrase)
|
||||||
|
return .none
|
||||||
|
}
|
||||||
state.route = route
|
state.route = route
|
||||||
|
|
||||||
case .proceedToHome:
|
case .proceedToHome:
|
||||||
|
@ -193,3 +195,45 @@ extension RecoveryPhraseValidationReducer {
|
||||||
return .none
|
return .none
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - ViewStore
|
||||||
|
|
||||||
|
extension RecoveryPhraseValidationViewStore {
|
||||||
|
func bindingForRoute(_ route: RecoveryPhraseValidationState.Route) -> Binding<Bool> {
|
||||||
|
self.binding(
|
||||||
|
get: { $0.route == route },
|
||||||
|
send: { isActive in
|
||||||
|
return .updateRoute(isActive ? route : nil)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension RecoveryPhraseValidationViewStore {
|
||||||
|
var bindingForValidation: Binding<Bool> {
|
||||||
|
self.binding(
|
||||||
|
get: { $0.route != nil },
|
||||||
|
send: { isActive in
|
||||||
|
return .updateRoute(isActive ? .validation : nil)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
var bindingForSuccess: Binding<Bool> {
|
||||||
|
self.binding(
|
||||||
|
get: { $0.route == .success },
|
||||||
|
send: { isActive in
|
||||||
|
return .updateRoute(isActive ? .success : .validation)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
var bindingForFailure: Binding<Bool> {
|
||||||
|
self.binding(
|
||||||
|
get: { $0.route == .failure },
|
||||||
|
send: { isActive in
|
||||||
|
return .updateRoute(isActive ? .failure : .validation)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -11,28 +11,31 @@ import ComposableArchitecture
|
||||||
struct RecoveryPhraseBackupValidationView: View {
|
struct RecoveryPhraseBackupValidationView: View {
|
||||||
let store: RecoveryPhraseValidationStore
|
let store: RecoveryPhraseValidationStore
|
||||||
|
|
||||||
|
var viewStore: RecoveryPhraseValidationViewStore {
|
||||||
|
ViewStore(store)
|
||||||
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
WithViewStore(self.store) { viewStore in
|
VStack(alignment: .center) {
|
||||||
VStack(alignment: .center) {
|
header(for: viewStore)
|
||||||
header(for: viewStore)
|
.padding(.horizontal)
|
||||||
.padding(.horizontal)
|
.padding(.bottom, 10)
|
||||||
.padding(.bottom, 10)
|
|
||||||
|
ZStack {
|
||||||
ZStack {
|
Asset.Colors.BackgroundColors.phraseGridDarkGray.color
|
||||||
Asset.Colors.BackgroundColors.phraseGridDarkGray.color
|
.edgesIgnoringSafeArea(.bottom)
|
||||||
.edgesIgnoringSafeArea(.bottom)
|
|
||||||
|
VStack(alignment: .center, spacing: 35) {
|
||||||
VStack(alignment: .center, spacing: 35) {
|
let state = viewStore.state
|
||||||
let state = viewStore.state
|
let groups = state.phrase.toGroups()
|
||||||
let groups = state.phrase.toGroups()
|
|
||||||
|
ForEach(Array(zip(groups.indices, groups)), id: \.0) { index, group in
|
||||||
ForEach(Array(zip(groups.indices, groups)), id: \.0) { index, group in
|
WordChipGrid(
|
||||||
WordChipGrid(
|
state: state,
|
||||||
state: state,
|
groupIndex: index,
|
||||||
groupIndex: index,
|
wordGroup: group,
|
||||||
wordGroup: group,
|
misingIndex: index
|
||||||
misingIndex: index
|
)
|
||||||
)
|
|
||||||
.frame(alignment: .center)
|
.frame(alignment: .center)
|
||||||
.background(Asset.Colors.BackgroundColors.phraseGridDarkGray.color)
|
.background(Asset.Colors.BackgroundColors.phraseGridDarkGray.color)
|
||||||
.whenIsDroppable(
|
.whenIsDroppable(
|
||||||
|
@ -41,28 +44,27 @@ struct RecoveryPhraseBackupValidationView: View {
|
||||||
viewStore.send(.move(wordChip: chipKind, intoGroup: index))
|
viewStore.send(.move(wordChip: chipKind, intoGroup: index))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
Spacer()
|
|
||||||
}
|
}
|
||||||
.padding()
|
|
||||||
.padding(.top, 0)
|
Spacer()
|
||||||
.navigationLinkEmpty(
|
|
||||||
isActive: viewStore.bindingForRoute(.success),
|
|
||||||
destination: { ValidationSucceededView(store: store) }
|
|
||||||
)
|
|
||||||
.navigationLinkEmpty(
|
|
||||||
isActive: viewStore.bindingForRoute(.failure),
|
|
||||||
destination: { ValidationFailedView(store: store) }
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
.frame(alignment: .top)
|
.padding()
|
||||||
|
.padding(.top, 0)
|
||||||
|
.navigationLinkEmpty(
|
||||||
|
isActive: viewStore.bindingForSuccess,
|
||||||
|
destination: { ValidationSucceededView(store: store) }
|
||||||
|
)
|
||||||
|
.navigationLinkEmpty(
|
||||||
|
isActive: viewStore.bindingForFailure,
|
||||||
|
destination: { ValidationFailedView(store: store) }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
.applyScreenBackground()
|
.frame(alignment: .top)
|
||||||
.scrollableWhenScaledUp()
|
|
||||||
.navigationBarTitleDisplayMode(.inline)
|
|
||||||
.navigationTitle(Text("recoveryPhraseBackupValidation.title"))
|
|
||||||
}
|
}
|
||||||
|
.applyScreenBackground()
|
||||||
|
.scrollableWhenScaledUp()
|
||||||
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
|
.navigationTitle(Text("recoveryPhraseBackupValidation.title"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ViewBuilder func header(for viewStore: RecoveryPhraseValidationViewStore) -> some View {
|
@ViewBuilder func header(for viewStore: RecoveryPhraseValidationViewStore) -> some View {
|
||||||
|
|
|
@ -29,6 +29,7 @@ internal enum Asset {
|
||||||
internal static let callout2 = ImageAsset(name: "callout2")
|
internal static let callout2 = ImageAsset(name: "callout2")
|
||||||
internal static let callout3 = ImageAsset(name: "callout3")
|
internal static let callout3 = ImageAsset(name: "callout3")
|
||||||
internal static let callout4 = ImageAsset(name: "callout4")
|
internal static let callout4 = ImageAsset(name: "callout4")
|
||||||
|
internal static let calloutBackupFlow1 = ImageAsset(name: "calloutBackupFlow1")
|
||||||
}
|
}
|
||||||
internal enum Icons {
|
internal enum Icons {
|
||||||
internal static let list = ImageAsset(name: "list")
|
internal static let list = ImageAsset(name: "list")
|
||||||
|
|
|
@ -41,7 +41,14 @@
|
||||||
"validationFailed.description" = "Your placed words did not match your secret recovery phrase.";
|
"validationFailed.description" = "Your placed words did not match your secret recovery phrase.";
|
||||||
"validationFailed.incorrectBackupDescription" = "Remember, you can't recover your funds if you lose (or incorrectly save) these 24 words.";
|
"validationFailed.incorrectBackupDescription" = "Remember, you can't recover your funds if you lose (or incorrectly save) these 24 words.";
|
||||||
"validationFailed.button.tryAgain" = "I'm ready to try again";
|
"validationFailed.button.tryAgain" = "I'm ready to try again";
|
||||||
|
|
||||||
|
// MARK: - Recovery Phrase Test Preamble
|
||||||
|
"recoveryPhraseTestPreamble.title" = "First things first";
|
||||||
|
"recoveryPhraseTestPreamble.paragraph1" = "It is important to understand that you are in charge here. Great, right? YOU get to be the bank!";
|
||||||
|
"recoveryPhraseTestPreamble.paragraph2" = "But it also means that YOU are the customer, and you need to be self-reliant.";
|
||||||
|
"recoveryPhraseTestPreamble.paragraph3" = "So how do you recover funds that you've hidden on a completely decentralized and private block-chain?";
|
||||||
|
"recoveryPhraseTestPreamble.button.goNext" = "By understanding and preparing";
|
||||||
|
|
||||||
// MARK: - Import Wallet Screen
|
// MARK: - Import Wallet Screen
|
||||||
"importWallet.title" = "Wallet Import";
|
"importWallet.title" = "Wallet Import";
|
||||||
"importWallet.description" = "You can import your backed up wallet by entering your backup recovery phrase (aka seed phrase) now.";
|
"importWallet.description" = "You can import your backed up wallet by entering your backup recovery phrase (aka seed phrase) now.";
|
||||||
|
|
Loading…
Reference in New Issue