From fcd7d2beabddfe03508bad163b8c7a259024418d Mon Sep 17 00:00:00 2001 From: Terry Yiu <963907+tyiu@users.noreply.github.com> Date: Sun, 9 Jul 2023 15:12:35 -0400 Subject: [PATCH] Fix localization issues and export strings for translation --- damus/Components/TranslateView.swift | 3 +- damus/Views/NostrScript/LoadScript.swift | 30 +-- damus/Views/Profile/ProfileView.swift | 3 +- damus/Views/Relays/RelayDetailView.swift | 2 +- damus/Views/Zaps/ZapTypePicker.swift | 17 +- damus/en-US.lproj/Localizable.stringsdict | 32 ++-- .../Localized Contents/en-US.xliff | 172 +++++++++++++----- .../damus/en-US.lproj/Localizable.strings | Bin 90656 -> 95542 bytes .../damus/en-US.lproj/Localizable.stringsdict | 32 ++-- damusTests/NostrScriptTests.swift | 12 ++ 10 files changed, 202 insertions(+), 101 deletions(-) diff --git a/damus/Components/TranslateView.swift b/damus/Components/TranslateView.swift index 68ca3a88..b7371786 100644 --- a/damus/Components/TranslateView.swift +++ b/damus/Components/TranslateView.swift @@ -44,7 +44,8 @@ struct TranslateView: View { func TranslatedView(lang: String?, artifacts: NoteArtifacts) -> some View { return VStack(alignment: .leading) { - Text(String(format: NSLocalizedString("Translated from %@", comment: "Button to indicate that the note has been translated from a different language."), lang ?? "ja")) + let translatedFromLanguageString = String(format: NSLocalizedString("Translated from %@", comment: "Button to indicate that the note has been translated from a different language."), lang ?? "ja") + Text(translatedFromLanguageString) .foregroundColor(.gray) .font(.footnote) .padding([.top, .bottom], 10) diff --git a/damus/Views/NostrScript/LoadScript.swift b/damus/Views/NostrScript/LoadScript.swift index 109922bb..38992dc9 100644 --- a/damus/Views/NostrScript/LoadScript.swift +++ b/damus/Views/NostrScript/LoadScript.swift @@ -80,6 +80,11 @@ class ScriptModel: ObservableObject { } } +func imports_string(_ count: Int, locale: Locale = Locale.current) -> String { + let format = localizedStringFormat(key: "imports_count", locale: locale) + return String(format: format, locale: locale, count) +} + struct LoadScript: View { let pool: RelayPool @@ -89,10 +94,9 @@ struct LoadScript: View { ScrollView { VStack { let imports = script.script.imports() - - (Text(verbatim: "\(imports.count)") + - Text(" Imports")) - .font(.title) + + let nounText = Text(verbatim: imports_string(imports.count)).font(.title) + Text("\(Text(verbatim: imports.count.formatted())) \(nounText)", comment: "Sentence composed of 2 variables to describe how many imports were performed from loading a NostrScript. In source English, the first variable is the number of imports, and the second variable is 'Import' or 'Imports'.") ForEach(imports.indices, id: \.self) { ind in Text(imports[ind]) @@ -100,25 +104,25 @@ struct LoadScript: View { switch script.state { case .loaded: - BigButton("Run") { + BigButton(NSLocalizedString("Run", comment: "Button that runs a NostrScript.")) { Task { await model.run() } } case .running: - Text("Running...") + Text("Running...", comment: "Indication that the execution of a NostrScript is running.") case .ran(let result): switch result { case .runtime_err(let errs): - Text("Runtime error") + Text("Runtime error", comment: "Indication that a runtime error occurred when running a NostrScript.") .font(.title2) ForEach(errs.indices, id: \.self) { ind in Text(verbatim: errs[ind]) } case .suspend: - Text("Ran to suspension.") + Text("Ran to suspension.", comment: "Indication that a NostrScript was run until it reached a suspended state.") case .finished(let code): - Text("Executed successfuly, returned with code \(code)") + Text("Executed successfully, returned with code \(code.description)", comment: "Indication that the execution of running a NostrScript finished successfully, while providing a numeric return code.") } } } @@ -138,13 +142,13 @@ struct LoadScript: View { ScriptView(loaded) case .failed(let load_err): VStack(spacing: 20) { - Text("NostrScript Error") + Text("NostrScript Error", comment: "Text indicating that there was an error with loading NostrScript. There is a more descriptive error message shown separately underneath.") .font(.title) switch load_err { case .parse: - Text("Failed to parse") + Text("Failed to parse", comment: "NostrScript error message when it fails to parse a script.") case .module_init: - Text("Failed to initialize") + Text("Failed to initialize", comment: "NostrScript error message when it fails to initialize a module.") } } } @@ -152,7 +156,7 @@ struct LoadScript: View { .task { await model.load(pool: self.pool) } - .navigationTitle("NostrScript") + .navigationTitle(NSLocalizedString("NostrScript", comment: "Navigation title for the view showing NostrScript.")) } } diff --git a/damus/Views/Profile/ProfileView.swift b/damus/Views/Profile/ProfileView.swift index ca77f234..8b265dc0 100644 --- a/damus/Views/Profile/ProfileView.swift +++ b/damus/Views/Profile/ProfileView.swift @@ -452,7 +452,8 @@ struct ProfileView: View { NavigationLink(value: Route.FollowersYouKnow(friendedFollowers: friended_followers, followers: followers)) { HStack { CondensedProfilePicturesView(state: damus_state, pubkeys: friended_followers, maxPictures: 3) - Text(followedByString(friended_followers, profiles: damus_state.profiles)) + let followedByString = followedByString(friended_followers, profiles: damus_state.profiles) + Text(followedByString) .font(.subheadline).foregroundColor(.gray) .multilineTextAlignment(.leading) } diff --git a/damus/Views/Relays/RelayDetailView.swift b/damus/Views/Relays/RelayDetailView.swift index 7a52ee95..02aeee81 100644 --- a/damus/Views/Relays/RelayDetailView.swift +++ b/damus/Views/Relays/RelayDetailView.swift @@ -126,7 +126,7 @@ struct RelayDetailView: View { } if state.settings.developer_mode, let log_contents = log.contents { - Section("Log") { + Section(NSLocalizedString("Log", comment: "Label to display developer mode logs.")) { Text(log_contents) .font(.system(size: 13)) .lineLimit(nil) diff --git a/damus/Views/Zaps/ZapTypePicker.swift b/damus/Views/Zaps/ZapTypePicker.swift index 632d84ee..4bcef8f7 100644 --- a/damus/Views/Zaps/ZapTypePicker.swift +++ b/damus/Views/Zaps/ZapTypePicker.swift @@ -61,15 +61,15 @@ struct ZapTypePicker: View { } } } - ZapTypeSelection(text: "Public", comment: "Picker option to indicate that a zap should be sent publicly and identify the user as who sent it.", img: "globe", action: {zap_type = ZapType.pub}, type: ZapType.pub) - ZapTypeSelection(text: "Private", comment: "Picker option to indicate that a zap should be sent privately and not identify the user to the public.", img: "lock", action: {zap_type = ZapType.priv}, type: ZapType.priv) - ZapTypeSelection(text: "Anonymous", comment: "Picker option to indicate that a zap should be sent anonymously and not identify the user as who sent it.", img: "question", action: {zap_type = ZapType.anon}, type: ZapType.anon) - ZapTypeSelection(text: "None", comment: "Picker option to indicate that sats should be sent to the user's wallet as a regular Lightning payment, not as a zap.", img: "zap", action: {zap_type = ZapType.non_zap}, type: ZapType.non_zap) + ZapTypeSelection(text: NSLocalizedString("Public", comment: "Picker option to indicate that a zap should be sent publicly and identify the user as who sent it."), img: "globe", action: {zap_type = ZapType.pub}, type: ZapType.pub) + ZapTypeSelection(text: NSLocalizedString("Private", comment: "Picker option to indicate that a zap should be sent privately and not identify the user to the public."), img: "lock", action: {zap_type = ZapType.priv}, type: ZapType.priv) + ZapTypeSelection(text: NSLocalizedString("Anonymous", comment: "Picker option to indicate that a zap should be sent anonymously and not identify the user as who sent it."), img: "question", action: {zap_type = ZapType.anon}, type: ZapType.anon) + ZapTypeSelection(text: NSLocalizedString("None", comment: "Picker option to indicate that sats should be sent to the user's wallet as a regular Lightning payment, not as a zap."), img: "zap", action: {zap_type = ZapType.non_zap}, type: ZapType.non_zap) } .padding(.horizontal) } - func ZapTypeSelection(text: LocalizedStringKey, comment: StaticString, img: String, action: @escaping () -> (), type: ZapType) -> some View { + func ZapTypeSelection(text: String, img: String, action: @escaping () -> (), type: ZapType) -> some View { Button(action: action) { VStack(alignment: .leading, spacing: 5) { HStack { @@ -79,14 +79,15 @@ struct ZapTypePicker: View { .frame(width: 20, height: 20) .foregroundColor(.gray) - Text(text, comment: comment) + Text(text) .font(.system(size: 20, weight: .semibold)) Spacer() } .padding(.horizontal) - - Text(zap_type_desc(type: type, profiles: profiles, pubkey: pubkey)) + + let zapTypeDescription = zap_type_desc(type: type, profiles: profiles, pubkey: pubkey) + Text(zapTypeDescription) .padding(.horizontal) .foregroundColor(.gray) .font(.system(size: 16)) diff --git a/damus/en-US.lproj/Localizable.stringsdict b/damus/en-US.lproj/Localizable.stringsdict index 8e04962e..787e50ab 100644 --- a/damus/en-US.lproj/Localizable.stringsdict +++ b/damus/en-US.lproj/Localizable.stringsdict @@ -2,22 +2,6 @@ - collapsed_event_view_other_notes - - NSStringLocalizedFormatKey - %#@NOTES@ - NOTES - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - d - one - ... %d other note ... - other - ... %d other notes ... - - followed_by_three_and_others NSStringLocalizedFormatKey @@ -66,6 +50,22 @@ Following + imports_count + + NSStringLocalizedFormatKey + %#@IMPORTS@ + IMPORTS + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + d + one + Import + other + Imports + + reacted_tagged_in_3 NSStringLocalizedFormatKey diff --git a/damus/en-US.xcloc/Localized Contents/en-US.xliff b/damus/en-US.xcloc/Localized Contents/en-US.xliff index 2ba795ff..e9fc97ac 100644 --- a/damus/en-US.xcloc/Localized Contents/en-US.xliff +++ b/damus/en-US.xcloc/Localized Contents/en-US.xliff @@ -45,7 +45,8 @@ %@ %@ %@ %@ - Sentence composed of 2 variables to describe how many zap payments there are on a post. In source English, the first variable is the number of zap payments, and the second variable is 'Zap' or 'Zaps'. + Sentence composed of 2 variables to describe how many imports were performed from loading a NostrScript. In source English, the first variable is the number of imports, and the second variable is 'Import' or 'Imports'. +Sentence composed of 2 variables to describe how many reposts. In source English, the first variable is the number of reposts, and the second variable is 'Repost' or 'Reposts'. Sentence composed of 2 variables to describe how many people are following a user. In source English, the first variable is the number of followers, and the second variable is 'Follower' or 'Followers'. @@ -158,6 +159,11 @@ Sentence composed of 2 variables to describe how many people are following a use Add bookmark Context menu option for adding a note bookmark. + + Additional information + Additional information + Header text to prompt user to optionally provide additional information when reporting a user or note. + Admin Admin @@ -191,7 +197,7 @@ Sentence composed of 2 variables to describe how many people are following a use Anonymous Anonymous - Placeholder author name of the anonymous person who zapped an event. + Picker option to indicate that a zap should be sent anonymously and not identify the user as who sent it. Placeholder display name of anonymous user. @@ -486,6 +492,22 @@ Sentence composed of 2 variables to describe how many people are following a use Description Label to display relay description. + + Developer + Developer + Navigation title for developer settings + Section header for developer settings + + + Developer Mode + Developer Mode + Setting to enable developer mode + + + Developer Mode enables features and options that may help developers diagnose issues and improve this app. Most users will not need Developer Mode. + Developer Mode enables features and options that may help developers diagnose issues and improve this app. Most users will not need Developer Mode. + Section header for Developer Settings view + Disconnect Disconnect @@ -551,6 +573,21 @@ Sentence composed of 2 variables to describe how many people are following a use Everyone will see that you zapped Description of public zap type where the zap is sent publicly and identifies the user who sent it. + + Executed successfully, returned with code %@ + Executed successfully, returned with code %@ + Indication that the execution of running a NostrScript finished successfully, while providing a numeric return code. + + + Failed to initialize + Failed to initialize + NostrScript error message when it fails to initialize a module. + + + Failed to parse + Failed to parse + NostrScript error message when it fails to parse a script. + Filter Filter @@ -646,10 +683,10 @@ Sentence composed of 2 variables to describe how many people are following a use Home Navigation bar title for Home view where notes and replies appear from those who the user is following. - - Illegal content - Illegal content - Button for user to report that the account or content has illegal content. + + Illegal Content + Illegal Content + Description of report type for illegal content. Image uploader @@ -661,16 +698,16 @@ Sentence composed of 2 variables to describe how many people are following a use Images Section title for images configuration. + + Impersonation + Impersonation + Description of report type for impersonation. + Invalid Tip Address Invalid Tip Address Title of alerting as invalid tip address. - - Invalid Zap - Invalid Zap - Text indicating that a zap event is malformed and could not be displayed. - Invalid key Invalid key @@ -681,11 +718,6 @@ Sentence composed of 2 variables to describe how many people are following a use Invalid lightning address Message to display when there was an error attempting to zap due to an invalid lightning address. - - It's spam - It's spam - Button for user to report that the account or content has spam. - Keys Keys @@ -757,6 +789,11 @@ Sentence composed of 2 variables to describe how many people are following a use Local default Dropdown option label for system default for Lightning wallet. + + Log + Log + Label to display developer mode logs. + Login Login @@ -878,13 +915,23 @@ Sentence composed of 2 variables to describe how many people are following a use None None - Button text to indicate that the zap type is a private zap. + Picker option to indicate that sats should be sent to the user's wallet as a regular Lightning payment, not as a zap. Nostr is a protocol, designed for simplicity, that aims to create a censorship-resistant global social network Nostr is a protocol, designed for simplicity, that aims to create a censorship-resistant global social network Description about what is Nostr. + + NostrScript + NostrScript + Navigation title for the view showing NostrScript. + + + NostrScript Error + NostrScript Error + Text indicating that there was an error with loading NostrScript. There is a more descriptive error message shown separately underneath. + Note contains "nsec1" private key. Are you sure? Note contains "nsec1" private key. Are you sure? @@ -928,10 +975,10 @@ Label for filter for seeing your notes and replies (instead of only your notes). Section header for Damus notifications Toolbar label for Notifications view. - - Nudity or explicit content - Nudity or explicit content - Button for user to report that the account or content has nudity or explicit content. + + Nudity + Nudity + Description of report type for nudity. Ok @@ -958,6 +1005,11 @@ Label for filter for seeing your notes and replies (instead of only your notes). OnlyZaps mode Setting toggle to hide reactions. + + Optional + Optional + Prompt to enter optional additional information when reporting an account or content. +