From b2bd0adaeafe6c3b7ca09f0836d273affeb425e2 Mon Sep 17 00:00:00 2001 From: Lukas Korba Date: Fri, 25 Feb 2022 13:27:50 +0100 Subject: [PATCH] Required strings localized All screens' strings that are meaningful for the demo application have been moved to the strings file. --- secant.xcodeproj/project.pbxproj | 4 ++ .../RecoveryPhraseBackupValidationView.swift | 8 ++-- .../Views/RecoveryPhraseDisplayView.swift | 12 ++--- .../Views/ValidationFailedView.swift | 8 ++-- .../Views/ValidationSucceededView.swift | 8 ++-- .../Features/Onboarding/OnboardingStore.swift | 4 +- .../Onboarding/Views/Onboarding.swift | 17 ++++--- secant/Features/Welcome/WelcomeView.swift | 4 +- secant/Localizable.strings | 48 +++++++++++++++++++ .../Onboarding/OnboardingFooterView.swift | 4 +- 10 files changed, 84 insertions(+), 33 deletions(-) create mode 100644 secant/Localizable.strings diff --git a/secant.xcodeproj/project.pbxproj b/secant.xcodeproj/project.pbxproj index ca482ab..ebdab6d 100644 --- a/secant.xcodeproj/project.pbxproj +++ b/secant.xcodeproj/project.pbxproj @@ -82,6 +82,7 @@ 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 */; }; + 9E37A2B827C8F59F00AE57B3 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9E37A2B727C8F59F00AE57B3 /* 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 */; }; @@ -211,6 +212,7 @@ 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 = ""; }; + 9E37A2B727C8F59F00AE57B3 /* Localizable.strings */ = {isa = PBXFileReference; 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 = ""; }; @@ -382,6 +384,7 @@ 0D4E7A0A26B364170058B01E /* ContentView.swift */, 0D4E7A0C26B364180058B01E /* Assets.xcassets */, 660558E8270C7A54009D6954 /* Colors.xcassets */, + 9E37A2B727C8F59F00AE57B3 /* Localizable.strings */, 0D4E7A1126B364180058B01E /* Info.plist */, 0D4E7A0E26B364180058B01E /* Preview Content */, ); @@ -926,6 +929,7 @@ 0D4E7A0D26B364180058B01E /* Assets.xcassets in Resources */, 0DACFA9727209FA70039EEA5 /* Roboto-Black.ttf in Resources */, 0DACFA9C27209FA70039EEA5 /* Roboto-ThinItalic.ttf in Resources */, + 9E37A2B827C8F59F00AE57B3 /* Localizable.strings in Resources */, 0DACFA9627209FA70039EEA5 /* Roboto-Thin.ttf in Resources */, 0D2ACE8026C2C67100D62E3C /* Zboto.otf in Resources */, ); diff --git a/secant/Features/BackupFlow/Views/RecoveryPhraseBackupValidationView.swift b/secant/Features/BackupFlow/Views/RecoveryPhraseBackupValidationView.swift index 00391f5..b2617c3 100644 --- a/secant/Features/BackupFlow/Views/RecoveryPhraseBackupValidationView.swift +++ b/secant/Features/BackupFlow/Views/RecoveryPhraseBackupValidationView.swift @@ -61,7 +61,7 @@ struct RecoveryPhraseBackupValidationView: View { .applyScreenBackground() .scrollableWhenScaledUp() .navigationBarTitleDisplayMode(.inline) - .navigationTitle(Text("Verify Your Backup")) + .navigationTitle(Text("recoveryPhraseBackupValidation.title")) } } @@ -70,7 +70,7 @@ struct RecoveryPhraseBackupValidationView: View { if viewStore.isComplete { completeHeader(for: viewStore.state) } else { - Text("Drag the words below to match your backed-up copy.") + Text("recoveryPhraseBackupValidation.description") .bodyText() } @@ -81,10 +81,10 @@ struct RecoveryPhraseBackupValidationView: View { @ViewBuilder func completeHeader(for state: RecoveryPhraseValidationState) -> some View { if state.isValid { - Text("Congratulations! You validated your secret recovery phrase.") + Text("recoveryPhraseBackupValidation.successResult") .bodyText() } else { - Text("Your placed words did not match your secret recovery phrase") + Text("recoveryPhraseBackupValidation.failedResult") .bodyText() } } diff --git a/secant/Features/BackupFlow/Views/RecoveryPhraseDisplayView.swift b/secant/Features/BackupFlow/Views/RecoveryPhraseDisplayView.swift index 8210b66..40b4413 100644 --- a/secant/Features/BackupFlow/Views/RecoveryPhraseDisplayView.swift +++ b/secant/Features/BackupFlow/Views/RecoveryPhraseDisplayView.swift @@ -17,15 +17,15 @@ struct RecoveryPhraseDisplayView: View { VStack(alignment: .center, spacing: 0) { if let groups = viewStore.phrase?.toGroups() { VStack(spacing: 20) { - Text("Your Secret Recovery Phrase") + Text("recoveryPhraseDisplay.title") .titleText() .multilineTextAlignment(.center) VStack(alignment: .center, spacing: 4) { - Text("The following 24 words represent your funds and the security used to protect them.") + Text("recoveryPhraseDisplay.description") .bodyText() - Text("Back them up now! There will be a test.") + Text("recoveryPhraseDisplay.backItUp") .bodyText() } } @@ -44,7 +44,7 @@ struct RecoveryPhraseDisplayView: View { VStack { Button( action: { viewStore.send(.finishedPressed) }, - label: { Text("Finished!") } + label: { Text("recoveryPhraseDisplay.button.finished") } ) .activeButtonStyle .frame(height: 60) @@ -54,7 +54,7 @@ struct RecoveryPhraseDisplayView: View { viewStore.send(.copyToBufferPressed) }, label: { - Text("Copy To Buffer") + Text("recoveryPhraseDisplay.button.copyToBuffer") .bodyText() } ) @@ -62,7 +62,7 @@ struct RecoveryPhraseDisplayView: View { } .padding() } else { - Text("Oops no words") + Text("recoveryPhraseDisplay.noWords") } } } diff --git a/secant/Features/BackupFlow/Views/ValidationFailedView.swift b/secant/Features/BackupFlow/Views/ValidationFailedView.swift index 1d1bb2f..25b6a5c 100644 --- a/secant/Features/BackupFlow/Views/ValidationFailedView.swift +++ b/secant/Features/BackupFlow/Views/ValidationFailedView.swift @@ -16,7 +16,7 @@ struct ValidationFailedView: View { GeometryReader { proxy in VStack { VStack(alignment: .center, spacing: 20) { - Text("Ouch, sorry, no.") + Text("validationFailed.title") .font(.custom(FontFamily.Rubik.regular.name, size: 30)) .fixedSize(horizontal: false, vertical: true) } @@ -36,18 +36,18 @@ struct ValidationFailedView: View { VStack(alignment: .center, spacing: 40) { VStack(alignment: .center, spacing: 20) { - Text("Your placed words did not match your secret recovery phrase.") + Text("validationFailed.description") .bodyText() .fixedSize(horizontal: false, vertical: true) - Text("Remember, you can't recover your funds if you lose (or incorrectly save) these 24 words.") + Text("validationFailed.incorrectBackupDescription") .bodyText() .fixedSize(horizontal: false, vertical: true) } Button( action: { viewStore.send(.reset) }, - label: { Text("I'm ready to try again") } + label: { Text("validationFailed.button.tryAgain") } ) .activeButtonStyle .frame(height: 60) diff --git a/secant/Features/BackupFlow/Views/ValidationSucceededView.swift b/secant/Features/BackupFlow/Views/ValidationSucceededView.swift index a53450a..2bd3873 100644 --- a/secant/Features/BackupFlow/Views/ValidationSucceededView.swift +++ b/secant/Features/BackupFlow/Views/ValidationSucceededView.swift @@ -19,10 +19,10 @@ struct ValidationSucceededView: View { GeometryReader { proxy in VStack { VStack(spacing: 20) { - Text("Success!") + Text("validationSuccess.title") .font(.custom(FontFamily.Rubik.regular.name, size: 36)) - Text("Place that backup somewhere safe and venture forth in security.") + Text("validationSuccess.description") .bodyText() .multilineTextAlignment(.center) .lineSpacing(2) @@ -52,7 +52,7 @@ struct ValidationSucceededView: View { viewStore.send(.proceedToHome, animation: .easeIn(duration: 1)) }, label: { - Text("Take me to my wallet!") + Text("validationSuccess.button.goToWallet") .fixedSize(horizontal: false, vertical: true) } ) @@ -71,7 +71,7 @@ struct ValidationSucceededView: View { ) }, label: { - Text("Show me my phrase again") + Text("validationSuccess.button.phraseAgain") .fixedSize(horizontal: false, vertical: true) } ) diff --git a/secant/Features/Onboarding/OnboardingStore.swift b/secant/Features/Onboarding/OnboardingStore.swift index 6404520..1f396bf 100644 --- a/secant/Features/Onboarding/OnboardingStore.swift +++ b/secant/Features/Onboarding/OnboardingStore.swift @@ -12,8 +12,8 @@ import ComposableArchitecture struct OnboardingState: Equatable { struct Step: Equatable, Identifiable { let id: UUID - let title: String - let description: String + let title: LocalizedStringKey + let description: LocalizedStringKey let background: Image let badge: Badge } diff --git a/secant/Features/Onboarding/Views/Onboarding.swift b/secant/Features/Onboarding/Views/Onboarding.swift index cb5882a..c4295ea 100644 --- a/secant/Features/Onboarding/Views/Onboarding.swift +++ b/secant/Features/Onboarding/Views/Onboarding.swift @@ -53,35 +53,34 @@ struct OnboardingView: View { } } -// swiftlint:disable line_length extension OnboardingState { static let onboardingSteps = IdentifiedArray( uniqueElements: [ Step( id: UUID(), - title: "Shielded by Default", - description: "Tired of worrying about which wallet you used last? US TOO! Now you don't have to, as all funds will automatically be moved to your shielded wallet (and migrated for you).", + title: "onboarding.step1.title", + description: "onboarding.step1.description", background: Asset.Assets.Backgrounds.callout1.image, badge: .shield ), Step( id: UUID(), - title: "Unified Addresses", - description: "Tired of worrying about which wallet you used last? US TOO! Now you don't have to, as all funds will automatically be moved to your shielded wallet (and migrated for you).", + title: "onboarding.step2.title", + description: "onboarding.step2.description", background: Asset.Assets.Backgrounds.callout2.image, badge: .person ), Step( id: UUID(), - title: "And so much more...", - description: "Faster reverse syncing (yes it's a thing). Liberated Payments, Social Payments, Address Books, in-line ZEC requests, wrapped Bitcoin, fractionalize NFTs, you providing liquidity for anything you want, getting that Defi, and going to Mexico.", + title: "onboarding.step3.title", + description: "onboarding.step3.description", background: Asset.Assets.Backgrounds.callout3.image, badge: .list ), Step( id: UUID(), - title: "Ready for the Future", - description: "Lets get you set up!", + title: "onboarding.step4.title", + description: "onboarding.step4.description", background: Asset.Assets.Backgrounds.callout4.image, badge: .shield ) diff --git a/secant/Features/Welcome/WelcomeView.swift b/secant/Features/Welcome/WelcomeView.swift index fad8bee..26c1182 100644 --- a/secant/Features/Welcome/WelcomeView.swift +++ b/secant/Features/Welcome/WelcomeView.swift @@ -23,10 +23,10 @@ struct WelcomeView: View { ) VStack { - Text("Welcome!") + Text("welcomeScreen.title") .titleText() - Text("Just Loading, one sec") + Text("welcomeScreen.subtitle") .captionText() } } diff --git a/secant/Localizable.strings b/secant/Localizable.strings new file mode 100644 index 0000000..d5e6406 --- /dev/null +++ b/secant/Localizable.strings @@ -0,0 +1,48 @@ +// MARK: - Welcome Screen +"welcomeScreen.title" = "Welcome!"; +"welcomeScreen.subtitle" = "Just Loading, one sec"; + +// MARK: - Onboarding Flow +"onboarding.step1.title" = "Shielded by Default"; +"onboarding.step1.description" = "Tired of worrying about which wallet you used last? US TOO! Now you don't have to, as all funds will automatically be moved to your shielded wallet (and migrated for you)."; + +"onboarding.step2.title" = "Unified Addresses"; +"onboarding.step2.description" = "Tired of worrying about which wallet you used last? US TOO! Now you don't have to, as all funds will automatically be moved to your shielded wallet (and migrated for you)."; + +"onboarding.step3.title" = "And so much more..."; +"onboarding.step3.description" = "Faster reverse syncing (yes it's a thing). Liberated Payments, Social Payments, Address Books, in-line ZEC requests, wrapped Bitcoin, fractionalize NFTs, you providing liquidity for anything you want, getting that Defi, and going to Mexico."; + +"onboarding.step4.title" = "Ready for the Future"; +"onboarding.step4.description" = "Lets get you set up!"; + +"onboarding.button.newWallet" = "Create New Wallet"; +"onboarding.button.importWallet" = "Import an Existing Wallet"; + +// MARK: - Secret Recovery Phrase Display +"recoveryPhraseDisplay.title" = "Your Secret Recovery Phrase"; +"recoveryPhraseDisplay.description" = "The following 24 words represent your funds and the security used to protect them."; +"recoveryPhraseDisplay.backItUp" = "Back them up now! There will be a test."; +"recoveryPhraseDisplay.button.finished" = "Finished!"; +"recoveryPhraseDisplay.button.copyToBuffer" = "Copy To Buffer"; +"recoveryPhraseDisplay.noWords" = "Oops no words"; + +// MARK: - Recovery Phrase Backup Validation & Success/Failed +"recoveryPhraseBackupValidation.title" = "Verify Your Backup"; +"recoveryPhraseBackupValidation.description" = "Drag the words below to match your backed-up copy."; +"recoveryPhraseBackupValidation.successResult" = "Congratulations! You validated your secret recovery phrase."; +"recoveryPhraseBackupValidation.failedResult" = "Your placed words did not match your secret recovery phrase"; + +"validationSuccess.title" = "Success!"; +"validationSuccess.description" = "Place that backup somewhere safe and venture forth in security."; +"validationSuccess.button.goToWallet" = "Take me to my wallet!"; +"validationSuccess.button.phraseAgain" = "Show me my phrase again"; + +"validationFailed.title" = "Ouch, sorry, no."; +"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.button.tryAgain" = "I'm ready to try again"; + +// MARK: - Common & Shared +"Back" = "Back"; +"Skip" = "Skip"; +"Next" = "Next"; diff --git a/secant/Screens/Onboarding/OnboardingFooterView.swift b/secant/Screens/Onboarding/OnboardingFooterView.swift index 2a93a60..8bb8b31 100644 --- a/secant/Screens/Onboarding/OnboardingFooterView.swift +++ b/secant/Screens/Onboarding/OnboardingFooterView.swift @@ -18,7 +18,7 @@ struct OnboardingFooterView: View { Spacer() if viewStore.isFinalStep { - Button("Create New Wallet") { + Button("onboarding.button.newWallet") { withAnimation(.easeInOut(duration: animationDuration)) { viewStore.send(.createNewWallet) } @@ -26,7 +26,7 @@ struct OnboardingFooterView: View { .createButtonStyle .onboardingFooterButtonLayout() - Button("Import an Existing Wallet") { + Button("onboarding.button.importWallet") { withAnimation(.easeInOut(duration: animationDuration)) { viewStore.send(.createNewWallet) }