From f6548ee4ff190a2b1d7653659c8f34861ee7f8c9 Mon Sep 17 00:00:00 2001 From: Lukas Korba Date: Tue, 1 Mar 2022 09:12:50 +0100 Subject: [PATCH 1/7] Import Wallet Screen added Scaffold of the import wallet screen has been created and connected to the onboarding flow --- secant.xcodeproj/project.pbxproj | 28 ++++ .../ImportSeedEditor.colorset/Contents.json | 38 ++++++ secant/Features/App/App.swift | 4 +- secant/Features/App/Views/AppView.swift | 13 +- .../ImportWallet/ImportWalletStore.swift | 47 +++++++ .../ImportWallet/Views/ImportSeedEditor.swift | 68 ++++++++++ .../ImportWallet/Views/ImportWalletView.swift | 120 ++++++++++++++++++ .../Features/Onboarding/OnboardingStore.swift | 50 +++++++- .../Onboarding/Views/Onboarding.swift | 4 +- secant/Generated/XCAssets+Generated.swift | 1 + .../Onboarding/OnboardingContentView.swift | 5 +- .../Onboarding/OnboardingFooterView.swift | 20 ++- .../Onboarding/OnboardingHeaderView.swift | 5 +- .../Screens/Onboarding/OnboardingScreen.swift | 25 +++- 14 files changed, 408 insertions(+), 20 deletions(-) create mode 100644 secant/Colors.xcassets/Text/ImportSeedEditor.colorset/Contents.json create mode 100644 secant/Features/ImportWallet/ImportWalletStore.swift create mode 100644 secant/Features/ImportWallet/Views/ImportSeedEditor.swift create mode 100644 secant/Features/ImportWallet/Views/ImportWalletView.swift diff --git a/secant.xcodeproj/project.pbxproj b/secant.xcodeproj/project.pbxproj index ca482ab..3c1be63 100644 --- a/secant.xcodeproj/project.pbxproj +++ b/secant.xcodeproj/project.pbxproj @@ -82,6 +82,9 @@ 66A0807B271993C500118B79 /* OnboardingProgressIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66A0807A271993C500118B79 /* OnboardingProgressIndicator.swift */; }; 66D50668271D9B6100E51F0D /* NavigationButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66D50667271D9B6100E51F0D /* NavigationButtonStyle.swift */; }; 66DC733F271D88CC0053CBB6 /* StandardButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66DC733E271D88CC0053CBB6 /* StandardButtonStyle.swift */; }; + 9E0FD7A027C910C000357DF0 /* ImportWalletStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E0FD79F27C910C000357DF0 /* ImportWalletStore.swift */; }; + 9E0FD7A327C910D500357DF0 /* ImportWalletView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E0FD7A227C910D500357DF0 /* ImportWalletView.swift */; }; + 9E0FD7A527C9163900357DF0 /* ImportSeedEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E0FD7A427C9163900357DF0 /* ImportSeedEditor.swift */; }; 9E4DC6E027C409A100E657F4 /* NeumorphicDesignModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E4DC6DF27C409A100E657F4 /* NeumorphicDesignModifier.swift */; }; 9E4DC6E227C4C6B700E657F4 /* SecantButtonStyles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E4DC6E127C4C6B700E657F4 /* SecantButtonStyles.swift */; }; F9322DC0273B555C00C105B5 /* NavigationLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9322DBF273B555C00C105B5 /* NavigationLinks.swift */; }; @@ -211,6 +214,9 @@ 66A0807A271993C500118B79 /* OnboardingProgressIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingProgressIndicator.swift; sourceTree = ""; }; 66D50667271D9B6100E51F0D /* NavigationButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationButtonStyle.swift; sourceTree = ""; }; 66DC733E271D88CC0053CBB6 /* StandardButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StandardButtonStyle.swift; sourceTree = ""; }; + 9E0FD79F27C910C000357DF0 /* ImportWalletStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImportWalletStore.swift; sourceTree = ""; }; + 9E0FD7A227C910D500357DF0 /* ImportWalletView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImportWalletView.swift; sourceTree = ""; }; + 9E0FD7A427C9163900357DF0 /* ImportSeedEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImportSeedEditor.swift; sourceTree = ""; }; 9E4DC6DF27C409A100E657F4 /* NeumorphicDesignModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NeumorphicDesignModifier.swift; sourceTree = ""; }; 9E4DC6E127C4C6B700E657F4 /* SecantButtonStyles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecantButtonStyles.swift; sourceTree = ""; }; F9322DBF273B555C00C105B5 /* NavigationLinks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationLinks.swift; sourceTree = ""; }; @@ -587,6 +593,7 @@ 0D3D04052728B2D70032ABC1 /* BackupFlow */, 6654C73C2715A3FA00901167 /* Onboarding */, F9971A6727680E1000A2DB75 /* WalletInfo */, + 9E0FD79E27C910AE00357DF0 /* ImportWallet */, ); path = Features; sourceTree = ""; @@ -642,6 +649,24 @@ path = CircularFrame; sourceTree = ""; }; + 9E0FD79E27C910AE00357DF0 /* ImportWallet */ = { + isa = PBXGroup; + children = ( + 9E0FD79F27C910C000357DF0 /* ImportWalletStore.swift */, + 9E0FD7A127C910C300357DF0 /* Views */, + ); + path = ImportWallet; + sourceTree = ""; + }; + 9E0FD7A127C910C300357DF0 /* Views */ = { + isa = PBXGroup; + children = ( + 9E0FD7A227C910D500357DF0 /* ImportWalletView.swift */, + 9E0FD7A427C9163900357DF0 /* ImportSeedEditor.swift */, + ); + path = Views; + sourceTree = ""; + }; F93874EC273C4DE200F0E875 /* Home */ = { isa = PBXGroup; children = ( @@ -999,6 +1024,7 @@ 2EB660E02747EAB900A06A07 /* OnboardingScreen.swift in Sources */, 660558F8270C862F009D6954 /* XCAssets+Generated.swift in Sources */, 0D35CC46277A36E00074316A /* ScrollableWhenScaled.swift in Sources */, + 9E0FD7A027C910C000357DF0 /* ImportWalletStore.swift in Sources */, F96B41E9273B501F0021B49A /* TransactionHistoryView.swift in Sources */, 669FDAE9272C23B3007B9422 /* CircularFrame.swift in Sources */, F96B41E8273B501F0021B49A /* TransactionDetailView.swift in Sources */, @@ -1010,6 +1036,7 @@ 0DACFA7F27208CE00039EEA5 /* Clamped.swift in Sources */, 0DFE93E3272CA1AA000FCCA5 /* RecoveryPhraseValidation.swift in Sources */, 0D354A0B26D5A9D000315F45 /* MnemonicSeedPhraseHandling.swift in Sources */, + 9E0FD7A527C9163900357DF0 /* ImportSeedEditor.swift in Sources */, 0D535FE2271F9476009A9E3E /* EnumeratedChip.swift in Sources */, 6654C73E2715A41300901167 /* OnboardingStore.swift in Sources */, 9E4DC6E227C4C6B700E657F4 /* SecantButtonStyles.swift in Sources */, @@ -1062,6 +1089,7 @@ 0D7DF08C271DCC0E00530046 /* ScreenBackground.swift in Sources */, F9C165C22740403600592F76 /* CreateView.swift in Sources */, F9C165B4274031F600592F76 /* Bindings.swift in Sources */, + 9E0FD7A327C910D500357DF0 /* ImportWalletView.swift in Sources */, F9971A6627680DFE00A2DB75 /* SettingsView.swift in Sources */, F96B41EB273B50520021B49A /* Strings.swift in Sources */, 0D354A0A26D5A9D000315F45 /* KeyStoring.swift in Sources */, diff --git a/secant/Colors.xcassets/Text/ImportSeedEditor.colorset/Contents.json b/secant/Colors.xcassets/Text/ImportSeedEditor.colorset/Contents.json new file mode 100644 index 0000000..8a83ad4 --- /dev/null +++ b/secant/Colors.xcassets/Text/ImportSeedEditor.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xA0", + "green" : "0x81", + "red" : "0x6E" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xA0", + "green" : "0x81", + "red" : "0x6E" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/secant/Features/App/App.swift b/secant/Features/App/App.swift index 6ced310..1546fcb 100644 --- a/secant/Features/App/App.swift +++ b/secant/Features/App/App.swift @@ -113,7 +113,9 @@ extension AppState { static var placeholder: Self { .init( homeState: .placeholder, - onboardingState: .init(), + onboardingState: .init( + importWalletState: .placeholder + ), phraseValidationState: RecoveryPhraseValidationState.placeholder, phraseDisplayState: RecoveryPhraseDisplayState( phrase: .placeholder diff --git a/secant/Features/App/Views/AppView.swift b/secant/Features/App/Views/AppView.swift index d55f613..f049072 100644 --- a/secant/Features/App/Views/AppView.swift +++ b/secant/Features/App/Views/AppView.swift @@ -20,12 +20,15 @@ struct AppView: View { .navigationViewStyle(StackNavigationViewStyle()) case .onboarding: - OnboardingScreen( - store: store.scope( - state: \.onboardingState, - action: AppAction.onboarding + NavigationView { + OnboardingScreen( + store: store.scope( + state: \.onboardingState, + action: AppAction.onboarding + ) ) - ) + } + .navigationViewStyle(StackNavigationViewStyle()) case .startup: ZStack(alignment: .topTrailing) { diff --git a/secant/Features/ImportWallet/ImportWalletStore.swift b/secant/Features/ImportWallet/ImportWalletStore.swift new file mode 100644 index 0000000..7c6bf56 --- /dev/null +++ b/secant/Features/ImportWallet/ImportWalletStore.swift @@ -0,0 +1,47 @@ +// +// ImportWalletStore.swift +// secant-testnet +// +// Created by Lukáš Korba on 02/25/2022. +// + +import ComposableArchitecture + +typealias ImportWalletStore = Store + +struct ImportWalletState: Equatable { + @BindableState var importedSeedPhrase: String = "" +} + +enum ImportWalletAction: Equatable, BindableAction { + case importRecoveryPhrase + case importPrivateOrViewingKey + case binding(BindingAction) +} + +struct ImportWalletEnvironment { } + +extension ImportWalletEnvironment { + static let demo = Self() + + static let live = Self() +} + +typealias ImportWalletReducer = Reducer + +extension ImportWalletReducer { + static let `default` = ImportWalletReducer { _, action, _ in + switch action { + case .importRecoveryPhrase: + // TODO: once connected to SDK, use the state.importedSeedPhrase + return .none + + case .importPrivateOrViewingKey: + return .none + + case .binding: + return .none + } + } + .binding() +} diff --git a/secant/Features/ImportWallet/Views/ImportSeedEditor.swift b/secant/Features/ImportWallet/Views/ImportSeedEditor.swift new file mode 100644 index 0000000..93b6d89 --- /dev/null +++ b/secant/Features/ImportWallet/Views/ImportSeedEditor.swift @@ -0,0 +1,68 @@ +// +// ImportSeedEditor.swift +// secant-testnet +// +// Created by Lukáš Korba on 02/25/2022. +// + +import SwiftUI +import ComposableArchitecture + +struct ImportSeedEditor: View { +// @State var state: String = "moose moose moose chicken chicken moose moose moose moose moose chicken chicken moose moose moose moose moose chicken chicken moose moose" + var store: ImportWalletStore + + /// Clearance of the black color for the TextEditor under the text (.dark colorScheme) + init(store: ImportWalletStore) { + self.store = store + UITextView.appearance().backgroundColor = .clear + } + + var body: some View { + WithViewStore(store) { viewStore in + TextEditor(text: viewStore.binding(\.$importedSeedPhrase)) + .importSeedEditorModifier() + .padding(28) + } + } +} + +struct ImportSeedEditorModifier: ViewModifier { + func body(content: Content) -> some View { + content + .foregroundColor(Asset.Colors.Text.importSeedEditor.color) + .padding() + .background(Color.white) + .cornerRadius(4) + .overlay( + RoundedRectangle(cornerRadius: 4) + .stroke(Color.black, lineWidth: 2) + ) + } +} + +extension View { + func importSeedEditorModifier() -> some View { + modifier(ImportSeedEditorModifier()) + } +} + +struct ImportSeedInputField_Previews: PreviewProvider { + static let width: CGFloat = 400 + static let height: CGFloat = 200 + + static var previews: some View { + Group { + ImportSeedEditor(store: .demo) + .frame(width: width, height: height) + .applyScreenBackground() + .preferredColorScheme(.light) + + ImportSeedEditor(store: .demo) + .frame(width: width, height: height) + .applyScreenBackground() + .preferredColorScheme(.dark) + } + .previewLayout(.fixed(width: width + 50, height: height + 50)) + } +} diff --git a/secant/Features/ImportWallet/Views/ImportWalletView.swift b/secant/Features/ImportWallet/Views/ImportWalletView.swift new file mode 100644 index 0000000..3fe2cc8 --- /dev/null +++ b/secant/Features/ImportWallet/Views/ImportWalletView.swift @@ -0,0 +1,120 @@ +// +// ImportWalletView.swift +// secant-testnet +// +// Created by Lukáš Korba on 02/25/2022. +// + +import SwiftUI +import ComposableArchitecture + +// jeste udelat scaledWhenBigFont +// fix button height +// zmena tlacitek na action pro dark +// navigaci, back nejak +// napojit na button v onboardingu +// texty do strings file +// back button at je jak ma byt +// action button ma spatnou barvu title v onboardingu +// progress bar se animuje skocenim dolu, protoze je animated + +struct ImportWalletView: View { + @Environment(\.presentationMode) var presentationMode + + var store: ImportWalletStore + + var body: some View { + WithViewStore(store) { viewStore in + VStack { + VStack(alignment: .leading, spacing: 30) { + HStack { + Button("Back") { presentationMode.wrappedValue.dismiss() } + .navigationButtonStyle + .frame(width: 75, height: 40) + + Text("Wallet Import") + .titleText() + } + + Text("You can import your backed up wallet by entering your backup recovery phrase (aka seed phrase) now.") + .paragraphText() + .lineSpacing(4) + .opacity(0.53) + } + .padding(18) + + ImportSeedEditor(store: store) + .frame(width: nil, height: 200, alignment: .center) + + Button("Import Recovery Phrase") { + viewStore.send(.importRecoveryPhrase) + } + .activeButtonStyle + .importWalletButtonLayout() + + Button("Import a private or viewing key") { + viewStore.send(.importPrivateOrViewingKey) + } + .secondaryButtonStyle + .importWalletButtonLayout() + + Spacer() + } + .navigationBarHidden(true) + .applyScreenBackground() + .scrollableWhenScaledUp() + } + } +} + +// swiftlint:disable:next private_over_fileprivate strict_fileprivate +fileprivate struct ImportWalletButtonLayout: ViewModifier { + func body(content: Content) -> some View { + content + .frame( + minWidth: 0, + maxWidth: .infinity, + minHeight: 60, + maxHeight: .infinity, + alignment: .center + ) + .fixedSize(horizontal: false, vertical: true) + .padding(.horizontal, 28) + .transition(.opacity) + } +} + +extension View { + func importWalletButtonLayout() -> some View { + modifier(ImportWalletButtonLayout()) + } +} + +extension ImportWalletStore { + static let demo = Store( + initialState: .placeholder, + reducer: .default, + environment: .demo + ) +} + +extension ImportWalletState { + static let placeholder = ImportWalletState(importedSeedPhrase: "") + + static let live = ImportWalletState(importedSeedPhrase: "") +} + +struct ImportWalletView_Previews: PreviewProvider { + static var previews: some View { + ImportWalletView(store: .demo) + .preferredColorScheme(.light) + + ImportWalletView(store: .demo) + .preferredColorScheme(.dark) + + ImportWalletView(store: .demo) + .previewDevice(PreviewDevice(rawValue: "iPhone SE (2nd generation)")) + .preferredColorScheme(.light) + .environment(\.sizeCategory, .accessibilityLarge) + } +} diff --git a/secant/Features/Onboarding/OnboardingStore.swift b/secant/Features/Onboarding/OnboardingStore.swift index 6404520..4329d45 100644 --- a/secant/Features/Onboarding/OnboardingStore.swift +++ b/secant/Features/Onboarding/OnboardingStore.swift @@ -9,7 +9,14 @@ import Foundation import SwiftUI import ComposableArchitecture +typealias OnboardingViewStore = ViewStore + struct OnboardingState: Equatable { + enum Route: Equatable, CaseIterable { + case createNewWallet + case importExistingWallet + } + struct Step: Equatable, Identifiable { let id: UUID let title: String @@ -21,7 +28,8 @@ struct OnboardingState: Equatable { var steps: IdentifiedArrayOf = Self.onboardingSteps var index = 0 var skippedAtindex: Int? - + var route: Route? + var currentStep: Step { steps[index] } var isFinalStep: Bool { steps.count == index + 1 } var isInitialStep: Bool { index == 0 } @@ -32,20 +40,43 @@ struct OnboardingState: Equatable { guard index != 0 else { return .zero } return stepOffset * CGFloat(index) } + + /// Import Wallet + var importWalletState: ImportWalletState +} + +extension OnboardingViewStore { + func bindingForRoute(_ route: OnboardingState.Route) -> Binding { + self.binding( + get: { $0.route == route }, + send: { isActive in + return .updateRoute(isActive ? route : nil) + } + ) + } } enum OnboardingAction: Equatable { case next case back case skip + case updateRoute(OnboardingState.Route?) case createNewWallet case importExistingWallet + case importWallet(ImportWalletAction) } typealias OnboardingReducer = Reducer extension OnboardingReducer { - static let `default` = Reducer { state, action, _ in + static let `default` = OnboardingReducer.combine( + [ + onboardingReducer, + importWalletReducer + ] + ) + + private static let onboardingReducer = OnboardingReducer { state, action, _ in switch action { case .back: guard state.index > 0 else { return .none } @@ -68,11 +99,26 @@ extension OnboardingReducer { state.index = state.steps.count - 1 return .none + case .updateRoute(let route): + state.route = route + return .none + case .createNewWallet: + state.route = .createNewWallet return .none case .importExistingWallet: + state.route = .importExistingWallet + return .none + + case .importWallet(let route): return .none } } + + private static let importWalletReducer: OnboardingReducer = ImportWalletReducer.default.pullback( + state: \OnboardingState.importWalletState, + action: /OnboardingAction.importWallet, + environment: { _ in ImportWalletEnvironment.live } + ) } diff --git a/secant/Features/Onboarding/Views/Onboarding.swift b/secant/Features/Onboarding/Views/Onboarding.swift index cb5882a..d5eae5e 100644 --- a/secant/Features/Onboarding/Views/Onboarding.swift +++ b/secant/Features/Onboarding/Views/Onboarding.swift @@ -94,7 +94,9 @@ struct Onboarding_Previews: PreviewProvider { Group { OnboardingView( store: Store( - initialState: OnboardingState(), + initialState: OnboardingState( + importWalletState: .placeholder + ), reducer: .default, environment: () ) diff --git a/secant/Generated/XCAssets+Generated.swift b/secant/Generated/XCAssets+Generated.swift index ec82a79..549edc3 100644 --- a/secant/Generated/XCAssets+Generated.swift +++ b/secant/Generated/XCAssets+Generated.swift @@ -91,6 +91,7 @@ internal enum Asset { internal static let body = ColorAsset(name: "Body") internal static let button = ColorAsset(name: "Button") internal static let heading = ColorAsset(name: "Heading") + internal static let importSeedEditor = ColorAsset(name: "ImportSeedEditor") internal static let medium = ColorAsset(name: "Medium") internal static let regular = ColorAsset(name: "Regular") internal static let secondaryButtonText = ColorAsset(name: "SecondaryButtonText") diff --git a/secant/Screens/Onboarding/OnboardingContentView.swift b/secant/Screens/Onboarding/OnboardingContentView.swift index 81e6e8f..1cb064b 100644 --- a/secant/Screens/Onboarding/OnboardingContentView.swift +++ b/secant/Screens/Onboarding/OnboardingContentView.swift @@ -127,7 +127,10 @@ extension OnboardingContentView { struct OnboardingContentView_Previews: PreviewProvider { static var previews: some View { let store = Store( - initialState: OnboardingState(index: 0), + initialState: OnboardingState( + index: 0, + importWalletState: .placeholder + ), reducer: OnboardingReducer.default, environment: () ) diff --git a/secant/Screens/Onboarding/OnboardingFooterView.swift b/secant/Screens/Onboarding/OnboardingFooterView.swift index 2a93a60..6ea92d1 100644 --- a/secant/Screens/Onboarding/OnboardingFooterView.swift +++ b/secant/Screens/Onboarding/OnboardingFooterView.swift @@ -23,12 +23,12 @@ struct OnboardingFooterView: View { viewStore.send(.createNewWallet) } } - .createButtonStyle + .activeButtonStyle .onboardingFooterButtonLayout() Button("Import an Existing Wallet") { withAnimation(.easeInOut(duration: animationDuration)) { - viewStore.send(.createNewWallet) + viewStore.send(.importExistingWallet) } } .secondaryButtonStyle @@ -52,6 +52,17 @@ struct OnboardingFooterView: View { .padding(.vertical, 20) } } + .navigationLinkEmpty( + isActive: viewStore.bindingForRoute(.importExistingWallet), + destination: { + ImportWalletView( + store: store.scope( + state: \.importWalletState, + action: OnboardingAction.importWallet + ) + ) + } + ) } } } @@ -75,7 +86,10 @@ extension View { struct OnboardingFooterView_Previews: PreviewProvider { static var previews: some View { let store = Store( - initialState: OnboardingState(index: 3), + initialState: OnboardingState( + index: 3, + importWalletState: .placeholder + ), reducer: OnboardingReducer.default, environment: () ) diff --git a/secant/Screens/Onboarding/OnboardingHeaderView.swift b/secant/Screens/Onboarding/OnboardingHeaderView.swift index 9df7987..a84f419 100644 --- a/secant/Screens/Onboarding/OnboardingHeaderView.swift +++ b/secant/Screens/Onboarding/OnboardingHeaderView.swift @@ -63,7 +63,10 @@ struct OnboardingHeaderView: View { struct OnboardingHeaderView_Previews: PreviewProvider { static var previews: some View { let store = Store( - initialState: OnboardingState(index: 0), + initialState: OnboardingState( + index: 0, + importWalletState: .placeholder + ), reducer: OnboardingReducer.default, environment: () ) diff --git a/secant/Screens/Onboarding/OnboardingScreen.swift b/secant/Screens/Onboarding/OnboardingScreen.swift index b234617..cea32be 100644 --- a/secant/Screens/Onboarding/OnboardingScreen.swift +++ b/secant/Screens/Onboarding/OnboardingScreen.swift @@ -42,6 +42,7 @@ struct OnboardingScreen: View { OnboardingFooterView(store: store) } } + .navigationBarHidden(true) .applyScreenBackground() } } @@ -50,7 +51,9 @@ struct OnboardingScreen_Previews: PreviewProvider { static var previews: some View { OnboardingScreen( store: Store( - initialState: OnboardingState(), + initialState: OnboardingState( + importWalletState: .placeholder + ), reducer: OnboardingReducer.default, environment: () ) @@ -60,7 +63,9 @@ struct OnboardingScreen_Previews: PreviewProvider { OnboardingScreen( store: Store( - initialState: OnboardingState(), + initialState: OnboardingState( + importWalletState: .placeholder + ), reducer: OnboardingReducer.default, environment: () ) @@ -70,7 +75,9 @@ struct OnboardingScreen_Previews: PreviewProvider { OnboardingScreen( store: Store( - initialState: OnboardingState(), + initialState: OnboardingState( + importWalletState: .placeholder + ), reducer: OnboardingReducer.default, environment: () ) @@ -80,7 +87,9 @@ struct OnboardingScreen_Previews: PreviewProvider { OnboardingScreen( store: Store( - initialState: OnboardingState(), + initialState: OnboardingState( + importWalletState: .placeholder + ), reducer: OnboardingReducer.default, environment: () ) @@ -90,7 +99,9 @@ struct OnboardingScreen_Previews: PreviewProvider { OnboardingScreen( store: Store( - initialState: OnboardingState(), + initialState: OnboardingState( + importWalletState: .placeholder + ), reducer: OnboardingReducer.default, environment: () ) @@ -100,7 +111,9 @@ struct OnboardingScreen_Previews: PreviewProvider { OnboardingScreen( store: Store( - initialState: OnboardingState(), + initialState: OnboardingState( + importWalletState: .placeholder + ), reducer: OnboardingReducer.default, environment: () ) From e52b28adc37b85d912b6cd52def13f855a6ec8df Mon Sep 17 00:00:00 2001 From: Lukas Korba Date: Tue, 1 Mar 2022 09:36:14 +0100 Subject: [PATCH 2/7] Import Wallet localised localisation of the import wallet screen done Height of the buttons according to design guide, the buttons should be 64px height --- secant.xcodeproj/project.pbxproj | 4 ++++ .../ImportWallet/Views/ImportWalletView.swift | 22 +++++-------------- secant/Localizable.strings | 6 +++++ 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/secant.xcodeproj/project.pbxproj b/secant.xcodeproj/project.pbxproj index 3c1be63..760e4cd 100644 --- a/secant.xcodeproj/project.pbxproj +++ b/secant.xcodeproj/project.pbxproj @@ -85,6 +85,7 @@ 9E0FD7A027C910C000357DF0 /* ImportWalletStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E0FD79F27C910C000357DF0 /* ImportWalletStore.swift */; }; 9E0FD7A327C910D500357DF0 /* ImportWalletView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E0FD7A227C910D500357DF0 /* ImportWalletView.swift */; }; 9E0FD7A527C9163900357DF0 /* ImportSeedEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E0FD7A427C9163900357DF0 /* ImportSeedEditor.swift */; }; + 9E0FD7AF27CE0E2900357DF0 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9E0FD7AE27CE0E2900357DF0 /* Localizable.strings */; }; 9E4DC6E027C409A100E657F4 /* NeumorphicDesignModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E4DC6DF27C409A100E657F4 /* NeumorphicDesignModifier.swift */; }; 9E4DC6E227C4C6B700E657F4 /* SecantButtonStyles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E4DC6E127C4C6B700E657F4 /* SecantButtonStyles.swift */; }; F9322DC0273B555C00C105B5 /* NavigationLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9322DBF273B555C00C105B5 /* NavigationLinks.swift */; }; @@ -217,6 +218,7 @@ 9E0FD79F27C910C000357DF0 /* ImportWalletStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImportWalletStore.swift; sourceTree = ""; }; 9E0FD7A227C910D500357DF0 /* ImportWalletView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImportWalletView.swift; sourceTree = ""; }; 9E0FD7A427C9163900357DF0 /* ImportSeedEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImportSeedEditor.swift; sourceTree = ""; }; + 9E0FD7AE27CE0E2900357DF0 /* Localizable.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; path = Localizable.strings; sourceTree = ""; }; 9E4DC6DF27C409A100E657F4 /* NeumorphicDesignModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NeumorphicDesignModifier.swift; sourceTree = ""; }; 9E4DC6E127C4C6B700E657F4 /* SecantButtonStyles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecantButtonStyles.swift; sourceTree = ""; }; F9322DBF273B555C00C105B5 /* NavigationLinks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationLinks.swift; sourceTree = ""; }; @@ -388,6 +390,7 @@ 0D4E7A0A26B364170058B01E /* ContentView.swift */, 0D4E7A0C26B364180058B01E /* Assets.xcassets */, 660558E8270C7A54009D6954 /* Colors.xcassets */, + 9E0FD7AE27CE0E2900357DF0 /* Localizable.strings */, 0D4E7A1126B364180058B01E /* Info.plist */, 0D4E7A0E26B364180058B01E /* Preview Content */, ); @@ -951,6 +954,7 @@ 0D4E7A0D26B364180058B01E /* Assets.xcassets in Resources */, 0DACFA9727209FA70039EEA5 /* Roboto-Black.ttf in Resources */, 0DACFA9C27209FA70039EEA5 /* Roboto-ThinItalic.ttf in Resources */, + 9E0FD7AF27CE0E2900357DF0 /* Localizable.strings in Resources */, 0DACFA9627209FA70039EEA5 /* Roboto-Thin.ttf in Resources */, 0D2ACE8026C2C67100D62E3C /* Zboto.otf in Resources */, ); diff --git a/secant/Features/ImportWallet/Views/ImportWalletView.swift b/secant/Features/ImportWallet/Views/ImportWalletView.swift index 3fe2cc8..a804465 100644 --- a/secant/Features/ImportWallet/Views/ImportWalletView.swift +++ b/secant/Features/ImportWallet/Views/ImportWalletView.swift @@ -8,21 +8,11 @@ import SwiftUI import ComposableArchitecture -// jeste udelat scaledWhenBigFont -// fix button height -// zmena tlacitek na action pro dark -// navigaci, back nejak -// napojit na button v onboardingu -// texty do strings file -// back button at je jak ma byt -// action button ma spatnou barvu title v onboardingu -// progress bar se animuje skocenim dolu, protoze je animated - struct ImportWalletView: View { @Environment(\.presentationMode) var presentationMode var store: ImportWalletStore - + var body: some View { WithViewStore(store) { viewStore in VStack { @@ -32,11 +22,11 @@ struct ImportWalletView: View { .navigationButtonStyle .frame(width: 75, height: 40) - Text("Wallet Import") + Text("importWallet.title") .titleText() } - Text("You can import your backed up wallet by entering your backup recovery phrase (aka seed phrase) now.") + Text("importWallet.description") .paragraphText() .lineSpacing(4) .opacity(0.53) @@ -46,13 +36,13 @@ struct ImportWalletView: View { ImportSeedEditor(store: store) .frame(width: nil, height: 200, alignment: .center) - Button("Import Recovery Phrase") { + Button("importWallet.button.importPhrase") { viewStore.send(.importRecoveryPhrase) } .activeButtonStyle .importWalletButtonLayout() - Button("Import a private or viewing key") { + Button("importWallet.button.importPrivateKey") { viewStore.send(.importPrivateOrViewingKey) } .secondaryButtonStyle @@ -74,7 +64,7 @@ fileprivate struct ImportWalletButtonLayout: ViewModifier { .frame( minWidth: 0, maxWidth: .infinity, - minHeight: 60, + minHeight: 64, maxHeight: .infinity, alignment: .center ) diff --git a/secant/Localizable.strings b/secant/Localizable.strings index d5e6406..4467270 100644 --- a/secant/Localizable.strings +++ b/secant/Localizable.strings @@ -42,6 +42,12 @@ "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"; +// MARK: - Import Wallet Screen +"importWallet.title" = "Wallet Import"; +"importWallet.description" = "You can import your backed up wallet by entering your backup recovery phrase (aka seed phrase) now."; +"importWallet.button.importPhrase" = "Import Recovery Phrase"; +"importWallet.button.importPrivateKey" = "Import a private or viewing key"; + // MARK: - Common & Shared "Back" = "Back"; "Skip" = "Skip"; From 907bcb2598880adf1ad3bc0f631c4a783befbf2f Mon Sep 17 00:00:00 2001 From: Lukas Korba Date: Tue, 1 Mar 2022 10:40:43 +0100 Subject: [PATCH 3/7] hotfix for the broken animation The .animation( is causing a visual issue in the views stack, the progress bar is animated to the bottom position. if we want easyInOut animation, we need to find a proper solution --- secant/Screens/Onboarding/OnboardingScreen.swift | 1 - .../ProgressIndicators/OnboardingProgressIndicator.swift | 2 -- 2 files changed, 3 deletions(-) diff --git a/secant/Screens/Onboarding/OnboardingScreen.swift b/secant/Screens/Onboarding/OnboardingScreen.swift index cea32be..2b623e4 100644 --- a/secant/Screens/Onboarding/OnboardingScreen.swift +++ b/secant/Screens/Onboarding/OnboardingScreen.swift @@ -10,7 +10,6 @@ import ComposableArchitecture struct OnboardingScreen: View { let store: Store - let animationDuration: CGFloat = 0.8 var body: some View { GeometryReader { proxy in diff --git a/secant/UIComponents/ProgressIndicators/OnboardingProgressIndicator.swift b/secant/UIComponents/ProgressIndicators/OnboardingProgressIndicator.swift index 7c6ab26..afa4af7 100644 --- a/secant/UIComponents/ProgressIndicators/OnboardingProgressIndicator.swift +++ b/secant/UIComponents/ProgressIndicators/OnboardingProgressIndicator.swift @@ -9,7 +9,6 @@ import SwiftUI struct OnboardingProgressStyle: ProgressViewStyle { let height: CGFloat = 3 - let animation: Animation = .easeInOut let gradient = LinearGradient( colors: [ Asset.Colors.ProgressIndicator.gradientLeft.color, @@ -53,7 +52,6 @@ struct OnboardingProgressStyle: ProgressViewStyle { } } .frame(height: height) - .animation(animation) } } } From 60d4db2f3b30dbeb586e4c53b363a090f9ffc542 Mon Sep 17 00:00:00 2001 From: Lukas Korba Date: Tue, 1 Mar 2022 10:50:57 +0100 Subject: [PATCH 4/7] updated tests all tests pass --- .../OnboardingStoreTests.swift | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/secantTests/OnboardingTests/OnboardingStoreTests.swift b/secantTests/OnboardingTests/OnboardingStoreTests.swift index 3fea50f..0cf270b 100644 --- a/secantTests/OnboardingTests/OnboardingStoreTests.swift +++ b/secantTests/OnboardingTests/OnboardingStoreTests.swift @@ -12,7 +12,9 @@ import ComposableArchitecture class OnboardingStoreTests: XCTestCase { func testIncrementingOnboarding() { let store = TestStore( - initialState: OnboardingState(), + initialState: OnboardingState( + importWalletState: .placeholder + ), reducer: OnboardingReducer.default, environment: () ) @@ -50,7 +52,10 @@ class OnboardingStoreTests: XCTestCase { func testIncrementingPastTotalStepsDoesNothing() { let store = TestStore( - initialState: OnboardingState(index: 3), + initialState: OnboardingState( + index: 3, + importWalletState: .placeholder + ), reducer: OnboardingReducer.default, environment: () ) @@ -74,7 +79,10 @@ class OnboardingStoreTests: XCTestCase { func testDecrementingOnboarding() { let store = TestStore( - initialState: OnboardingState(index: 2), + initialState: OnboardingState( + index: 2, + importWalletState: .placeholder + ), reducer: OnboardingReducer.default, environment: () ) @@ -102,7 +110,9 @@ class OnboardingStoreTests: XCTestCase { func testDecrementingPastFirstStepDoesNothing() { let store = TestStore( - initialState: OnboardingState(), + initialState: OnboardingState( + importWalletState: .placeholder + ), reducer: OnboardingReducer.default, environment: () ) @@ -128,7 +138,10 @@ class OnboardingStoreTests: XCTestCase { let initialIndex = 1 let store = TestStore( - initialState: OnboardingState(index: initialIndex), + initialState: OnboardingState( + index: initialIndex, + importWalletState: .placeholder + ), reducer: OnboardingReducer.default, environment: () ) From 59741f9cc665f12a0f013e2d3b0587362723d3fa Mon Sep 17 00:00:00 2001 From: Lukas Korba Date: Tue, 1 Mar 2022 15:33:01 +0100 Subject: [PATCH 5/7] FIXME added hotfix for the broken animation is to comment out easeInOut animation --- .../ProgressIndicators/OnboardingProgressIndicator.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/secant/UIComponents/ProgressIndicators/OnboardingProgressIndicator.swift b/secant/UIComponents/ProgressIndicators/OnboardingProgressIndicator.swift index afa4af7..5e80831 100644 --- a/secant/UIComponents/ProgressIndicators/OnboardingProgressIndicator.swift +++ b/secant/UIComponents/ProgressIndicators/OnboardingProgressIndicator.swift @@ -52,6 +52,7 @@ struct OnboardingProgressStyle: ProgressViewStyle { } } .frame(height: height) + // FIXME: .animation(.easeInOut) breaks the Onboarding UI when onAppear, fallback to .linear for now } } } From 3fd5a2061db41ae26064b7304158f8bbc6891db2 Mon Sep 17 00:00:00 2001 From: Lukas Korba Date: Tue, 1 Mar 2022 17:09:18 +0100 Subject: [PATCH 6/7] Update secant/Features/ImportWallet/ImportWalletStore.swift Co-authored-by: Francisco Gindre --- secant/Features/ImportWallet/ImportWalletStore.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/secant/Features/ImportWallet/ImportWalletStore.swift b/secant/Features/ImportWallet/ImportWalletStore.swift index 7c6bf56..adfb0a5 100644 --- a/secant/Features/ImportWallet/ImportWalletStore.swift +++ b/secant/Features/ImportWallet/ImportWalletStore.swift @@ -33,7 +33,7 @@ extension ImportWalletReducer { static let `default` = ImportWalletReducer { _, action, _ in switch action { case .importRecoveryPhrase: - // TODO: once connected to SDK, use the state.importedSeedPhrase + // TODO: once connected to SDK, use the state.importedSeedPhrase (Issue #166) return .none case .importPrivateOrViewingKey: From b0dff8a063aaf4f7686879f45e9a6c5aaf10d4e3 Mon Sep 17 00:00:00 2001 From: Lukas Korba Date: Tue, 1 Mar 2022 17:10:09 +0100 Subject: [PATCH 7/7] pointless comment removed --- secant/Features/ImportWallet/Views/ImportSeedEditor.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/secant/Features/ImportWallet/Views/ImportSeedEditor.swift b/secant/Features/ImportWallet/Views/ImportSeedEditor.swift index 93b6d89..9f0630b 100644 --- a/secant/Features/ImportWallet/Views/ImportSeedEditor.swift +++ b/secant/Features/ImportWallet/Views/ImportSeedEditor.swift @@ -9,7 +9,6 @@ import SwiftUI import ComposableArchitecture struct ImportSeedEditor: View { -// @State var state: String = "moose moose moose chicken chicken moose moose moose moose moose chicken chicken moose moose moose moose moose chicken chicken moose moose" var store: ImportWalletStore /// Clearance of the black color for the TextEditor under the text (.dark colorScheme)