From adadaaa31c48b6f3fa007eb48a7d8db73a5bcbe1 Mon Sep 17 00:00:00 2001 From: David Weekly Date: Tue, 31 May 2022 10:01:21 -0700 Subject: [PATCH] First stab at localization and French locale --- RedditOs.xcodeproj/project.pbxproj | 32 +++ .../xcshareddata/xcschemes/RedditOs.xcscheme | 2 + .../Search/Quick/QuickSearchBar.swift | 3 +- .../Search/Quick/QuickSearchResultsView.swift | 10 +- RedditOs/Features/Sidebar/SidebarItem.swift | 17 +- RedditOs/Shared/LoadingRow.swift | 2 +- RedditOs/en.lproj/Localizable.strings | 53 ++++ RedditOs/fr.lproj/InfoPlist.strings | 3 + RedditOs/fr.lproj/Localizable.strings | 261 ++++++++++++++++++ 9 files changed, 372 insertions(+), 11 deletions(-) create mode 100644 RedditOs/en.lproj/Localizable.strings create mode 100644 RedditOs/fr.lproj/InfoPlist.strings create mode 100644 RedditOs/fr.lproj/Localizable.strings diff --git a/RedditOs.xcodeproj/project.pbxproj b/RedditOs.xcodeproj/project.pbxproj index d0f4b4d..6227069 100644 --- a/RedditOs.xcodeproj/project.pbxproj +++ b/RedditOs.xcodeproj/project.pbxproj @@ -71,6 +71,8 @@ 9F4812CC264FC8DB007A719D /* QuickSearchFullResultsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F4812CB264FC8DB007A719D /* QuickSearchFullResultsView.swift */; }; 9F7E75E42654102700390010 /* AVKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9F7E75E32654102700390010 /* AVKit.framework */; }; 9F8EE49126510BCF00BDE4AC /* MarkdownUI in Frameworks */ = {isa = PBXBuildFile; productRef = 9F8EE49026510BCF00BDE4AC /* MarkdownUI */; }; + DBF4737628418A0A0067D8CC /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = DBF4737428418A0A0067D8CC /* InfoPlist.strings */; }; + DBF4737928418A0A0067D8CC /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = DBF4737728418A0A0067D8CC /* Localizable.strings */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -139,6 +141,9 @@ 9F4537872652ED550026C19B /* QuickSearchPostsResultView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickSearchPostsResultView.swift; sourceTree = ""; }; 9F4812CB264FC8DB007A719D /* QuickSearchFullResultsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickSearchFullResultsView.swift; sourceTree = ""; }; 9F7E75E32654102700390010 /* AVKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVKit.framework; path = System/Library/Frameworks/AVKit.framework; sourceTree = SDKROOT; }; + DBBA8E9228419264007202FF /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; + DBF4737528418A0A0067D8CC /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; + DBF4737828418A0A0067D8CC /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -316,6 +321,8 @@ 6970A0AC24B7494C00B11031 /* Shared */, 69EACF2024B7298C00303A16 /* Features */, 69EACF0B24B63D5900303A16 /* Info.plist */, + DBF4737728418A0A0067D8CC /* Localizable.strings */, + DBF4737428418A0A0067D8CC /* InfoPlist.strings */, 69EACF0624B63D5900303A16 /* Assets.xcassets */, 69EACF0C24B63D5900303A16 /* RedditOs.entitlements */, 69EACF0824B63D5900303A16 /* Preview Content */, @@ -459,6 +466,7 @@ knownRegions = ( en, Base, + fr, ); mainGroup = 69EACEF624B63D5800303A16; packageReferences = ( @@ -480,6 +488,8 @@ buildActionMask = 2147483647; files = ( 69EACF0A24B63D5900303A16 /* Preview Assets.xcassets in Resources */, + DBF4737928418A0A0067D8CC /* Localizable.strings in Resources */, + DBF4737628418A0A0067D8CC /* InfoPlist.strings in Resources */, 69EACF0724B63D5900303A16 /* Assets.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -553,6 +563,26 @@ }; /* End PBXSourcesBuildPhase section */ +/* Begin PBXVariantGroup section */ + DBF4737428418A0A0067D8CC /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + DBF4737528418A0A0067D8CC /* fr */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + DBF4737728418A0A0067D8CC /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + DBF4737828418A0A0067D8CC /* fr */, + DBBA8E9228419264007202FF /* en */, + ); + name = Localizable.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + /* Begin XCBuildConfiguration section */ 69EACF0D24B63D5900303A16 /* Debug */ = { isa = XCBuildConfiguration; @@ -611,6 +641,7 @@ ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; }; name = Debug; @@ -665,6 +696,7 @@ MTL_FAST_MATH = YES; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_OPTIMIZATION_LEVEL = "-O"; }; name = Release; diff --git a/RedditOs.xcodeproj/xcshareddata/xcschemes/RedditOs.xcscheme b/RedditOs.xcodeproj/xcshareddata/xcschemes/RedditOs.xcscheme index ee70bc3..bca862f 100644 --- a/RedditOs.xcodeproj/xcshareddata/xcschemes/RedditOs.xcscheme +++ b/RedditOs.xcodeproj/xcshareddata/xcschemes/RedditOs.xcscheme @@ -34,6 +34,8 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + language = "fr" + region = "FR" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" diff --git a/RedditOs/Features/Search/Quick/QuickSearchBar.swift b/RedditOs/Features/Search/Quick/QuickSearchBar.swift index 2758532..468106d 100644 --- a/RedditOs/Features/Search/Quick/QuickSearchBar.swift +++ b/RedditOs/Features/Search/Quick/QuickSearchBar.swift @@ -17,7 +17,8 @@ struct QuickSearchBar: View { let onCancel: () -> Void var body: some View { - SearchBarView(placeholder: "Search anything", + SearchBarView(placeholder: NSLocalizedString("Search anything", + comment: "placeholder for search"), searchText: $searchState.searchText) { editing in if showSuggestionPopover { isPopoverPresented = editing diff --git a/RedditOs/Features/Search/Quick/QuickSearchResultsView.swift b/RedditOs/Features/Search/Quick/QuickSearchResultsView.swift index 95cf749..b469f89 100644 --- a/RedditOs/Features/Search/Quick/QuickSearchResultsView.swift +++ b/RedditOs/Features/Search/Quick/QuickSearchResultsView.swift @@ -45,7 +45,7 @@ struct QuickSearchResultsView: View { } } - private func makeTitle(_ title: String) -> some View { + private func makeTitle(_ title: LocalizedStringKey) -> some View { Text(title) .font(.headline) .fontWeight(.bold) @@ -54,13 +54,17 @@ struct QuickSearchResultsView: View { private func makeQuickAccess() -> some View { ResultContainerView { QuickSearchResultRow(icon: nil, - name: "Posts with '\(searchState.searchText)'") + name: String.localizedStringWithFormat(NSLocalizedString("Posts with %@", + comment: "label showing search text"), + searchState.searchText)) .onTapGesture { uiState.searchRoute = .searchPostsResult } QuickSearchResultRow(icon: nil, - name: "Go to r/\(searchState.searchText)") + name: String.localizedStringWithFormat(NSLocalizedString("Go to r/%@", + comment: "Navigates to a given subreddit"), + searchState.searchText)) .onTapGesture { uiState.searchRoute = .subreddit(subreddit: searchState.searchText) } diff --git a/RedditOs/Features/Sidebar/SidebarItem.swift b/RedditOs/Features/Sidebar/SidebarItem.swift index 389ce32..e7252ad 100644 --- a/RedditOs/Features/Sidebar/SidebarItem.swift +++ b/RedditOs/Features/Sidebar/SidebarItem.swift @@ -18,17 +18,22 @@ enum SidebarItem: String, CaseIterable, Identifiable, Equatable { func title() -> String { switch self { case .home: - return "Home" + return NSLocalizedString("Home", + comment: "Sidebar item - navigates back to the Home screen") case .account: - return "Account" + return NSLocalizedString("Account", + comment: "Sidebar item - navigates to the Account screen") case .favorites: - return "Favorites" + return NSLocalizedString("Favorites", + comment: "Sidebar item - navigates to the Favorites screen") case .recentlyVisited: - return "Recently Visited" + return NSLocalizedString("Recently Visited", + comment: "Sidebar item - navigates to Recently Visited screen") case .subscription: - return "Subscriptions" + return NSLocalizedString("Subscriptions", + comment: "Sidebar item - navigates to the Subscriptions screen") case .multi: - return "Multireddits" + return "Multireddits" // VERBATIM, no localization } } } diff --git a/RedditOs/Shared/LoadingRow.swift b/RedditOs/Shared/LoadingRow.swift index a39e825..f0c3ab0 100644 --- a/RedditOs/Shared/LoadingRow.swift +++ b/RedditOs/Shared/LoadingRow.swift @@ -8,7 +8,7 @@ import SwiftUI struct LoadingRow: View { - let text: String? + let text: LocalizedStringKey? var body: some View { HStack { diff --git a/RedditOs/en.lproj/Localizable.strings b/RedditOs/en.lproj/Localizable.strings new file mode 100644 index 0000000..0cafbbf --- /dev/null +++ b/RedditOs/en.lproj/Localizable.strings @@ -0,0 +1,53 @@ +/* No comment provided by engineer. */ +"Reply" = "Reply"; + +/* No comment provided by engineer. */ +"Share" = "Share"; + +/* No comment provided by engineer. */ +"Save" = "Save"; + +/* No comment provided by engineer. */ +"Report" = "Report"; + +/* No comment provided by engineer. */ +"Saved" = "Saved"; + +/* No comment provided by engineer. */ +"Overview" = "Overview"; + +/* No comment provided by engineer. */ +"Awards" = "Awards"; + +/* No comment provided by engineer. */ +"Profile" = "Profile"; + +/* No comment provided by engineer. */ +"Inbox" = "Inbox"; + +/* No comment provided by engineer. */ +"Posts" = "Posts"; + +/* No comment provided by engineer. */ +"Comments" = "Comments"; + +/* When search fails for a given search string */ +"No matching subscriptions for %@" = "No matching subscriptions for %@"; + +/* A count of the number of comments */ +"%d comments" = "%d comments"; + +/* Home Sidebar: navigates to posts that are 'hot' or popular */ +"Hot" = "Hot"; + +/* Home Sidebar: navigates to newest posts */ +"New" = "New"; + +/* Home Sidebar: navigates to best posts */ +"Best" = "Best"; + +/* Home Sidebar: navigates to top posts */ +"Top" = "Top"; + +/* Home Sidebar: navigates to rising posts */ +"Rising" = "Rising"; diff --git a/RedditOs/fr.lproj/InfoPlist.strings b/RedditOs/fr.lproj/InfoPlist.strings new file mode 100644 index 0000000..1be8004 --- /dev/null +++ b/RedditOs/fr.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "Curiosité"; + diff --git a/RedditOs/fr.lproj/Localizable.strings b/RedditOs/fr.lproj/Localizable.strings new file mode 100644 index 0000000..b56e170 --- /dev/null +++ b/RedditOs/fr.lproj/Localizable.strings @@ -0,0 +1,261 @@ +/* No comment provided by engineer. */ +" · %@ points · " = " · %@ points ·"; + +/* No comment provided by engineer. */ +" Created " = " Établi"; + +/* No comment provided by engineer. */ +"%@" = "%@"; + +/* A count of the number of comments */ +"%d comments" = "%d commentaires"; + +/* No comment provided by engineer. */ +"%lld" = "%lld"; + +/* No comment provided by engineer. */ +"%lld comments" = "%lld commentaires"; + +/* No comment provided by engineer. */ +"About Community" = "À propos de la communauté"; + +/* Sidebar item - navigates to the Account screen */ +"Account" = "Compte"; + +/* No comment provided by engineer. */ +"Accounts" = "Comptes"; + +/* No comment provided by engineer. */ +"Auth in progress" = "Authentification en cours"; + +/* No comment provided by engineer. */ +"Awards" = "Prix"; + +/* No comment provided by engineer. */ +"Back" = "Retour"; + +/* Home Sidebar: navigates to best posts */ +"Best" = "Meilleur"; + +/* No comment provided by engineer. */ +"Close" = "Ferme"; + +/* No comment provided by engineer. */ +"Comments" = "Commentaires"; + +/* No comment provided by engineer. */ +"Copy oauth token to pasteboard" = "Copier le jeton oauth dans le presse-papiers"; + +/* No comment provided by engineer. */ +"Copy URL" = "Copier le lien"; + +/* No comment provided by engineer. */ +"Debug" = "Déboguer"; + +/* No comment provided by engineer. */ +"Default Subreddit settings" = "Paramètres de sous-reddit par défaut"; + +/* No comment provided by engineer. */ +"Deleted comment" = "Commentaire supprimé"; + +/* No comment provided by engineer. */ +"Deleted user" = "Utilisateur supprimé"; + +/* No comment provided by engineer. */ +"Display layout" = "Disposition de l'affichage"; + +/* No comment provided by engineer. */ +"Display layout style" = "Style de mise en page de l'affichage"; + +/* No comment provided by engineer. */ +"Downvote" = "Voter contre"; + +/* Sidebar item - navigates to the Favorites screen */ +"Favorites" = "Favoris"; + +/* No comment provided by engineer. */ +"Filters" = "Filtres"; + +/* No comment provided by engineer. */ +"General" = "Général"; + +/* Navigates to a given subreddit */ +"Go to r/%@" = "Allez à r/%@"; + +/* Sidebar item - navigates back to the Home screen */ +"Home" = "Maison"; + +/* Home Sidebar: navigates to posts that are 'hot' or popular */ +"Hot" = "Chaud"; + +/* No comment provided by engineer. */ +"Inbox" = "Boîte de réception"; + +/* No comment provided by engineer. */ +"Loading next page" = "Chargement de la page suivante"; + +/* No comment provided by engineer. */ +"Loading user" = "Chargement de l'utilisateur"; + +/* No comment provided by engineer. */ +"Logout" = "Se déconnecter"; + +/* No comment provided by engineer. */ +"Members" = "Membres"; + +/* No comment provided by engineer. */ +"My subscriptions" = "Mes abonnements"; + +/* Home Sidebar: navigates to newest posts */ +"New" = "Nouveau"; + +/* No comment provided by engineer. */ +"No matching search for %@" = "Aucune recherche correspondante pour %@"; + +/* When search fails for a given search string */ +"No matching subscriptions for %@" = "Aucun abonnement correspondant pour %@"; + +/* No comment provided by engineer. */ +"No post selected" = "Aucune publication sélectionnée"; + +/* No comment provided by engineer. */ +"Online" = "En ligne"; + +/* No comment provided by engineer. */ +"Open in browser" = "Ouvrir dans le navigateur"; + +/* No comment provided by engineer. */ +"Overview" = "Aperçu"; + +/* No comment provided by engineer. */ +"Post" = "Poste"; + +/* No comment provided by engineer. */ +"Posts" = "Des postes"; + +/* label showing search text */ +"Posts with %@" = "Messages avec %@"; + +/* No comment provided by engineer. */ +"Profile" = "Profil"; + +/* No comment provided by engineer. */ +"Quick access" = "Accès rapide"; + +/* No comment provided by engineer. */ +"r/%@" = "r/%@"; + +/* Sidebar item - navigates to Recently Visited screen */ +"Recently Visited" = "Récemment visité"; + +/* No comment provided by engineer. */ +"Refresh" = "Rafraîchir"; + +/* No comment provided by engineer. */ +"Refresh comments" = "Actualiser les commentaires"; + +/* No comment provided by engineer. */ +"Reply" = "Réponse"; + +/* No comment provided by engineer. */ +"Report" = "Signaler"; + +/* Home Sidebar: navigates to rising posts */ +"Rising" = "En hausse"; + +/* No comment provided by engineer. */ +"Save" = "Sauvegarder"; + +/* No comment provided by engineer. */ +"Saved" = "Enregistré"; + +/* No comment provided by engineer. */ +"Search" = "Chercher"; + +/* placeholder for search */ +"Search anything" = "Rechercher n'importe quoi"; + +/* No comment provided by engineer. */ +"Searching..." = "Recherche..."; + +/* No comment provided by engineer. */ +"Select display layout style" = "Sélectionnez le style de mise en page de l'affichage"; + +/* No comment provided by engineer. */ +"Share" = "Partager"; + +/* No comment provided by engineer. */ +"Sidebar" = "Barre latérale"; + +/* No comment provided by engineer. */ +"Sidebar items" = "Éléments de la barre latérale"; + +/* No comment provided by engineer. */ +"Sign in" = "S'identifier"; + +/* No comment provided by engineer. */ +"Signed in" = "Connecté"; + +/* No comment provided by engineer. */ +"Sort by" = "Trier par"; + +/* No comment provided by engineer. */ +"Sort order" = "Ordre de tri"; + +/* No comment provided by engineer. */ +"Sorting" = "Tri"; + +/* No comment provided by engineer. */ +"Submitted" = "Soumis"; + +/* No comment provided by engineer. */ +"Subreddit" = "Sous-reddit"; + +/* No comment provided by engineer. */ +"Subreddit search" = "Recherche de sous-reddit"; + +/* No comment provided by engineer. */ +"Subscribe" = "S'abonner"; + +/* No comment provided by engineer. */ +"Subscribe?" = "S'abonner?"; + +/* No comment provided by engineer. */ +"Subscribed" = "Abonné"; + +/* No comment provided by engineer. */ +"Subscribers: %lld" = "Abonnés : %lld"; + +/* Sidebar item - navigates to the Subscriptions screen */ +"Subscriptions" = "Abonnements"; + +/* No comment provided by engineer. */ +"Toggle favorite" = "Basculer en favori"; + +/* Home Sidebar: navigates to top posts */ +"Top" = "Haut"; + +/* No comment provided by engineer. */ +"Trending" = "Tendance"; + +/* No comment provided by engineer. */ +"u/%@" = "u/%@"; + +/* No comment provided by engineer. */ +"Unsave" = "Annuler l'enregistrement"; + +/* No comment provided by engineer. */ +"Unsubscribe?" = "Se désabonner?"; + +/* No comment provided by engineer. */ +"Unsupported view" = "Vue non prise en charge"; + +/* No comment provided by engineer. */ +"Upvote" = "Vote positif"; + +/* No comment provided by engineer. */ +"User since" = "Utilisateur depuis"; + +/* No comment provided by engineer. */ +"View full profile" = "Voir le profil complet"; +