From ee4ab43a8bb5bd5e04225dacc229affe82381c2a Mon Sep 17 00:00:00 2001 From: Stuart Breckenridge Date: Sat, 21 Nov 2020 09:11:31 +0800 Subject: [PATCH] Widget localization --- NetNewsWire.xcodeproj/project.pbxproj | 37 +++++++++- .../{ => Resources}/Localizable.stringsdict | 0 Widget/Resources/Localized.swift | 70 +++++++++++++++++++ Widget/Resources/en.lproj/Localizable.strings | 29 ++++++++ Widget/Widget Views/StarredWidget.swift | 4 +- Widget/Widget Views/TodayWidget.swift | 4 +- Widget/Widget Views/UnreadWidget.swift | 6 +- Widget/WidgetBundle.swift | 16 ++--- 8 files changed, 147 insertions(+), 19 deletions(-) rename Widget/{ => Resources}/Localizable.stringsdict (100%) create mode 100644 Widget/Resources/Localized.swift create mode 100644 Widget/Resources/en.lproj/Localizable.strings diff --git a/NetNewsWire.xcodeproj/project.pbxproj b/NetNewsWire.xcodeproj/project.pbxproj index 4f7037307..61e6c5814 100644 --- a/NetNewsWire.xcodeproj/project.pbxproj +++ b/NetNewsWire.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + 1701E1B52568983D009453D8 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 1701E1B72568983D009453D8 /* Localizable.strings */; }; + 1701E1E725689D1E009453D8 /* Localized.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1701E1E625689D1E009453D8 /* Localized.swift */; }; 1704053424E5985A00A00787 /* SceneNavigationModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1704053324E5985A00A00787 /* SceneNavigationModel.swift */; }; 1704053524E5985A00A00787 /* SceneNavigationModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1704053324E5985A00A00787 /* SceneNavigationModel.swift */; }; 1710B9132552354E00679C0D /* AddAccountHelpView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1710B9122552354E00679C0D /* AddAccountHelpView.swift */; }; @@ -1313,6 +1315,8 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 1701E1B62568983D009453D8 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; + 1701E1E625689D1E009453D8 /* Localized.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Localized.swift; sourceTree = ""; }; 1704053324E5985A00A00787 /* SceneNavigationModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneNavigationModel.swift; sourceTree = ""; }; 1710B9122552354E00679C0D /* AddAccountHelpView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddAccountHelpView.swift; sourceTree = ""; }; 1710B928255246F900679C0D /* EnableExtensionPointHelpView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnableExtensionPointHelpView.swift; sourceTree = ""; }; @@ -2119,7 +2123,6 @@ 176814792564BE3C00D98635 /* Resources */, 176813FB2564BB2D00D98635 /* Assets.xcassets */, 176813FD2564BB2D00D98635 /* Info.plist */, - 17D0682B2564F47E00C0B37E /* Localizable.stringsdict */, ); path = Widget; sourceTree = ""; @@ -2146,7 +2149,10 @@ 176814792564BE3C00D98635 /* Resources */ = { isa = PBXGroup; children = ( + 1701E1E625689D1E009453D8 /* Localized.swift */, 1768147A2564BE5400D98635 /* widget-sample.json */, + 1701E1B72568983D009453D8 /* Localizable.strings */, + 17D0682B2564F47E00C0B37E /* Localizable.stringsdict */, ); path = Resources; sourceTree = ""; @@ -3520,6 +3526,7 @@ 176813EF2564BB2C00D98635 /* Sources */, 176813F02564BB2C00D98635 /* Frameworks */, 176813F12564BB2C00D98635 /* Resources */, + 1701E1BF25689B44009453D8 /* SwiftGen Localization */, ); buildRules = ( ); @@ -3934,6 +3941,7 @@ buildActionMask = 2147483647; files = ( 176813FC2564BB2D00D98635 /* Assets.xcassets in Resources */, + 1701E1B52568983D009453D8 /* Localizable.strings in Resources */, 1768147B2564BE5400D98635 /* widget-sample.json in Resources */, 17D0682C2564F47E00C0B37E /* Localizable.stringsdict in Resources */, ); @@ -4177,6 +4185,24 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 1701E1BF25689B44009453D8 /* SwiftGen Localization */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "SwiftGen Localization"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "#swiftgen run strings -t structured-swift5 \"$PROJECT_DIR/Widget/Resources/en.lproj/Localizable.strings\" \"$PROJECT_DIR/Widget/Resources/Localizable.stringsdict\" --output \"$PROJECT_DIR/Widget/Resources/Localized.swift\";\n"; + }; 515D50802326D02600EE1167 /* Run Script: Verify No Build Settings */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 8; @@ -4288,6 +4314,7 @@ 1768146C2564BD8100D98635 /* WidgetDeepLinks.swift in Sources */, 1768143E2564BCC800D98635 /* TodayWidget.swift in Sources */, 1768142D2564BCA800D98635 /* TimelineProvider.swift in Sources */, + 1701E1E725689D1E009453D8 /* Localized.swift in Sources */, 176814652564BD7F00D98635 /* WidgetData.swift in Sources */, 1768145E2564BD7B00D98635 /* WidgetDataDecoder.swift in Sources */, 176814132564BC8A00D98635 /* WidgetBundle.swift in Sources */, @@ -5282,6 +5309,14 @@ /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ + 1701E1B72568983D009453D8 /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 1701E1B62568983D009453D8 /* en */, + ); + name = Localizable.strings; + sourceTree = ""; + }; 510C416224E5CDE3008226FD /* ShareViewController.xib */ = { isa = PBXVariantGroup; children = ( diff --git a/Widget/Localizable.stringsdict b/Widget/Resources/Localizable.stringsdict similarity index 100% rename from Widget/Localizable.stringsdict rename to Widget/Resources/Localizable.stringsdict diff --git a/Widget/Resources/Localized.swift b/Widget/Resources/Localized.swift new file mode 100644 index 000000000..6e1104097 --- /dev/null +++ b/Widget/Resources/Localized.swift @@ -0,0 +1,70 @@ +// swiftlint:disable all +// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen + +import Foundation + +// swiftlint:disable superfluous_disable_command file_length implicit_return + +// MARK: - Strings + +// swiftlint:disable explicit_type_interface function_parameter_count identifier_name line_length +// swiftlint:disable nesting type_body_length type_name vertical_whitespace_opening_braces +internal enum L10n { + /// A count of your smart feeds. + internal static let smartFeedSummaryWidgetDescription = L10n.tr("Localizable", "SmartFeedSummary_Widget_Description") + /// Your Smart Feed Summary + internal static let smartFeedSummaryWidgetTitle = L10n.tr("Localizable", "SmartFeedSummary_Widget_Title") + /// A sneak peak at your starred articles. + internal static let starredWidgetDescription = L10n.tr("Localizable", "Starred_Widget_Description") + /// You've not starred any artices. + internal static let starredWidgetNoItems = L10n.tr("Localizable", "Starred_Widget_NoItems") + /// Your Starred Articles + internal static let starredWidgetTitle = L10n.tr("Localizable", "Starred_Widget_Title") + /// Plural format key: "%#@starred_count@" + internal static func starredCount(_ p1: Int) -> String { + return L10n.tr("Localizable", "StarredCount", p1) + } + /// A sneak peak at recently published unread articles. + internal static let todayWidgetDescription = L10n.tr("Localizable", "Today_Widget_Description") + /// There are no recent articles to read. + internal static let todayWidgetNoItems = L10n.tr("Localizable", "Today_Widget_NoItems") + /// Your Today Articles + internal static let todayWidgetTitle = L10n.tr("Localizable", "Today_Widget_Title") + /// Plural format key: "%#@today_count@" + internal static func todayCount(_ p1: Int) -> String { + return L10n.tr("Localizable", "TodayCount", p1) + } + /// A sneak peak at your unread articles. + internal static let unreadWidgetDescription = L10n.tr("Localizable", "Unread_Widget_Description") + /// There's nothing to read right now. + internal static let unreadWidgetNoItems = L10n.tr("Localizable", "Unread_Widget_NoItems") + /// Your Unread Articles + internal static let unreadWidgetTitle = L10n.tr("Localizable", "Unread_Widget_Title") + /// Plural format key: "%#@unread_count@" + internal static func unreadCount(_ p1: Int) -> String { + return L10n.tr("Localizable", "UnreadCount", p1) + } +} +// swiftlint:enable explicit_type_interface function_parameter_count identifier_name line_length +// swiftlint:enable nesting type_body_length type_name vertical_whitespace_opening_braces + +// MARK: - Implementation Details + +extension L10n { + private static func tr(_ table: String, _ key: String, _ args: CVarArg...) -> String { + let format = BundleToken.bundle.localizedString(forKey: key, value: nil, table: table) + return String(format: format, locale: Locale.current, arguments: args) + } +} + +// swiftlint:disable convenience_type +private final class BundleToken { + static let bundle: Bundle = { + #if SWIFT_PACKAGE + return Bundle.module + #else + return Bundle(for: BundleToken.self) + #endif + }() +} +// swiftlint:enable convenience_type diff --git a/Widget/Resources/en.lproj/Localizable.strings b/Widget/Resources/en.lproj/Localizable.strings new file mode 100644 index 000000000..ad2d56140 --- /dev/null +++ b/Widget/Resources/en.lproj/Localizable.strings @@ -0,0 +1,29 @@ +/* + Localizable.strings + NetNewsWire + + Created by Stuart Breckenridge on 21/11/2020. + Copyright © 2020 Ranchero Software. All rights reserved. +*/ + +/* Bundle */ +"Unread_Widget_Title" = "Your Unread Articles"; +"Unread_Widget_Description" = "A sneak peak at your unread articles."; + +"Today_Widget_Title" = "Your Today Articles"; +"Today_Widget_Description" = "A sneak peak at recently published unread articles."; + +"Starred_Widget_Title" = "Your Starred Articles"; +"Starred_Widget_Description" = "A sneak peak at your starred articles."; + +"SmartFeedSummary_Widget_Title" = "Your Smart Feed Summary"; +"SmartFeedSummary_Widget_Description" = "A count of your smart feeds."; + +/* Unread Widget */ +"Unread_Widget_NoItems" = "There's nothing to read right now."; + +/* Today Widget */ +"Today_Widget_NoItems" = "There are no recent articles to read."; + +/* Starred Widget */ +"Starred_Widget_NoItems" = "You've not starred any artices."; diff --git a/Widget/Widget Views/StarredWidget.swift b/Widget/Widget Views/StarredWidget.swift index 630669e23..6a4091fb2 100644 --- a/Widget/Widget Views/StarredWidget.swift +++ b/Widget/Widget Views/StarredWidget.swift @@ -69,9 +69,7 @@ struct StarredWidgetView : View { count = count - 3 } if count < 0 { count = 0 } - let formatString = NSLocalizedString("StarredCount", - comment: "Starred Count Format") - let str = String.localizedStringWithFormat(formatString, UInt(count)) + let str = L10n.unreadCount(count) return Text(str) .font(.caption2) .bold() diff --git a/Widget/Widget Views/TodayWidget.swift b/Widget/Widget Views/TodayWidget.swift index a5125552f..0c132cd53 100644 --- a/Widget/Widget Views/TodayWidget.swift +++ b/Widget/Widget Views/TodayWidget.swift @@ -69,9 +69,7 @@ struct TodayWidgetView : View { count = count - 3 } if count < 0 { count = 0 } - let formatString = NSLocalizedString("TodayCount", - comment: "Today Count Format") - let str = String.localizedStringWithFormat(formatString, UInt(count)) + let str = L10n.unreadCount(count) return Text(str) .font(.caption2) .bold() diff --git a/Widget/Widget Views/UnreadWidget.swift b/Widget/Widget Views/UnreadWidget.swift index 819e2778c..4a82a26d4 100644 --- a/Widget/Widget Views/UnreadWidget.swift +++ b/Widget/Widget Views/UnreadWidget.swift @@ -69,9 +69,7 @@ struct UnreadWidgetView : View { count = count - 3 } if count < 0 { count = 0 } - let formatString = NSLocalizedString("UnreadCount", - comment: "Unread Count Format") - let str = String.localizedStringWithFormat(formatString, UInt(count)) + let str = L10n.unreadCount(count) return Text(str) .font(.caption2) .bold() @@ -99,7 +97,7 @@ struct UnreadWidgetView : View { .frame(width: 15, height: 15, alignment: .center) .cornerRadius(4) - Text("There's nothing to read right now.") + Text(L10n.unreadWidgetNoItems) .font(.caption2) .foregroundColor(.gray) } diff --git a/Widget/WidgetBundle.swift b/Widget/WidgetBundle.swift index 3ea531f53..7e88a65d5 100644 --- a/Widget/WidgetBundle.swift +++ b/Widget/WidgetBundle.swift @@ -22,8 +22,8 @@ struct UnreadWidget: Widget { .background(Color("WidgetBackground")) }) - .configurationDisplayName("Your Unread Articles") - .description("A sneak peak at what's left unread.") + .configurationDisplayName(L10n.unreadWidgetTitle) + .description(L10n.unreadWidgetDescription) .supportedFamilies([.systemMedium, .systemLarge]) } @@ -40,8 +40,8 @@ struct TodayWidget: Widget { .background(Color("WidgetBackground")) }) - .configurationDisplayName("Your Today Articles") - .description("A sneak peak at unread recently published articles.") + .configurationDisplayName(L10n.todayWidgetTitle) + .description(L10n.todayWidgetDescription) .supportedFamilies([.systemMedium, .systemLarge]) } @@ -58,8 +58,8 @@ struct StarredWidget: Widget { .background(Color("WidgetBackground")) }) - .configurationDisplayName("Your Starred Articles") - .description("A sneak peak at your starred articles.") + .configurationDisplayName(L10n.starredWidgetTitle) + .description(L10n.starredWidgetDescription) .supportedFamilies([.systemMedium, .systemLarge]) } @@ -76,8 +76,8 @@ struct SmartFeedSummaryWidget: Widget { .background(Color("WidgetBackground")) }) - .configurationDisplayName("Your Smart Feed Summary") - .description("A count of your smart feeds.") + .configurationDisplayName(L10n.smartFeedSummaryWidgetTitle) + .description(L10n.smartFeedSummaryWidgetDescription) .supportedFamilies([.systemSmall]) }