diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 426c789b8..25840d268 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,6 +33,9 @@ jobs: # /!\ important: this checks out code from the HEAD of the PR instead of the main branch (for pull_request_target) ref: ${{ github.event.pull_request.head.sha || github.ref }} + - name: Validate localizations + run: python localizations.py validate + - name: Add Apple Store Key run: echo "${{ secrets.APPLE_STORE_AUTH_KEY }}" | base64 --decode -o ${{ env.APPLE_STORE_AUTH_KEY_PATH}} diff --git a/.gitignore b/.gitignore index a31fd4e7f..a0bd06a35 100644 --- a/.gitignore +++ b/.gitignore @@ -81,4 +81,7 @@ Brewfile.lock.json # this is CI specific Brewfile_CI -Brewfile_CI.lock.json \ No newline at end of file +Brewfile_CI.lock.json + +# Generated localization swift file: +Support/LocalString.swift \ No newline at end of file diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index efbfe30f9..7bb3fdb89 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,6 +3,12 @@ default_install_hook_types: [post-merge, post-checkout, post-rewrite] repos: - repo: local hooks: + - id: generate_localizations + name: "Generate localization swift file" + entry: python localizations.py generate + language: python + always_run: true + stages: [post-checkout, post-merge, post-rewrite] - id: xcodegen name: Generate project files for Xcode description: "Generate project file for Xcode" diff --git a/.swiftlint.yml b/.swiftlint.yml index e75411cc2..3db242d9d 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -1,4 +1,6 @@ disabled_rules: - trailing_whitespace included: - - Views/Settings/ \ No newline at end of file + - Views/Settings/ +excluded: + - Support/LocalString.swift diff --git a/App/App_macOS.swift b/App/App_macOS.swift index 52bee99e9..1c8ebf926 100644 --- a/App/App_macOS.swift +++ b/App/App_macOS.swift @@ -52,10 +52,10 @@ struct Kiwix: App { }.commands { SidebarCommands() CommandGroup(replacing: .importExport) { - OpenFileButton(context: .command) { Text("app_macos_commands.open_file".localized) } + OpenFileButton(context: .command) { Text(LocalString.app_macos_commands_open_file) } } CommandGroup(replacing: .newItem) { - Button("app_macos_commands.new".localized) { + Button(LocalString.app_macos_commands_new) { guard let currentWindow = NSApp.keyWindow, let controller = currentWindow.windowController else { return } controller.newWindowForTab(nil) @@ -85,7 +85,7 @@ struct Kiwix: App { } .frame(width: 550, height: 400) } - Window("payment.donate.title".localized, id: "donation") { + Window(LocalString.payment_donate_title, id: "donation") { Group { if let selectedAmount { PaymentSummary(selectedAmount: selectedAmount, onComplete: { @@ -187,7 +187,7 @@ struct RootView: View { Label(navigationItem.name, systemImage: navigationItem.icon) } if FeatureFlags.hasLibrary { - Section("app_macos_navigation.button.library".localized) { + Section(LocalString.app_macos_navigation_button_library) { ForEach(libraryItems, id: \.self) { navigationItem in Label(navigationItem.name, systemImage: navigationItem.icon) } diff --git a/App/CompactViewController.swift b/App/CompactViewController.swift index 0d6984780..6af264996 100644 --- a/App/CompactViewController.swift +++ b/App/CompactViewController.swift @@ -84,7 +84,7 @@ final class CompactViewController: UIHostingController, UISearchControl searchController.delegate = self searchController.hidesNavigationBarDuringPresentation = false searchController.showsSearchResultsController = true - searchController.searchBar.searchTextField.placeholder = "common.search".localized + searchController.searchBar.searchTextField.placeholder = LocalString.common_search searchTextObserver = searchViewModel.$searchText.sink { [weak self] searchText in guard self?.searchController.searchBar.text != searchText else { return } @@ -107,7 +107,7 @@ final class CompactViewController: UIHostingController, UISearchControl trailingNavItemGroups = navigationItem.trailingItemGroups navigationItem.setRightBarButton( UIBarButtonItem( - title: "common.button.cancel".localized, + title: LocalString.common_button_cancel, style: .done, target: self, action: #selector(onSearchCancelled) @@ -185,14 +185,14 @@ private struct CompactView: View { Button { presentedSheet = .library } label: { - Label("common.tab.menu.library".localized, systemImage: "folder") + Label(LocalString.common_tab_menu_library, systemImage: "folder") } Spacer() } Button { presentedSheet = .settings } label: { - Label("common.tab.menu.settings".localized, systemImage: "gear") + Label(LocalString.common_tab_menu_settings, systemImage: "gear") } Spacer() } @@ -209,7 +209,7 @@ private struct CompactView: View { Button { self.presentedSheet = nil } label: { - Text("common.button.done".localized).fontWeight(.semibold) + Text(LocalString.common_button_done).fontWeight(.semibold) } } } @@ -285,7 +285,7 @@ private struct Content: View where LaunchModel: LaunchProtocol { } .toolbar { ToolbarItemGroup(placement: .primaryAction) { - Button("article_shortcut.random.button.title.ios".localized, + Button(LocalString.article_shortcut_random_button_title_ios, systemImage: "die.face.5", action: { browser.loadRandomArticle() }) .disabled(zimFiles.isEmpty) diff --git a/App/SidebarViewController.swift b/App/SidebarViewController.swift index 1e600a16c..3ccf8d98f 100644 --- a/App/SidebarViewController.swift +++ b/App/SidebarViewController.swift @@ -105,7 +105,7 @@ class SidebarViewController: UICollectionViewController, NSFetchedResultsControl }, menu: UIMenu(children: [ UIAction( - title: "sidebar_view.navigation.button.close".localized, + title: LocalString.sidebar_view_navigation_button_close, image: UIImage(systemName: "xmark.square"), attributes: .destructive ) { [unowned self] _ in @@ -114,7 +114,7 @@ class SidebarViewController: UICollectionViewController, NSFetchedResultsControl navigationViewModel.deleteTab(tabID: tabID) }, UIAction( - title: "sidebar_view.navigation.button.close_all".localized, + title: LocalString.sidebar_view_navigation_button_close_all, image: UIImage(systemName: "xmark.square.fill"), attributes: .destructive ) { [unowned self] _ in @@ -196,7 +196,7 @@ class SidebarViewController: UICollectionViewController, NSFetchedResultsControl if case let .tab(objectID) = item, let tab = try? Database.shared.viewContext.existingObject(with: objectID) as? Tab { var config = cell.defaultContentConfiguration() - config.text = tab.title ?? "common.tab.menu.new_tab".localized + config.text = tab.title ?? LocalString.common_tab_menu_new_tab if let zimFile = tab.zimFile, let category = Category(rawValue: zimFile.category) { config.textProperties.numberOfLines = 1 if let imgData = zimFile.faviconData { @@ -224,11 +224,11 @@ class SidebarViewController: UICollectionViewController, NSFetchedResultsControl switch section { case .tabs: var config = UIListContentConfiguration.sidebarHeader() - config.text = "common.tab.navigation.title".localized + config.text = LocalString.common_tab_navigation_title headerView.contentConfiguration = config case .library: var config = UIListContentConfiguration.sidebarHeader() - config.text = "common.tab.menu.library".localized + config.text = LocalString.common_tab_menu_library headerView.contentConfiguration = config default: headerView.contentConfiguration = nil @@ -239,7 +239,7 @@ class SidebarViewController: UICollectionViewController, NSFetchedResultsControl guard let navigationViewModel, let item = dataSource.itemIdentifier(for: indexPath), case let .tab(tabID) = item else { return nil } - let title = "sidebar_view.navigation.button.close".localized + let title = LocalString.sidebar_view_navigation_button_close let action = UIContextualAction(style: .destructive, title: title) { [weak navigationViewModel] _, _, _ in navigationViewModel?.deleteTab(tabID: tabID) diff --git a/Brewfile b/Brewfile index 6cbcdcbcb..0188c8609 100644 --- a/Brewfile +++ b/Brewfile @@ -9,5 +9,6 @@ at_exit do system "cp Support/CoreKiwix.modulemap CoreKiwix.xcframework/ios-arm64/Headers/module.modulemap" system "cp Support/CoreKiwix.modulemap CoreKiwix.xcframework/ios-arm64_x86_64-simulator/Headers/module.modulemap" system "cp Support/CoreKiwix.modulemap CoreKiwix.xcframework/macos-arm64_x86_64/Headers/module.modulemap" + system "python localizations.py generate" system "xcodegen" end diff --git a/Model/Brand.swift b/Model/Brand.swift index 26a8c636a..54086b575 100644 --- a/Model/Brand.swift +++ b/Model/Brand.swift @@ -49,7 +49,7 @@ enum Brand { static let loadingLogoImage: String = "welcomeLogo" static var loadingLogoSize: CGSize = ImageInfo.sizeOf(imageName: loadingLogoImage)! - static let aboutText: String = Config.value(for: .aboutText) ?? "settings.about.description".localized + static let aboutText: String = Config.value(for: .aboutText) ?? LocalString.settings_about_description static let aboutWebsite: String = Config.value(for: .aboutWebsite) ?? "https://www.kiwix.org" // currently only used under the Kiwix brand // if this is set to true in Support/Info.plist the support/donation button is hidden (for macOS FTP) diff --git a/Model/DownloadService.swift b/Model/DownloadService.swift index 4bc9ae3fc..d0d932a72 100644 --- a/Model/DownloadService.swift +++ b/Model/DownloadService.swift @@ -254,10 +254,10 @@ final class DownloadService: NSObject, URLSessionDelegate, URLSessionTaskDelegat Database.shared.performBackgroundTask { context in // configure notification content let content = UNMutableNotificationContent() - content.title = "download_service.complete.title".localized + content.title = LocalString.download_service_complete_title content.sound = .default if let zimFile = try? context.fetch(ZimFile.fetchRequest(fileID: zimFileID)).first { - content.body = "download_service.complete.description".localizedWithFormat(withArgs: zimFile.name) + content.body = LocalString.download_service_complete_description(withArgs: zimFile.name) } // schedule notification diff --git a/Model/Entities/Errors.swift b/Model/Entities/Errors.swift index d699ed14c..1dcfeeb17 100644 --- a/Model/Entities/Errors.swift +++ b/Model/Entities/Errors.swift @@ -23,12 +23,12 @@ public enum LibraryRefreshError: LocalizedError { public var errorDescription: String? { switch self { case .retrieve(let description): - let prefix = "library_refresh_error.retrieve.description".localizedWith(comment: "Library Refresh Error") + let prefix = LocalString.library_refresh_error_retrieve_description return [prefix, description].compactMap({ $0 }).joined(separator: " ") case .parse: - return "library_refresh_error.parse.description".localizedWith(comment: "Library Refresh Error") + return LocalString.library_refresh_error_parse_description case .process: - return "library_refresh_error.process.description".localizedWith(comment: "Library Refresh Error") + return LocalString.library_refresh_error_process_description } } } diff --git a/Model/Payment.swift b/Model/Payment.swift index 2e76e87cc..7c4fc9626 100644 --- a/Model/Payment.swift +++ b/Model/Payment.swift @@ -146,8 +146,8 @@ struct Payment { request.supportedNetworks = Self.supportedNetworks request.requiredBillingContactFields = [.emailAddress] let recurring: PKRecurringPaymentRequest? = if selectedAmount.isMonthly { - PKRecurringPaymentRequest(paymentDescription: "payment.description.label".localized, - regularBilling: .init(label: "payment.monthly_support.label".localized, + PKRecurringPaymentRequest(paymentDescription: LocalString.payment_description_label, + regularBilling: .init(label: LocalString.payment_monthly_support_label, amount: NSDecimalNumber(value: selectedAmount.value), type: .final), managementURL: URL(string: Self.paymentSubscriptionManagingURL)!) @@ -157,7 +157,7 @@ struct Payment { request.recurringPaymentRequest = recurring request.paymentSummaryItems = [ PKPaymentSummaryItem( - label: "payment.summary.title".localized, + label: LocalString.payment_summary_title, amount: NSDecimalNumber(value: selectedAmount.value), type: .final ) diff --git a/Model/Utilities/String+Extension.swift b/Model/Utilities/String+Extension.swift index 148ac5167..7fcdc86cc 100644 --- a/Model/Utilities/String+Extension.swift +++ b/Model/Utilities/String+Extension.swift @@ -17,46 +17,6 @@ import Foundation extension String { - var localized: String { - localizedWithFallback() - } - - func localizedWith(comment: String) -> String { - localizedWithFallback(comment: comment) - } - - func localizedWithFormat(withArgs: CVarArg...) -> String { - let format = localizedWithFallback() - switch withArgs.count { - case 1: return String.localizedStringWithFormat(format, withArgs[0]) - case 2: return String.localizedStringWithFormat(format, withArgs[0], withArgs[1]) - default: return String.localizedStringWithFormat(format, withArgs) - } - } - - private func localizedWithFallback( - bundle: Bundle = Bundle.main, - comment: String = "" - ) -> String { - let englishValue: String - if let path = Bundle.main.path(forResource: "en", ofType: "lproj"), - let bundle = Bundle(path: path) { - englishValue = NSLocalizedString(self, bundle: bundle, comment: comment) - if NSLocale.preferredLanguages.first == "en" { - return englishValue - } - } else { - englishValue = "" - } - return NSLocalizedString( - self, - tableName: nil, - bundle: bundle, - value: englishValue, // fall back to this, if translation not found - comment: comment - ) - } - func removingPrefix(_ value: String) -> String { guard hasPrefix(value) else { return self } return String(dropFirst(value.count)) diff --git a/Support/StringLocalExtension.swift_temp b/Support/StringLocalExtension.swift_temp new file mode 100644 index 000000000..feda4b7f5 --- /dev/null +++ b/Support/StringLocalExtension.swift_temp @@ -0,0 +1,56 @@ +// This file is part of Kiwix for iOS & macOS. +// +// Kiwix is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// any later version. +// +// Kiwix is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Kiwix; If not, see https://www.gnu.org/licenses/. + +import Foundation + +fileprivate extension String { + + var localized: String { + localizedWithFallback() + } + + func localizedWithFormat(withArgs: CVarArg...) -> String { + let format = localizedWithFallback() + switch withArgs.count { + case 1: return String.localizedStringWithFormat(format, withArgs[0]) + case 2: return String.localizedStringWithFormat(format, withArgs[0], withArgs[1]) + default: return String.localizedStringWithFormat(format, withArgs) + } + } + + private func localizedWithFallback( + bundle: Bundle = Bundle.main, + comment: String = "" + ) -> String { + let englishValue: String + if let path = Bundle.main.path(forResource: "en", ofType: "lproj"), + let bundle = Bundle(path: path) { + englishValue = NSLocalizedString(self, bundle: bundle, comment: comment) + if NSLocale.preferredLanguages.first == "en" { + return englishValue + } + } else { + englishValue = "" + } + return NSLocalizedString( + self, + tableName: nil, + bundle: bundle, + value: englishValue, // fall back to this, if translation not found + comment: comment + ) + } +} + diff --git a/Support/br.lproj/Localizable.strings b/Support/br.lproj/Localizable.strings index 7eee9b033..3e6ae8f7e 100644 --- a/Support/br.lproj/Localizable.strings +++ b/Support/br.lproj/Localizable.strings @@ -29,7 +29,6 @@ "common.tab.list.close" = "Serriñ ar steudenn"; "common.tab.menu.library" = "Levraoueg"; "common.tab.menu.settings" = "Arventennoù"; -"common.support.app_name" = "Skoazellañ %@"; "common.export_file.alert.title" = "Ezporzhiañ ar restr"; "common.export_file.alert.description" = "Fellout a ra deoc'h ezporzhiañ ar restr %@?"; "common.export_file.alert.button.title" = "Ezporzhiañ"; @@ -51,7 +50,7 @@ "flavor_tag.help.no_pic" = "lamet eo bet darn vrasañ ar skeudennoù"; "library_refresh_time.last" = "Nevez zo"; "library_refresh_time.never" = "James"; -"zim_file_cell_article_count_suffix" = "pennadoù"; +"zim_file_cell.article_count.suffix" = "pennadoù"; "zim_file_missing_indicator.help" = "Ar restr ZIM a vank."; "library.zim_file_context.main_page.label" = "Degemer"; "library.zim_file_context.random.label" = "Pajenn dre zegouezh"; @@ -65,7 +64,7 @@ "zim_file_category.section.empty.message" = "Restr ZIM ebet er rummad-mañ."; "zim_file_downloads.toolbar.show_sidebar.label" = "Diskouez ar varrenn-gostez"; "zim_file_new_overlay.empty" = "Restr ZIM nevez ebet"; -"zim_file_new_button_refresh" = "Freskaat"; +"zim_file_new.button.refresh" = "Freskaat"; "zim_file.list.name.text" = "Anv"; "zim_file.list.description.text" = "Deskrivadur"; "zim_file.list.actions.text" = "Oberoù"; @@ -144,7 +143,6 @@ "app_macos_commands.open_file" = "Digeriñ..."; "app_macos_commands.new" = "Steudenn nevez"; "app_macos_navigation.button.library" = "Levraoueg"; -"app_macos_navigation.show_sidebar" = "Diskouez ar varrenn-gostez"; "sidebar_view.navigation.button.close" = "Serriñ"; "sidebar_view.navigation.button.close_all" = "Serriñ an holl steudennoù"; "enum.category.wikipedia" = "Wikipedia"; diff --git a/Support/dag.lproj/Localizable.strings b/Support/dag.lproj/Localizable.strings index 703c1a1c7..314f9c31c 100644 --- a/Support/dag.lproj/Localizable.strings +++ b/Support/dag.lproj/Localizable.strings @@ -54,7 +54,7 @@ "flavor_tag.help.mini" = "Sabbu ŋɔ bela koŋko nyɛ din be ni, di yi pa shɛli tuuli yaɣili"; "library_refresh_time.last" = "Kulla saha ŋɔ"; "library_refresh_time.never" = "Abada"; -"zim_file_cell_article_count_suffix" = "Lahabaya"; +"zim_file_cell.article_count.suffix" = "Lahabaya"; "zim_file_missing_indicator.help" = "Zim fasara nyɛla din kani."; // Fuzzy "library.zim_file_details.side_panel.message" = "Piimi zim fasara n- nya bayana"; @@ -71,7 +71,7 @@ "zim_file_downloads.overlay.empty.message" = "Deebu tuma nima kani"; "zim_file_downloads.toolbar.show_sidebar.label" = "Wuhimi \"Sidebar\""; "zim_file_new_overlay.empty" = "Zim fasara palli kani"; -"zim_file_new_button_refresh" = "Kahigi"; +"zim_file_new.button.refresh" = "Kahigi"; "zim_file.list.name.text" = "Yuli"; "zim_file.list.description.text" = "Buɣisibu"; "zim_file.list.actions.text" = "Niŋsim"; diff --git a/Support/de.lproj/Localizable.strings b/Support/de.lproj/Localizable.strings index 2e5de623d..39f870c13 100644 --- a/Support/de.lproj/Localizable.strings +++ b/Support/de.lproj/Localizable.strings @@ -33,7 +33,6 @@ "common.tab.list.close" = "Tab schließen"; "common.tab.menu.library" = "Bibliothek"; "common.tab.menu.settings" = "Einstellungen"; -"common.support.app_name" = "%@ unterstützen"; "outline_button.outline.title" = "Gliederung"; "outline_button.outline.help" = "Artikelgliederung anzeigen"; "outline_button.outline.empty.message" = "Keine Gliederung vorhanden"; @@ -62,7 +61,7 @@ "flavor_tag.help.mini" = "Es ist nur ein Teil des Textes verfügbar, wahrscheinlich der erste Abschnitt"; "library_refresh_time.last" = "Soeben"; "library_refresh_time.never" = "Niemals"; -"zim_file_cell_article_count_suffix" = "Artikel"; +"zim_file_cell.article_count.suffix" = "Artikel"; "zim_file_missing_indicator.help" = "Zim-Datei fehlt."; "library.zim_file_details.side_panel.message" = "Wähle eine ZIM-Datei aus, um Details zu sehen"; "library.zim_file_context.main_page.label" = "Hauptseite"; @@ -80,7 +79,7 @@ "zim_file_downloads.toolbar.show_sidebar.label" = "Seitenleiste anzeigen"; // Fuzzy "zim_file_new_overlay.empty" = "Keine neue ZIM-Datei"; -"zim_file_new_button_refresh" = "Aktualisieren"; +"zim_file_new.button.refresh" = "Aktualisieren"; "zim_file.list.name.text" = "Name"; "zim_file.list.description.text" = "Beschreibung"; "zim_file.list.actions.text" = "Aktionen"; @@ -196,7 +195,6 @@ "app_macos_commands.open_file" = "Öffnen…"; "app_macos_commands.new" = "Neuer Tab"; "app_macos_navigation.button.library" = "Bibliothek"; -"app_macos_navigation.show_sidebar" = "Seitenleiste anzeigen"; "sidebar_view.navigation.button.close" = "Schließen"; "sidebar_view.navigation.button.close_all" = "Alle Tabs schließen"; "enum.category.wikipedia" = "Wikipedia"; diff --git a/Support/en.lproj/Localizable.strings b/Support/en.lproj/Localizable.strings index 9289bdf45..031bed465 100644 --- a/Support/en.lproj/Localizable.strings +++ b/Support/en.lproj/Localizable.strings @@ -49,7 +49,6 @@ "common.tab.list.close" = "Close Tab"; "common.tab.menu.library" = "Library"; "common.tab.menu.settings" = "Settings"; -"common.support.app_name" = "Support %@"; "common.export_file.alert.title" = "Export file"; "common.export_file.alert.description" = "Do you want to export the file %@?"; "common.export_file.alert.button.title" = "Export"; @@ -91,7 +90,7 @@ "library_refresh_time.last" = "Just Now"; "library_refresh_time.never" = "Never"; -"zim_file_cell_article_count_suffix" = "articles"; +"zim_file_cell.article_count.suffix" = "articles"; "zim_file_missing_indicator.help" = "Zim file is missing."; @@ -113,7 +112,7 @@ "zim_file_downloads.toolbar.show_sidebar.label" = "Show Sidebar"; "zim_file_new_overlay.empty" = "No new ZIM file"; -"zim_file_new_button_refresh" = "Refresh"; +"zim_file_new.button.refresh" = "Refresh"; "zim_file.list.name.text" = "Name"; "zim_file.list.description.text" = "Description"; @@ -234,9 +233,7 @@ "app_macos_commands.open_file" = "Open..."; "app_macos_commands.new" = "New Tab"; "app_macos_navigation.button.library" = "Library"; -"app_macos_navigation.show_sidebar" = "Show Sidebar"; -"sidebar_view.navigation.button.close" = "Close This Tab"; "sidebar_view.navigation.button.close_all" = "Close All Tabs"; "sidebar_view.navigation.button.close" = "Close"; diff --git a/Support/es.lproj/Localizable.strings b/Support/es.lproj/Localizable.strings index 43efeedf8..d797a2110 100644 --- a/Support/es.lproj/Localizable.strings +++ b/Support/es.lproj/Localizable.strings @@ -34,7 +34,6 @@ "common.tab.list.close" = "Cerrar pestaña"; "common.tab.menu.library" = "Biblioteca"; "common.tab.menu.settings" = "Configuración"; -"common.support.app_name" = "%@ de apoyo"; "common.export_file.alert.title" = "Exportar archivo"; "common.export_file.alert.description" = "¿Quieres exportar el archivo %@?"; "common.export_file.alert.button.title" = "Exportar"; @@ -65,7 +64,7 @@ "flavor_tag.help.mini" = "Sólo está disponible un subconjunto del texto, probablemente la primera sección."; "library_refresh_time.last" = "Ahora mismo"; "library_refresh_time.never" = "Nunca"; -"zim_file_cell_article_count_suffix" = "artículos"; +"zim_file_cell.article_count.suffix" = "artículos"; "zim_file_missing_indicator.help" = "Falta el archivo Zim."; "library.zim_file_details.side_panel.message" = "Seleccione un archivo ZIM para ver los detalles"; "library.zim_file_context.main_page.label" = "Página principal"; @@ -82,7 +81,7 @@ "zim_file_downloads.overlay.empty.message" = "Sin tareas de descarga"; "zim_file_downloads.toolbar.show_sidebar.label" = "Mostrar barra lateral"; "zim_file_new_overlay.empty" = "No hay un nuevo archivo ZIM"; -"zim_file_new_button_refresh" = "Actualizar"; +"zim_file_new.button.refresh" = "Actualizar"; "zim_file.list.name.text" = "Nombre"; "zim_file.list.description.text" = "Descripción"; "zim_file.list.actions.text" = "Acciones"; @@ -194,7 +193,6 @@ "app_macos_commands.open_file" = "Abrir..."; "app_macos_commands.new" = "Pestaña nueva"; "app_macos_navigation.button.library" = "Biblioteca"; -"app_macos_navigation.show_sidebar" = "Mostrar barra lateral"; "sidebar_view.navigation.button.close" = "Cerrar"; "sidebar_view.navigation.button.close_all" = "Cerrar todas las pestañas"; "enum.category.wikipedia" = "Wikipedia"; diff --git a/Support/fi.lproj/Localizable.strings b/Support/fi.lproj/Localizable.strings index 7a3df653b..333e04b99 100644 --- a/Support/fi.lproj/Localizable.strings +++ b/Support/fi.lproj/Localizable.strings @@ -23,7 +23,6 @@ "common.tab.list.close" = "Sulje välilehti"; "common.tab.menu.library" = "Kirjasto"; "common.tab.menu.settings" = "Asetukset"; -"common.support.app_name" = "Tue %@"; "common.export_file.alert.title" = "Vie tiedosto"; "common.export_file.alert.description" = "Haluatko viedä tiedoston %@?"; "article_shortcut.main.button.title" = "Pääartikkeli"; @@ -41,7 +40,7 @@ "download_task_cell.status.downloading" = "Ladataan..."; "download_task_cell.status.paused" = "Pysäytetty"; "library_refresh_time.never" = "Ei koskaan"; -"zim_file_cell_article_count_suffix" = "artikkelia"; +"zim_file_cell.article_count.suffix" = "artikkelia"; "zim_file_missing_indicator.help" = "Zim-tiedosto puuttuu."; "library.zim_file_context.main_page.label" = "Etusivu"; "library.zim_file_context.random.label" = "Satunnainen sivu"; @@ -109,7 +108,6 @@ "app_macos_commands.open_file" = "Avaa..."; "app_macos_commands.new" = "Uusi välilehti"; "app_macos_navigation.button.library" = "Kirjasto"; -"app_macos_navigation.show_sidebar" = "Näytä sivupalkki"; "sidebar_view.navigation.button.close" = "Sulje"; "sidebar_view.navigation.button.close_all" = "Sulje kaikki välilehdet"; "enum.category.wikibooks" = "Wikikirjasto"; diff --git a/Support/fr.lproj/Localizable.strings b/Support/fr.lproj/Localizable.strings index a7c2433ed..8f9286e7a 100644 --- a/Support/fr.lproj/Localizable.strings +++ b/Support/fr.lproj/Localizable.strings @@ -44,7 +44,6 @@ "common.tab.list.close" = "Fermer l’onglet"; "common.tab.menu.library" = "Bibliothèque"; "common.tab.menu.settings" = "Paramètres"; -"common.support.app_name" = "Soutenez-nous %@"; "common.export_file.alert.title" = "Exporter le fichier"; "common.export_file.alert.description" = "Voulez-vous exporter le fichier %@ ?"; "common.export_file.alert.button.title" = "Exporter"; @@ -75,7 +74,7 @@ "flavor_tag.help.mini" = "seul un sous-ensemble du texte est disponible, probablement la première section"; "library_refresh_time.last" = "À l’instant"; "library_refresh_time.never" = "Jamais"; -"zim_file_cell_article_count_suffix" = "articles"; +"zim_file_cell.article_count.suffix" = "articles"; "zim_file_missing_indicator.help" = "Le fichier Zim est manquant."; "library.zim_file_details.side_panel.message" = "Sélectionnez un fichier ZIM pour voir les détails"; "library.zim_file_context.main_page.label" = "Page principale"; @@ -92,7 +91,7 @@ "zim_file_downloads.overlay.empty.message" = "Aucune tâche de téléchargement"; "zim_file_downloads.toolbar.show_sidebar.label" = "Afficher la barre latérale"; "zim_file_new_overlay.empty" = "Pas de nouveau fichier ZIM"; -"zim_file_new_button_refresh" = "Actualiser"; +"zim_file_new.button.refresh" = "Actualiser"; "zim_file.list.name.text" = "Nom"; "zim_file.list.description.text" = "Description"; "zim_file.list.actions.text" = "Actions"; @@ -204,7 +203,6 @@ "app_macos_commands.open_file" = "Ouvrir..."; "app_macos_commands.new" = "Nouvel onglet"; "app_macos_navigation.button.library" = "Bibliothèque"; -"app_macos_navigation.show_sidebar" = "Afficher la barre latérale"; "sidebar_view.navigation.button.close" = "Fermer"; "sidebar_view.navigation.button.close_all" = "Fermer tous les onglets"; "enum.category.wikipedia" = "Wikipédia"; diff --git a/Support/ha.lproj/Localizable.strings b/Support/ha.lproj/Localizable.strings index 8946cf9b2..90c31d38a 100644 --- a/Support/ha.lproj/Localizable.strings +++ b/Support/ha.lproj/Localizable.strings @@ -61,7 +61,7 @@ "flavor_tag.help.mini" = "Juzu'in rubutu ne kawai yaka samuwa, tayiyu da farkon sashi"; "library_refresh_time.last" = "Yanxu yanxu"; "library_refresh_time.never" = "Ba a taɓa yin hakan ba"; -"zim_file_cell_article_count_suffix" = "Makalu"; +"zim_file_cell.article_count.suffix" = "Makalu"; "zim_file_missing_indicator.help" = "Fayil ɗin Zim ya ɓace."; // Fuzzy "library.zim_file_details.side_panel.message" = "Zabi fayil din zim dan ganin cikakken bayani"; @@ -78,7 +78,7 @@ "zim_file_downloads.overlay.empty.message" = "Babu ayyukan zazzagewa"; "zim_file_downloads.toolbar.show_sidebar.label" = "Nuna ma'aunin gefe"; "zim_file_new_overlay.empty" = "Babu sabon fayil ɗin Zim"; -"zim_file_new_button_refresh" = "Wartsake"; +"zim_file_new.button.refresh" = "Wartsake"; "zim_file.list.name.text" = "Suna"; "zim_file.list.description.text" = "Bayani"; "zim_file.list.actions.text" = "Ayyuka"; @@ -188,7 +188,6 @@ "app_macos_commands.open_file" = "Bude.."; "app_macos_commands.new" = "Sabon shafi"; "app_macos_navigation.button.library" = "Laburare"; -"app_macos_navigation.show_sidebar" = "Nuna ma'aunin gefe"; "sidebar_view.navigation.button.close" = "Kulle"; "sidebar_view.navigation.button.close_all" = "Rufe duk shafuka"; "enum.category.wikipedia" = "Wikipedia"; diff --git a/Support/he.lproj/Localizable.strings b/Support/he.lproj/Localizable.strings index 023c61476..e714b390d 100644 --- a/Support/he.lproj/Localizable.strings +++ b/Support/he.lproj/Localizable.strings @@ -32,7 +32,6 @@ "common.tab.list.close" = "סגירת לשונית"; "common.tab.menu.library" = "ספרייה"; "common.tab.menu.settings" = "הגדרות"; -"common.support.app_name" = "תמיכה בפרויקט %@"; "common.export_file.alert.title" = "יצוא קובץ"; "common.export_file.alert.description" = "לייצא את הקובץ %@?"; "common.export_file.alert.button.title" = "יצוא"; @@ -63,7 +62,7 @@ "flavor_tag.help.mini" = "רק חלק מהטקסט זמין, כנראה הפרק הראשון"; "library_refresh_time.last" = "זה עתה"; "library_refresh_time.never" = "מעולם לא"; -"zim_file_cell_article_count_suffix" = "ערכים"; +"zim_file_cell.article_count.suffix" = "ערכים"; "zim_file_missing_indicator.help" = "קובץ ה־zim חסר."; "library.zim_file_details.side_panel.message" = "נא לבחור קובץ ZIM כדי לראות פרטים"; "library.zim_file_context.main_page.label" = "עמוד ראשי"; @@ -80,7 +79,7 @@ "zim_file_downloads.overlay.empty.message" = "אין משימות הורדה"; "zim_file_downloads.toolbar.show_sidebar.label" = "הצגת סרגל צד"; "zim_file_new_overlay.empty" = "אין קובץ ZIM חדש"; -"zim_file_new_button_refresh" = "רענון"; +"zim_file_new.button.refresh" = "רענון"; "zim_file.list.name.text" = "שם"; "zim_file.list.description.text" = "תיאור"; "zim_file.list.actions.text" = "פעולות"; @@ -192,7 +191,6 @@ "app_macos_commands.open_file" = "פתיחה..."; "app_macos_commands.new" = "לשונית חדשה"; "app_macos_navigation.button.library" = "ספרייה"; -"app_macos_navigation.show_sidebar" = "הצגת סרגל צד"; "sidebar_view.navigation.button.close" = "סגירה"; "sidebar_view.navigation.button.close_all" = "סגירת כל הלשוניות"; "enum.category.wikipedia" = "ויקיפדיה"; diff --git a/Support/hi.lproj/Localizable.strings b/Support/hi.lproj/Localizable.strings index a8dd80254..f5829d123 100644 --- a/Support/hi.lproj/Localizable.strings +++ b/Support/hi.lproj/Localizable.strings @@ -26,7 +26,7 @@ "library.zim_file_context.main_page.label" = "मुखपृष्ठ"; "zim_file_opened.toolbar.open.title" = "खोलें..."; "zim_file_category.title" = "श्रेणी"; -"zim_file_new_button_refresh" = "ताजा करें"; +"zim_file_new.button.refresh" = "ताजा करें"; "zim_file.list.name.text" = "नाम"; "zim_file.list.description.text" = "विवरण"; "zim_file.list.actions.text" = "क्रियाएँ"; diff --git a/Support/ia.lproj/Localizable.strings b/Support/ia.lproj/Localizable.strings index 405d564dd..4b33a046b 100644 --- a/Support/ia.lproj/Localizable.strings +++ b/Support/ia.lproj/Localizable.strings @@ -31,7 +31,6 @@ "common.tab.list.close" = "Clauder scheda"; "common.tab.menu.library" = "Bibliotheca"; "common.tab.menu.settings" = "Parametros"; -"common.support.app_name" = "Appoiar %@"; "common.export_file.alert.title" = "Exportar file"; "common.export_file.alert.description" = "Vole tu exportar le file %@?"; "common.export_file.alert.button.title" = "Exportar"; @@ -62,7 +61,7 @@ "flavor_tag.help.mini" = "solmente un parte del texto es disponibile, probabilemente le prime section"; "library_refresh_time.last" = "Justo ora"; "library_refresh_time.never" = "Nunquam"; -"zim_file_cell_article_count_suffix" = "articulos"; +"zim_file_cell.article_count.suffix" = "articulos"; "zim_file_missing_indicator.help" = "Le file ZIM manca."; "library.zim_file_details.side_panel.message" = "Selige un file ZIM pro vider detalios"; "library.zim_file_context.main_page.label" = "Pagina principal"; @@ -79,7 +78,7 @@ "zim_file_downloads.overlay.empty.message" = "Necun discargamento"; "zim_file_downloads.toolbar.show_sidebar.label" = "Monstrar barra lateral"; "zim_file_new_overlay.empty" = "Necun nove file ZIM"; -"zim_file_new_button_refresh" = "Refrescar"; +"zim_file_new.button.refresh" = "Refrescar"; "zim_file.list.name.text" = "Nomine"; "zim_file.list.description.text" = "Description"; "zim_file.list.actions.text" = "Actiones"; @@ -191,7 +190,6 @@ "app_macos_commands.open_file" = "Aperir…"; "app_macos_commands.new" = "Nove scheda"; "app_macos_navigation.button.library" = "Bibliotheca"; -"app_macos_navigation.show_sidebar" = "Monstrar barra lateral"; "sidebar_view.navigation.button.close" = "Clauder"; "sidebar_view.navigation.button.close_all" = "Clauder tote le schedas"; "enum.category.wikipedia" = "Wikipedia"; diff --git a/Support/id.lproj/Localizable.strings b/Support/id.lproj/Localizable.strings index 0b8ca90a6..94b9e0c90 100644 --- a/Support/id.lproj/Localizable.strings +++ b/Support/id.lproj/Localizable.strings @@ -31,7 +31,6 @@ "common.tab.list.close" = "Tutup Tab"; "common.tab.menu.library" = "Perpustakaan"; "common.tab.menu.settings" = "Pengaturan"; -"common.support.app_name" = "Dukung %@"; "common.export_file.alert.title" = "Ekspor berkas"; "common.export_file.alert.description" = "Apakah Anda ingin mengekspor berkas %@?"; "common.export_file.alert.button.title" = "Ekspor"; @@ -62,7 +61,7 @@ "flavor_tag.help.mini" = "hanya sebagian kecil teks yang tersedia, mungkin bagian pertama"; "library_refresh_time.last" = "Baru Saja"; "library_refresh_time.never" = "Tidak pernah"; -"zim_file_cell_article_count_suffix" = "artikel"; +"zim_file_cell.article_count.suffix" = "artikel"; "zim_file_missing_indicator.help" = "Berkas Zim hilang."; "library.zim_file_details.side_panel.message" = "Pilih berkas ZIM untuk melihat detailnya"; "library.zim_file_context.main_page.label" = "Halaman Utama"; @@ -79,7 +78,7 @@ "zim_file_downloads.overlay.empty.message" = "Tidak ada tugas unduhan"; "zim_file_downloads.toolbar.show_sidebar.label" = "Tampilkan Bilah Sisi"; "zim_file_new_overlay.empty" = "Tidak ada berkas ZIM baru"; -"zim_file_new_button_refresh" = "Muat ulang"; +"zim_file_new.button.refresh" = "Muat ulang"; "zim_file.list.name.text" = "Nama"; "zim_file.list.description.text" = "Deskripsi"; "zim_file.list.actions.text" = "Tindakan"; @@ -191,7 +190,6 @@ "app_macos_commands.open_file" = "Buka..."; "app_macos_commands.new" = "Tab Baru"; "app_macos_navigation.button.library" = "Perpustakaan"; -"app_macos_navigation.show_sidebar" = "Tampilkan Bilah Sisi"; "sidebar_view.navigation.button.close" = "Tutup"; "sidebar_view.navigation.button.close_all" = "Tutup Semua Tab"; "enum.category.wikibooks" = "Wikibuku"; diff --git a/Support/ig.lproj/Localizable.strings b/Support/ig.lproj/Localizable.strings index b26775058..4f6cee3f8 100644 --- a/Support/ig.lproj/Localizable.strings +++ b/Support/ig.lproj/Localizable.strings @@ -61,7 +61,7 @@ "flavor_tag.help.mini" = "naanị obere akụkụ nke ederede dị, ma eleghị anya ngalaba nke mbụ"; "library_refresh_time.last" = "Ugbu a"; "library_refresh_time.never" = "Ọ dịghị mgbe"; -"zim_file_cell_article_count_suffix" = "ederede"; +"zim_file_cell.article_count.suffix" = "ederede"; "zim_file_missing_indicator.help" = "Zim faịlụ na-efu efu."; // Fuzzy "library.zim_file_details.side_panel.message" = "Họrọ faịlụ zim ka ịhụ nkọwa ihe ndị ozọ"; @@ -82,7 +82,7 @@ "zim_file_downloads.toolbar.show_sidebar.label" = "Gosi akụkụ ngwa ọrụ"; // Fuzzy "zim_file_new_overlay.empty" = "Enweghị zim faịlụ ọhụrụ"; -"zim_file_new_button_refresh" = "Tụnyegharia"; +"zim_file_new.button.refresh" = "Tụnyegharia"; "zim_file.list.name.text" = "Aha"; "zim_file.list.description.text" = "Nkọwa"; "zim_file.list.actions.text" = "Omume ihe"; @@ -198,7 +198,6 @@ "app_macos_commands.open_file" = "Mepee..."; "app_macos_commands.new" = "Taabụ ọhụrụ"; "app_macos_navigation.button.library" = "Ọ́bá Akwụkwọ"; -"app_macos_navigation.show_sidebar" = "Gosi Ogwe akụkụ"; "sidebar_view.navigation.button.close" = "Mechie"; "sidebar_view.navigation.button.close_all" = "Mechie taabụ niile"; "enum.category.wikipedia" = "Wikipidịa"; diff --git a/Support/it.lproj/Localizable.strings b/Support/it.lproj/Localizable.strings index 3626967b5..02a1862b5 100644 --- a/Support/it.lproj/Localizable.strings +++ b/Support/it.lproj/Localizable.strings @@ -42,7 +42,7 @@ "zim_file_category.title" = "Categoria"; "zim_file_category.section.empty.message" = "Nessun file ZIM in questa categoria."; "zim_file_new_overlay.empty" = "Nessun nuovo file ZIM"; -"zim_file_new_button_refresh" = "Aggiorna"; +"zim_file_new.button.refresh" = "Aggiorna"; "zim_file.list.name.text" = "Nome"; "zim_file.list.description.text" = "Descrizione"; "zim_file.list.actions.text" = "Azioni"; diff --git a/Support/ja.lproj/Localizable.strings b/Support/ja.lproj/Localizable.strings index 5682154c7..60898d508 100644 --- a/Support/ja.lproj/Localizable.strings +++ b/Support/ja.lproj/Localizable.strings @@ -33,7 +33,6 @@ "common.tab.list.close" = "タブを閉じる"; "common.tab.menu.library" = "ライブラリ"; "common.tab.menu.settings" = "設定"; -"common.support.app_name" = "%@を支援"; "common.export_file.alert.title" = "ファイルをエクスポート"; "common.export_file.alert.description" = "ファイル%@をエクスポートしますか?"; "common.export_file.alert.button.title" = "エクスポート"; @@ -64,7 +63,7 @@ "flavor_tag.help.mini" = "文章の一部のみ(多くの場合最初の段落)が利用可能です。"; "library_refresh_time.last" = "今すぐ"; "library_refresh_time.never" = "なし"; -"zim_file_cell_article_count_suffix" = "記事"; +"zim_file_cell.article_count.suffix" = "記事"; "zim_file_missing_indicator.help" = "ZIMファイルがありません。"; "library.zim_file_details.side_panel.message" = "詳細を参照したいZIMファイルを選択"; "library.zim_file_context.main_page.label" = "メインページ"; @@ -81,7 +80,7 @@ "zim_file_downloads.overlay.empty.message" = "ダウンロード処理はありません"; "zim_file_downloads.toolbar.show_sidebar.label" = "サイドバーを表示"; "zim_file_new_overlay.empty" = "新しいZIMファイルはありません"; -"zim_file_new_button_refresh" = "更新"; +"zim_file_new.button.refresh" = "更新"; "zim_file.list.name.text" = "名前"; "zim_file.list.description.text" = "概要"; "zim_file.list.actions.text" = "操作"; @@ -191,7 +190,6 @@ "app_macos_commands.open_file" = "開く..."; "app_macos_commands.new" = "新規タブ"; "app_macos_navigation.button.library" = "ライブラリ"; -"app_macos_navigation.show_sidebar" = "サイドバーを表示"; "sidebar_view.navigation.button.close" = "閉じる"; "sidebar_view.navigation.button.close_all" = "すべてのタブを閉じる"; "enum.category.wikipedia" = "ウィキペディア"; diff --git a/Support/ko.lproj/Localizable.strings b/Support/ko.lproj/Localizable.strings index 6d7e67a15..c14b2a108 100644 --- a/Support/ko.lproj/Localizable.strings +++ b/Support/ko.lproj/Localizable.strings @@ -32,7 +32,6 @@ "common.tab.list.close" = "탭 닫기"; "common.tab.menu.library" = "라이브러리"; "common.tab.menu.settings" = "설정"; -"common.support.app_name" = "%@ 지원하기"; "common.export_file.alert.title" = "파일 내보내기"; "common.export_file.alert.description" = "%@ 파일을 내보내시겠습니까?"; "common.export_file.alert.button.title" = "내보내기"; @@ -75,7 +74,7 @@ "zim_file_downloads.overlay.empty.message" = "다운로드 작업 없음"; "zim_file_downloads.toolbar.show_sidebar.label" = "사이드바 표시"; "zim_file_new_overlay.empty" = "새 ZIM 파일 없습니다"; -"zim_file_new_button_refresh" = "새로 고침"; +"zim_file_new.button.refresh" = "새로 고침"; "zim_file.list.name.text" = "이름"; "zim_file.list.description.text" = "설명"; "zim_file.list.actions.text" = "동작"; @@ -178,7 +177,6 @@ "app_macos_commands.open_file" = "열기..."; "app_macos_commands.new" = "새 탭"; "app_macos_navigation.button.library" = "라이브러리"; -"app_macos_navigation.show_sidebar" = "사이드바 표시"; "sidebar_view.navigation.button.close" = "닫기"; "sidebar_view.navigation.button.close_all" = "모든 탭 닫기"; "enum.category.wikipedia" = "위키백과"; diff --git a/Support/lb.lproj/Localizable.strings b/Support/lb.lproj/Localizable.strings index d7f2eaee5..afa0ea134 100644 --- a/Support/lb.lproj/Localizable.strings +++ b/Support/lb.lproj/Localizable.strings @@ -28,7 +28,6 @@ "common.tab.list.close" = "Tab zoumaachen"; "common.tab.menu.library" = "Bibliothéik"; "common.tab.menu.settings" = "Astellungen"; -"common.support.app_name" = "%@ ënnerstëtzen"; "common.export_file.alert.title" = "Fichier exportéieren"; "common.export_file.alert.description" = "Wëllt Dir de Fichier %@ exportéieren?"; "common.export_file.alert.button.title" = "Exportéieren"; @@ -52,7 +51,7 @@ "flavor_tag.help.mini" = "nëmmen een Deel vum Text ass verfügbar, warscheinlech den éischten Abschnitt"; "library_refresh_time.last" = "Elo just"; "library_refresh_time.never" = "Ni"; -"zim_file_cell_article_count_suffix" = "Artikelen"; +"zim_file_cell.article_count.suffix" = "Artikelen"; "library.zim_file_context.main_page.label" = "Haaptsäit"; "library.zim_file_context.random.label" = "Zoufälleg Säit"; "library.zim_file_context.copy_url" = "URL kopéieren"; @@ -62,7 +61,7 @@ "zim_file_category.title" = "Kategorie"; "zim_file_category.section.empty.message" = "Keen ZIM-Fichier an dëser Kategorie."; "zim_file_new_overlay.empty" = "Keng nei ZIM-Datei"; -"zim_file_new_button_refresh" = "Aktualiséieren"; +"zim_file_new.button.refresh" = "Aktualiséieren"; "zim_file.list.name.text" = "Numm"; "zim_file.list.description.text" = "Beschreiwung"; "zim_file.list.actions.text" = "Aktiounen"; diff --git a/Support/mk.lproj/Localizable.strings b/Support/mk.lproj/Localizable.strings index 239e7cb9a..95f0d27d9 100644 --- a/Support/mk.lproj/Localizable.strings +++ b/Support/mk.lproj/Localizable.strings @@ -31,7 +31,6 @@ "common.tab.list.close" = "Затвори јазиче"; "common.tab.menu.library" = "Библиотека"; "common.tab.menu.settings" = "Нагодувања"; -"common.support.app_name" = "Поддржете го %@"; "common.export_file.alert.title" = "Извези податотека"; "common.export_file.alert.description" = "Дали сакате да ја извезете податотеката %@?"; "common.export_file.alert.button.title" = "Извези"; @@ -62,7 +61,7 @@ "flavor_tag.help.mini" = "достапен е само дел од текстот, веројатно првиот"; "library_refresh_time.last" = "Штотуку"; "library_refresh_time.never" = "Никогаш"; -"zim_file_cell_article_count_suffix" = "статии"; +"zim_file_cell.article_count.suffix" = "статии"; "zim_file_missing_indicator.help" = "ZIM-податотеката недостасува."; "library.zim_file_details.side_panel.message" = "Изберете ZIM-податотека за да ги видите поединостите"; "library.zim_file_context.main_page.label" = "Главна страница"; @@ -79,7 +78,7 @@ "zim_file_downloads.overlay.empty.message" = "Нема задачи за преземање"; "zim_file_downloads.toolbar.show_sidebar.label" = "Прикажи страничник"; "zim_file_new_overlay.empty" = "Нема нова ZIM-податотека"; -"zim_file_new_button_refresh" = "Превчитај"; +"zim_file_new.button.refresh" = "Превчитај"; "zim_file.list.name.text" = "Име"; "zim_file.list.description.text" = "Опис"; "zim_file.list.actions.text" = "Дејства"; @@ -191,7 +190,6 @@ "app_macos_commands.open_file" = "Отвори..."; "app_macos_commands.new" = "Ново јазиче"; "app_macos_navigation.button.library" = "Библиотека"; -"app_macos_navigation.show_sidebar" = "Прикажи страничник"; "sidebar_view.navigation.button.close" = "Затвори"; "sidebar_view.navigation.button.close_all" = "Затвори ги сите јазичиња"; "enum.category.wikipedia" = "Википедија"; diff --git a/Support/pl.lproj/Localizable.strings b/Support/pl.lproj/Localizable.strings index e5989843a..af82bccae 100644 --- a/Support/pl.lproj/Localizable.strings +++ b/Support/pl.lproj/Localizable.strings @@ -25,7 +25,6 @@ "common.tab.list.close" = "Zamknij zakładkę"; "common.tab.menu.library" = "Biblioteka"; "common.tab.menu.settings" = "Ustawienia"; -"common.support.app_name" = "Wsparcie %@"; "common.export_file.alert.title" = "Eksportuj plik"; "common.export_file.alert.button.title" = "Eksportuj"; "bookmark_context_menu.view.title" = "Podgląd"; @@ -42,7 +41,7 @@ "flavor_tag.help.mini" = "dostępny jest tylko podzbiór tekstu, prawdopodobnie pierwsza sekcja"; "library_refresh_time.last" = "Dopiero co"; "library_refresh_time.never" = "Nigdy"; -"zim_file_cell_article_count_suffix" = "artykuły"; +"zim_file_cell.article_count.suffix" = "artykuły"; "zim_file_missing_indicator.help" = "Brak pliku Zim."; // Fuzzy "library.zim_file_details.side_panel.message" = "Wybierz plik zim, aby zobaczyć szczegóły"; @@ -56,7 +55,7 @@ "zim_file_downloads.toolbar.show_sidebar.label" = "Pokaż pasek boczny"; // Fuzzy "zim_file_new_overlay.empty" = "Brak nowego pliku zim"; -"zim_file_new_button_refresh" = "Odśwież"; +"zim_file_new.button.refresh" = "Odśwież"; "zim_file.list.name.text" = "Nazwa"; "zim_file.list.description.text" = "Opis"; "zim_file.action.delete.title" = "Usuń"; @@ -144,7 +143,6 @@ "comments.button.zoom_out" = "Oddal"; "app_macos_commands.new" = "Nowa zakładka"; "app_macos_navigation.button.library" = "Biblioteka"; -"app_macos_navigation.show_sidebar" = "Pokaż pasek boczny"; "sidebar_view.navigation.button.close" = "Zamknij"; "sidebar_view.navigation.button.close_all" = "Zamknij wszystkie zakładki"; "enum.category.other" = "Inne"; diff --git a/Support/pt-br.lproj/Localizable.strings b/Support/pt-br.lproj/Localizable.strings index 555bc4228..0e3586c49 100644 --- a/Support/pt-br.lproj/Localizable.strings +++ b/Support/pt-br.lproj/Localizable.strings @@ -31,7 +31,6 @@ "common.tab.list.close" = "Fechar Guia"; "common.tab.menu.library" = "Biblioteca"; "common.tab.menu.settings" = "Configurações"; -"common.support.app_name" = "Apoie %@"; "common.export_file.alert.title" = "Exportar arquivo"; "common.export_file.alert.description" = "Você deseja exportar o arquivo %@?"; "common.export_file.alert.button.title" = "Exportar"; @@ -50,7 +49,7 @@ "download_task_cell.status.downloading" = "Baixando..."; "download_task_cell.status.paused" = "Pausado"; "library_refresh_time.never" = "Nunca"; -"zim_file_cell_article_count_suffix" = "artigos"; +"zim_file_cell.article_count.suffix" = "artigos"; "zim_file_missing_indicator.help" = "Está faltando o arquivo zim."; "library.zim_file_details.side_panel.message" = "Selecione um arquivo ZIM para ver mais detalhes"; "library.zim_file_context.main_page.label" = "Página principal"; @@ -60,6 +59,6 @@ "zim_file_opened.toolbar.open.title" = "Abrir..."; "zim_file_opened.toolbar.open.help" = "Abrir arquivo ZIM"; "zim_file_category.title" = "Categoria"; -"zim_file_new_button_refresh" = "Atualizar"; +"zim_file_new.button.refresh" = "Atualizar"; "zim_file.list.name.text" = "Nome"; "zim_file.list.description.text" = "Descrição"; diff --git a/Support/qqq.lproj/Localizable.strings b/Support/qqq.lproj/Localizable.strings index 742890218..60ff87092 100644 --- a/Support/qqq.lproj/Localizable.strings +++ b/Support/qqq.lproj/Localizable.strings @@ -12,6 +12,9 @@ "common.dialog.button.remove_bookmark" = "After long pressing a link or the bottom tab menu item it is the title of one of the options in the overflow menu"; "common.dialog.button.show_bookmarks" = "After long pressing the bottom tab menu item it is the title of one of the options in the overflow menu"; "common.dialog.button.bookmark" = "After long pressing a link or the bottom tab menu item it is the title of one of the options in the overflow menu"; +"common.export_file.alert.button.title" = "Title of the confirmation button in alert pop up, when trying to export a file"; +"common.export_file.alert.description" = "Description of alter pop up, asking for confirmation in exporting the selected file"; +"common.export_file.alert.title" = "Title of alert pop up, when trying to export a file"; "common.button.go_back" = "Browser navigation buttton title"; "common.button.go_forward" = "Browser navigation buttton title"; "common.button.done" = "The default button label for overflow menus, in order to close them"; @@ -29,7 +32,6 @@ "common.tab.list.close" = "Accessibility label for button to close the current tab"; "common.tab.menu.library" = "On iPad it is a sidemenu title grouping library/ZIM file related buttons. Library: Opened | Categories | Downloads | New"; "common.tab.menu.settings" = "On iPad it is a sidemenu title leading to application settings page"; -"common.support.app_name" = "Button title, opening the external browser to support the app. The App Name being the argument, eg: Support Kiwix"; "outline_button.outline.title" = "Button label on macOS for topbar browser button"; "outline_button.outline.help" = "Accessibility label on macOS for topbar browser button"; "outline_button.outline.empty.message" = "Title within an overlay menu, when there's no outline available for the current article loaded"; @@ -57,7 +59,10 @@ "flavor_tag.help.mini" = "Accessibility label for ZIM file results, explaining the different flavours of the same ZIM file (mini|max|nopic)"; "library_refresh_time.last" = "Just Now"; "library_refresh_time.never" = "Never"; -"zim_file_cell_article_count_suffix" = "Part of the ZIM file description, when we list ZIM files (as card results), eg: '246K articles', the word articles is added after the number"; +"library_refresh_error.parse.description" = "Alert description, when refreshing the library failed, due to an error when parsing the response from the server"; +"library_refresh_error.process.description" = "Alert description, when refreshing the library failed, due to an error while processing the data from the server"; +"library_refresh_error.retrieve.description" = "Alert description, when refreshing the library failed, due to a connection error to the server"; +"zim_file_cell.article_count.suffix" = "Part of the ZIM file description, when we list ZIM files (as card results), eg: '246K articles', the word articles is added after the number"; "zim_file_missing_indicator.help" = "Accessibility label for a warning (!) icon"; "library.zim_file_details.side_panel.message" = "Default placeholder text for side panel on macOS, when no file is selected."; "library.zim_file_context.main_page.label" = "Supplementary action title, when long pressing on a ZIM file"; @@ -74,7 +79,7 @@ "zim_file_downloads.overlay.empty.message" = "Fallback text for center panel, when downloads are selected from the side menu."; "zim_file_downloads.toolbar.show_sidebar.label" = "Accessibility label for side bar toggle button"; "zim_file_new_overlay.empty" = "Fallback text for listing new ZIM files available for download"; -"zim_file_new_button_refresh" = "Accessibility label for refresh button on the top nav bar to refresh the list of new ZIM files"; +"zim_file_new.button.refresh" = "Accessibility label for refresh button on the top nav bar to refresh the list of new ZIM files"; "zim_file.list.name.text" = "Title for displaying the details of a ZIM file"; "zim_file.list.description.text" = "Title for displaying the details of a ZIM file"; "zim_file.list.actions.text" = "Title for displaying the possible actions to a selected ZIM file. Eg. The 'Download' button is below this."; @@ -177,14 +182,13 @@ "welcome.main_page.title" = "Default new browser tab title on iOS. the downloaded ZIM files are listed below this title"; "welcome.grid.bookmarks.title" = "Welcome page section title"; "welcome.actions.open_file" = "Welcome page button title"; -"welcome.button.status.fetch_catalog.text" = "Welcome page button title"; +"welcome.button.status.fetch_catalog.text" = "Welcome page button title, to fetch the catalog (un-pressed state)"; "commands.button.actual_size" = "MacOS command menu item"; "comments.button.zoom_in" = "MacOS command menu item"; "comments.button.zoom_out" = "MacOS command menu item"; "app_macos_commands.open_file" = "MacOS command menu item"; "app_macos_commands.new" = "MacOS command menu item"; "app_macos_navigation.button.library" = "MacOS command menu item"; -"app_macos_navigation.show_sidebar" = "MacOS command menu item"; "sidebar_view.navigation.button.close" = "Accessiblity title for navigation button icon"; "sidebar_view.navigation.button.close_all" = "Accessiblity title for navigation button icon"; "enum.category.wikipedia" = "{{Optional}}"; @@ -223,3 +227,23 @@ "enum.navigation_item.settings" = "Side navigation menu item title"; "enum.search_result_snippet_mode.disabled" = "Picker option title in settings. Search snippet: Disabled | Matches"; "enum.search_result_snippet_mode.matches" = "Picker option title in settings. Search snippet: Disabled | Matches"; +"payment.confirm.button.title" = "Confirmation button title, when the payment amount is selected"; +"payment.description.label" = "Label describing the purpose of the payment (Supporting Kiwix)"; +"payment.donate.title" = "Title of the donation pop-up (Support Kiwix)"; +"payment.error.description" = "Error message description, the user receives if the payment fails"; +"payment.error.title" = "Error message title, the user receives if the payment fails"; +"payment.monthly_support.label" = "Label to describe the already selected option, that the user will be charged a recurring monthly payment"; +"payment.selection.option.one_time" = "Option to pick for the user: a one time payment (not recurring)"; +"payment.selection.option.monthly" = "Selectable option title: a monthly recurring payment (not one time)"; +"payment.selection.average_monthly_donation.subtitle" = "Subtitle hint for the user, informing what was the average recurring monthly donation by other users, when selecting a custom (user defined) amount for donation"; +"payment.selection.last_year_average.subtitle" = "Subtitle hint for the user, informing what was the average one time donation by other users, when selecting a custom (user defined) amount for donation"; +"payment.selection.custom_amount" = "Selectable option title: define a custom amount, the user wants to donate (eg: 7.55$ instead of picking one of the pre-defined amounts from a list: 5$, 10$, 15$...)"; +"payment.success.description" = "Confirmation text that the donation payment was successful and thanking the user for supporting us"; +"payment.success.title" = "Confirmation title that the donation payment was successful."; +"payment.summary.title" = "Text for the payment summary item of the payment. It is required to display the total of the payment, and the items included. In our case it's a single donation item"; +"payment.summary_page.title" = "Title for the payment summary page. It is required to display a summary before the final payemnt. The title makes it clear who is the beneficient of the donation."; +"payment.support_button.label" = "The donation button title with a heart, that brings up the the donation / payment pop-up"; +"payment.support_fallback_message" = "It is a fallback user message on devices that do not support Apple Pay"; +"payment.textfield.custom_amount.label" = "Label text for the input text field, where the user can type in their custom donation amount, eg: 7.55$"; +"welcome.button.status.fetching_catalog.text" = "Welcome page button title, to fetch the catalog. This title is used, when the fetching is already running, and the button itself is inactive (cannot be pressed again), but indicates progress."; +"welcome.loading.data.text" = "Loading indicator label, this is the first message the user will see when opening the app after a fresh install. Important to keep the ... part, or otherwise indicate the ongoing process."; \ No newline at end of file diff --git a/Support/ru.lproj/Localizable.strings b/Support/ru.lproj/Localizable.strings index e35e2ae45..1224ddd78 100644 --- a/Support/ru.lproj/Localizable.strings +++ b/Support/ru.lproj/Localizable.strings @@ -37,7 +37,6 @@ "common.tab.list.close" = "Закрыть вкладку"; "common.tab.menu.library" = "Библиотека"; "common.tab.menu.settings" = "Настройки"; -"common.support.app_name" = "Справка %@"; "common.export_file.alert.title" = "Экспорт файла"; "common.export_file.alert.description" = "Вы хотите экспортировать файл %@?"; "common.export_file.alert.button.title" = "Экспорт"; @@ -68,7 +67,7 @@ "flavor_tag.help.mini" = "доступна только часть текста, вероятно, первый раздел"; "library_refresh_time.last" = "Прямо сейчас"; "library_refresh_time.never" = "Никогда"; -"zim_file_cell_article_count_suffix" = "статей"; +"zim_file_cell.article_count.suffix" = "статей"; "zim_file_missing_indicator.help" = "Zim-файл отсутствует."; "library.zim_file_details.side_panel.message" = "Выберите ZIM-файл, чтобы просмотреть подробности."; "library.zim_file_context.main_page.label" = "Заглавная страница"; @@ -85,7 +84,7 @@ "zim_file_downloads.overlay.empty.message" = "Нет задач по загрузке"; "zim_file_downloads.toolbar.show_sidebar.label" = "Показать боковую панель"; "zim_file_new_overlay.empty" = "Нет нового ZIM-файла"; -"zim_file_new_button_refresh" = "Обновить"; +"zim_file_new.button.refresh" = "Обновить"; "zim_file.list.name.text" = "Имя"; "zim_file.list.description.text" = "Описание"; "zim_file.list.actions.text" = "Действия"; @@ -196,7 +195,6 @@ "app_macos_commands.open_file" = "Открыть..."; "app_macos_commands.new" = "Новая вкладка"; "app_macos_navigation.button.library" = "Библиотека"; -"app_macos_navigation.show_sidebar" = "Показать боковую панель"; "sidebar_view.navigation.button.close" = "Закрыть"; "sidebar_view.navigation.button.close_all" = "Закрыть все вкладки"; "enum.category.wikipedia" = "Википедия"; diff --git a/Support/se.lproj/Localizable.strings b/Support/se.lproj/Localizable.strings index 0936f226a..f3f097ba3 100644 --- a/Support/se.lproj/Localizable.strings +++ b/Support/se.lproj/Localizable.strings @@ -29,7 +29,7 @@ "download_task_cell.status.failed" = "Ii lihkostuvvan"; "library_refresh_time.last" = "Juste dal"; "library_refresh_time.never" = "Ii goassige"; -"zim_file_cell_article_count_suffix" = "artihkkala"; +"zim_file_cell.article_count.suffix" = "artihkkala"; "zim_file_missing_indicator.help" = "ZIM-fiila váilu."; "library.zim_file_context.main_page.label" = "Váldosiidu"; "library.zim_file_context.random.label" = "Summalis siidu"; diff --git a/Support/skr-arab.lproj/Localizable.strings b/Support/skr-arab.lproj/Localizable.strings index 813b6c6b9..dfb1105e2 100644 --- a/Support/skr-arab.lproj/Localizable.strings +++ b/Support/skr-arab.lproj/Localizable.strings @@ -33,11 +33,11 @@ "download_task_cell.status.paused" = "جمب ڳیا"; "library_refresh_time.last" = "ہُݨے ہُݨے"; "library_refresh_time.never" = "کݙاہیں وی کائناں"; -"zim_file_cell_article_count_suffix" = "مضمون"; +"zim_file_cell.article_count.suffix" = "مضمون"; "library.zim_file_context.main_page.label" = "پہلا پرت"; "zim_file_opened.toolbar.open.title" = "کھولو۔۔۔"; "zim_file_category.title" = "ونکی"; -"zim_file_new_button_refresh" = "تازہ کرو"; +"zim_file_new.button.refresh" = "تازہ کرو"; "zim_file.list.name.text" = "ناں"; "zim_file.list.description.text" = "تفصیل"; "zim_file.list.actions.text" = "عمل"; diff --git a/Support/sl.lproj/Localizable.strings b/Support/sl.lproj/Localizable.strings index 72e74b9e3..97de5d077 100644 --- a/Support/sl.lproj/Localizable.strings +++ b/Support/sl.lproj/Localizable.strings @@ -56,7 +56,7 @@ "flavor_tag.help.mini" = "na voljo je samo del besedila, verjetno prvi razdelek"; "library_refresh_time.last" = "Pravkar"; "library_refresh_time.never" = "Nikoli"; -"zim_file_cell_article_count_suffix" = "članki"; +"zim_file_cell.article_count.suffix" = "članki"; "zim_file_missing_indicator.help" = "Datoteka Zim manjka."; // Fuzzy "library.zim_file_details.side_panel.message" = "Izberite datoteko ZIM za ogled podrobnosti"; @@ -74,7 +74,7 @@ "zim_file_downloads.toolbar.show_sidebar.label" = "Prikaži stransko vrstico"; // Fuzzy "zim_file_new_overlay.empty" = "Ni novih datotek ZIM"; -"zim_file_new_button_refresh" = "Osveži"; +"zim_file_new.button.refresh" = "Osveži"; "zim_file.list.name.text" = "Ime"; "zim_file.list.description.text" = "Opis"; "zim_file.list.actions.text" = "Dejanja"; @@ -186,7 +186,6 @@ "app_macos_commands.open_file" = "Odpri ..."; "app_macos_commands.new" = "Nov zavihek"; "app_macos_navigation.button.library" = "Knjižnica"; -"app_macos_navigation.show_sidebar" = "Prikaži stransko vrstico"; "sidebar_view.navigation.button.close" = "Zapri"; "sidebar_view.navigation.button.close_all" = "Zapri vse zavihke"; "enum.category.wikipedia" = "Wikipedija"; diff --git a/Support/sq.lproj/Localizable.strings b/Support/sq.lproj/Localizable.strings index c9bd71ba3..cf08521ce 100644 --- a/Support/sq.lproj/Localizable.strings +++ b/Support/sq.lproj/Localizable.strings @@ -31,7 +31,6 @@ "common.tab.list.close" = "Mbylle Skedën"; "common.tab.menu.library" = "Bibliotekë"; "common.tab.menu.settings" = "Rregullime"; -"common.support.app_name" = "Përkrahni %@"; "common.export_file.alert.title" = "Eksportoni kartelë"; "common.export_file.alert.description" = "Doni të eksportohet kartela %@?"; "common.export_file.alert.button.title" = "Eksportoje"; @@ -62,7 +61,7 @@ "flavor_tag.help.mini" = "është i gatshëm vetëm një nëngrup i tekstit, me gjasa ndarja e parë"; "library_refresh_time.last" = "Mu Tani"; "library_refresh_time.never" = "Kurrë"; -"zim_file_cell_article_count_suffix" = "artikuj"; +"zim_file_cell.article_count.suffix" = "artikuj"; "zim_file_missing_indicator.help" = "Mungon kartelë ZIM."; "library.zim_file_details.side_panel.message" = "Që të shihni hollësi, përzgjidhni një kartelë ZIM"; "library.zim_file_context.main_page.label" = "Faqja Kryesore"; @@ -79,7 +78,7 @@ "zim_file_downloads.overlay.empty.message" = "S’ka akte shkarkimi"; "zim_file_downloads.toolbar.show_sidebar.label" = "Shfaq Anështyllë"; "zim_file_new_overlay.empty" = "Pa kartelë të re ZIM"; -"zim_file_new_button_refresh" = "Rifreskoje"; +"zim_file_new.button.refresh" = "Rifreskoje"; "zim_file.list.name.text" = "Emër"; "zim_file.list.description.text" = "Përshkrim"; "zim_file.list.actions.text" = "Veprime"; @@ -189,7 +188,6 @@ "app_macos_commands.open_file" = "Hapni…"; "app_macos_commands.new" = "Skedë e Re"; "app_macos_navigation.button.library" = "Bibliotekë"; -"app_macos_navigation.show_sidebar" = "Shfaq Anështyllë"; "sidebar_view.navigation.button.close" = "Mbylle"; "sidebar_view.navigation.button.close_all" = "Mbylli Krejt Skedat"; "enum.category.wikipedia" = "Wikipedia"; diff --git a/Support/sv.lproj/Localizable.strings b/Support/sv.lproj/Localizable.strings index 50f5884ad..e9e407adb 100644 --- a/Support/sv.lproj/Localizable.strings +++ b/Support/sv.lproj/Localizable.strings @@ -32,7 +32,6 @@ "common.tab.list.close" = "Stäng flik"; "common.tab.menu.library" = "Bibliotek"; "common.tab.menu.settings" = "Inställningar"; -"common.support.app_name" = "Stöd %@"; "common.export_file.alert.title" = "Exportera fil"; "common.export_file.alert.description" = "Vill du exportera filen %@?"; "common.export_file.alert.button.title" = "Exportera"; @@ -64,7 +63,7 @@ "flavor_tag.help.mini" = "endast en delmängd av texten är tillgänglig, förmodligen det första avsnittet"; "library_refresh_time.last" = "Alldeles nyss"; "library_refresh_time.never" = "Aldrig"; -"zim_file_cell_article_count_suffix" = "artiklar"; +"zim_file_cell.article_count.suffix" = "artiklar"; "zim_file_missing_indicator.help" = "Zim-fil saknas."; "library.zim_file_details.side_panel.message" = "Välj en ZIM-fil för att se information"; "library.zim_file_context.main_page.label" = "Huvudsida"; @@ -80,7 +79,7 @@ "zim_file_downloads.overlay.empty.message" = "Inga nedladdningsuppgifter"; "zim_file_downloads.toolbar.show_sidebar.label" = "Visa sidofält"; "zim_file_new_overlay.empty" = "Ingen ny ZIM-fil"; -"zim_file_new_button_refresh" = "Uppdatera"; +"zim_file_new.button.refresh" = "Uppdatera"; "zim_file.list.name.text" = "Namn"; "zim_file.list.description.text" = "Beskrivning"; "zim_file.list.actions.text" = "Åtgärder"; @@ -190,7 +189,6 @@ "app_macos_commands.open_file" = "Öppna..."; "app_macos_commands.new" = "Ny flik"; "app_macos_navigation.button.library" = "Bibliotek"; -"app_macos_navigation.show_sidebar" = "Visa sidofält"; "sidebar_view.navigation.button.close" = "Stäng"; "sidebar_view.navigation.button.close_all" = "Stäng alla flikar"; "enum.category.wikipedia" = "Wikipedia"; diff --git a/Support/tr.lproj/Localizable.strings b/Support/tr.lproj/Localizable.strings index ab602a741..85ee72d06 100644 --- a/Support/tr.lproj/Localizable.strings +++ b/Support/tr.lproj/Localizable.strings @@ -57,7 +57,7 @@ "flavor_tag.help.mini" = "metnin yalnızca bir alt kümesi mevcut, muhtemelen ilk bölüm"; "library_refresh_time.last" = "Şu anda"; "library_refresh_time.never" = "Asla"; -"zim_file_cell_article_count_suffix" = "makale"; +"zim_file_cell.article_count.suffix" = "makale"; "zim_file_missing_indicator.help" = "Zim dosyası eksik."; // Fuzzy "library.zim_file_details.side_panel.message" = "Ayrıntıları görmek için bir zim dosyası seçin"; @@ -78,7 +78,7 @@ "zim_file_downloads.toolbar.show_sidebar.label" = "Kenar Çubuğunu Göster"; // Fuzzy "zim_file_new_overlay.empty" = "Yeni zim dosyası yok"; -"zim_file_new_button_refresh" = "Yenile"; +"zim_file_new.button.refresh" = "Yenile"; "zim_file.list.name.text" = "Ad"; "zim_file.list.description.text" = "Açıklama"; "zim_file.list.actions.text" = "Eylemler"; @@ -194,7 +194,6 @@ "app_macos_commands.open_file" = "Aç..."; "app_macos_commands.new" = "Yeni Sekme"; "app_macos_navigation.button.library" = "Kütüphane"; -"app_macos_navigation.show_sidebar" = "Kenar Çubuğunu Göster"; "sidebar_view.navigation.button.close" = "Kapat"; "sidebar_view.navigation.button.close_all" = "Tüm Sekmeleri Kapat"; "enum.category.wikipedia" = "Vikipedi"; diff --git a/Support/uk.lproj/Localizable.strings b/Support/uk.lproj/Localizable.strings index b36896ee4..2c5033204 100644 --- a/Support/uk.lproj/Localizable.strings +++ b/Support/uk.lproj/Localizable.strings @@ -31,7 +31,6 @@ "common.tab.list.close" = "Закрити вкладку"; "common.tab.menu.library" = "Бібліотека"; "common.tab.menu.settings" = "Налаштування"; -"common.support.app_name" = "Підтримайте %@"; "common.export_file.alert.title" = "Експортувати файл"; "common.export_file.alert.description" = "Ви бажаєте експортувати файл %@?"; "common.export_file.alert.button.title" = "Експортувати"; @@ -58,7 +57,7 @@ "flavor_tag.help.no_pic" = "більшість зображень було видалено"; "library_refresh_time.last" = "Щойно"; "library_refresh_time.never" = "Ніколи"; -"zim_file_cell_article_count_suffix" = "статей"; +"zim_file_cell.article_count.suffix" = "статей"; "zim_file_missing_indicator.help" = "Файл Zim відсутній."; "library.zim_file_details.side_panel.message" = "Оберіть файл ZIM, щоб побачити деталі"; "library.zim_file_context.main_page.label" = "Головна сторінка"; @@ -73,7 +72,7 @@ "zim_file_category.section.empty.message" = "У цій категорії немає файлу ZIM."; "zim_file_downloads.toolbar.show_sidebar.label" = "Показати бічну панель"; "zim_file_new_overlay.empty" = "Немає нового файлу ZIM"; -"zim_file_new_button_refresh" = "Оновити"; +"zim_file_new.button.refresh" = "Оновити"; "zim_file.list.name.text" = "Назва"; "zim_file.list.description.text" = "Опис"; "zim_file.list.actions.text" = "Дії"; @@ -179,7 +178,6 @@ "app_macos_commands.open_file" = "Відкрити..."; "app_macos_commands.new" = "Нова вкладка"; "app_macos_navigation.button.library" = "Бібліотека"; -"app_macos_navigation.show_sidebar" = "Показати бічну панель"; "sidebar_view.navigation.button.close" = "Закрити"; "sidebar_view.navigation.button.close_all" = "Закрити всі вкладки"; "enum.category.wikipedia" = "Вікіпедія"; diff --git a/Support/zh-hans.lproj/Localizable.strings b/Support/zh-hans.lproj/Localizable.strings index 77991ba9a..1ea90e7d7 100644 --- a/Support/zh-hans.lproj/Localizable.strings +++ b/Support/zh-hans.lproj/Localizable.strings @@ -36,7 +36,6 @@ "common.tab.list.close" = "关闭标签页"; "common.tab.menu.library" = "图书馆"; "common.tab.menu.settings" = "设置"; -"common.support.app_name" = "支持 %@"; "common.export_file.alert.title" = "导出文件"; "common.export_file.alert.description" = "您真的想导出文件 %@ 吗?"; "common.export_file.alert.button.title" = "导出"; @@ -67,7 +66,7 @@ "flavor_tag.help.mini" = "仅有部分文本可用,这可能是第一部分"; "library_refresh_time.last" = "刚刚"; "library_refresh_time.never" = "从不"; -"zim_file_cell_article_count_suffix" = "条目"; +"zim_file_cell.article_count.suffix" = "条目"; "zim_file_missing_indicator.help" = "Zim 文件丢失"; "library.zim_file_details.side_panel.message" = "选择一个 ZIM 文件以查看详细信息"; "library.zim_file_context.main_page.label" = "首页"; @@ -84,7 +83,7 @@ "zim_file_downloads.overlay.empty.message" = "没有下载任务"; "zim_file_downloads.toolbar.show_sidebar.label" = "显示侧边栏"; "zim_file_new_overlay.empty" = "没有新的 ZIM 文件"; -"zim_file_new_button_refresh" = "刷新"; +"zim_file_new.button.refresh" = "刷新"; "zim_file.list.name.text" = "名称"; "zim_file.list.description.text" = "描述"; "zim_file.list.actions.text" = "操作"; @@ -196,7 +195,6 @@ "app_macos_commands.open_file" = "打开..."; "app_macos_commands.new" = "新建标签页"; "app_macos_navigation.button.library" = "图书馆"; -"app_macos_navigation.show_sidebar" = "显示侧边栏"; "sidebar_view.navigation.button.close" = "关闭"; "sidebar_view.navigation.button.close_all" = "关闭所有标签页"; "enum.category.wikipedia" = "维基百科"; diff --git a/Support/zh-hant.lproj/Localizable.strings b/Support/zh-hant.lproj/Localizable.strings index 8fdf2437e..44666c00d 100644 --- a/Support/zh-hant.lproj/Localizable.strings +++ b/Support/zh-hant.lproj/Localizable.strings @@ -32,7 +32,6 @@ "common.tab.list.close" = "關閉分頁"; "common.tab.menu.library" = "圖書館"; "common.tab.menu.settings" = "設定"; -"common.support.app_name" = "支援 %@"; "common.export_file.alert.title" = "匯出檔案"; "common.export_file.alert.description" = "您要匯出檔案「%@」嗎?"; "common.export_file.alert.button.title" = "匯出"; @@ -63,7 +62,7 @@ "flavor_tag.help.mini" = "僅有文字的子集合可用,有可能是第一段落"; "library_refresh_time.last" = "現在"; "library_refresh_time.never" = "永不"; -"zim_file_cell_article_count_suffix" = "條目"; +"zim_file_cell.article_count.suffix" = "條目"; "zim_file_missing_indicator.help" = "遺失 Zim 檔案。"; "library.zim_file_details.side_panel.message" = "選擇一個 ZIM 檔案以查看詳細資訊"; "library.zim_file_context.main_page.label" = "主頁"; @@ -80,7 +79,7 @@ "zim_file_downloads.overlay.empty.message" = "沒有下載任務"; "zim_file_downloads.toolbar.show_sidebar.label" = "顯示側邊欄"; "zim_file_new_overlay.empty" = "沒有新的 ZIM 檔案"; -"zim_file_new_button_refresh" = "重整"; +"zim_file_new.button.refresh" = "重整"; "zim_file.list.name.text" = "名稱"; "zim_file.list.description.text" = "描述"; "zim_file.list.actions.text" = "操作"; @@ -192,7 +191,6 @@ "app_macos_commands.open_file" = "開啟…"; "app_macos_commands.new" = "新分頁"; "app_macos_navigation.button.library" = "圖書館"; -"app_macos_navigation.show_sidebar" = "顯示側邊欄"; "sidebar_view.navigation.button.close" = "關閉"; "sidebar_view.navigation.button.close_all" = "關閉所有分頁"; "enum.category.wikipedia" = "維基百科"; diff --git a/SwiftUI/Model/DirectoryMonitor.swift b/SwiftUI/Model/DirectoryMonitor.swift index 1212a065d..6dad66fa8 100644 --- a/SwiftUI/Model/DirectoryMonitor.swift +++ b/SwiftUI/Model/DirectoryMonitor.swift @@ -98,15 +98,16 @@ class DirectoryMonitor { } private func directoryDidReachStasis() { - DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(Int64(NSEC_PER_SEC/10)) / Double(NSEC_PER_SEC) , execute: { () -> Void in - self.delegate?.directoryContentDidChange(url: self.url) - self.onChange?(self.url) + DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(Int64(NSEC_PER_SEC/10)) / Double(NSEC_PER_SEC), execute: { [weak self] in + guard let url = self?.url else { return } + self?.delegate?.directoryContentDidChange(url: url) + self?.onChange?(url) }) } private func waitAndCheckAgain() { - queue.asyncAfter(deadline: DispatchTime.now() + Double(Int64(NSEC_PER_SEC/2)) / Double(NSEC_PER_SEC) , execute: { () -> Void in - self.checkDirectoryChanges() + queue.asyncAfter(deadline: DispatchTime.now() + Double(Int64(NSEC_PER_SEC/2)) / Double(NSEC_PER_SEC), execute: { [weak self] in + self?.checkDirectoryChanges() }) } diff --git a/SwiftUI/Model/Enum.swift b/SwiftUI/Model/Enum.swift index 271cc1442..e1af6d966 100644 --- a/SwiftUI/Model/Enum.swift +++ b/SwiftUI/Model/Enum.swift @@ -65,29 +65,29 @@ enum Category: String, CaseIterable, Identifiable, LosslessStringConvertible, Ha var name: String { switch self { case .wikipedia: - return "enum.category.wikipedia".localized + return LocalString.enum_category_wikipedia case .wikibooks: - return "enum.category.wikibooks".localized + return LocalString.enum_category_wikibooks case .wikinews: - return "enum.category.wikinews".localized + return LocalString.enum_category_wikinews case .wikiquote: - return "enum.category.wikiquote".localized + return LocalString.enum_category_wikiquote case .wikisource: - return "enum.category.wikisource".localized + return LocalString.enum_category_wikisource case .wikiversity: - return "enum.category.wikiversity".localized + return LocalString.enum_category_wikiversity case .wikivoyage: - return "enum.category.wikivoyage".localized + return LocalString.enum_category_wikivoyage case .wiktionary: - return "enum.category.wiktionary".localized + return LocalString.enum_category_wiktionary case .ted: - return "enum.category.ted".localized + return LocalString.enum_category_ted case .vikidia: - return "enum.category.vikidia".localized + return LocalString.enum_category_vikidia case .stackExchange: - return "enum.category.stackexchange".localized + return LocalString.enum_category_stackexchange case .other: - return "enum.category.other".localized + return LocalString.enum_category_other } } @@ -129,11 +129,11 @@ enum ExternalLinkLoadingPolicy: String, CaseIterable, Identifiable, Defaults.Ser var name: String { switch self { case .alwaysAsk: - return "enum.external_link_loading_policy.always_ask".localized + return LocalString.enum_external_link_loading_policy_always_ask case .alwaysLoad: - return "enum.external_link_loading_policy.always_load".localized + return LocalString.enum_external_link_loading_policy_always_load case .neverLoad: - return "enum.external_link_loading_policy.never_load".localized + return LocalString.enum_external_link_loading_policy_never_load } } } @@ -162,11 +162,11 @@ enum Flavor: String, CustomStringConvertible { var description: String { switch self { case .max: - return "enum.flavor.max".localized + return LocalString.enum_flavor_max case .noPic: - return "enum.flavor.no_pic".localized + return LocalString.enum_flavor_no_pic case .mini: - return "enum.flavor.mini".localized + return LocalString.enum_flavor_mini } } } @@ -179,9 +179,9 @@ enum LibraryLanguageSortingMode: String, CaseIterable, Identifiable, Defaults.Se var name: String { switch self { case .alphabetically: - return "enum.library_language_sorting_model.a-z".localized + return LocalString.enum_library_language_sorting_model_a_z case .byCounts: - return "enum.library_language_sorting_model.by_count".localized + return LocalString.enum_library_language_sorting_model_by_count } } } @@ -194,13 +194,13 @@ enum LibraryTabItem: String, CaseIterable, Identifiable { var name: String { switch self { case .opened: - return "enum.libray_tab_item.opened".localized + return LocalString.enum_libray_tab_item_opened case .categories: - return "enum.libray_tab_item.categories".localized + return LocalString.enum_libray_tab_item_categories case .downloads: - return "enum.libray_tab_item.downloads".localized + return LocalString.enum_libray_tab_item_downloads case .new: - return "enum.libray_tab_item.new".localized + return LocalString.enum_libray_tab_item_new } } @@ -229,27 +229,27 @@ enum NavigationItem: Hashable, Identifiable { var name: String { switch self { case .loading: - return "enum.navigation_item.loading".localized + return LocalString.enum_navigation_item_loading case .bookmarks: - return "enum.navigation_item.bookmarks".localized + return LocalString.enum_navigation_item_bookmarks case .map: - return "enum.navigation_item.map".localized + return LocalString.enum_navigation_item_map case .tab: #if os(macOS) - return "enum.navigation_item.reading".localized + return LocalString.enum_navigation_item_reading #else - return "enum.navigation_item.new_tab".localized + return LocalString.enum_navigation_item_new_tab #endif case .opened: - return "enum.navigation_item.opened".localized + return LocalString.enum_navigation_item_opened case .categories: - return "enum.navigation_item.categories".localized + return LocalString.enum_navigation_item_categories case .new: - return "enum.navigation_item.new".localized + return LocalString.enum_navigation_item_new case .downloads: - return "enum.navigation_item.downloads".localized + return LocalString.enum_navigation_item_downloads case .settings: - return "enum.navigation_item.settings".localized + return LocalString.enum_navigation_item_settings } } @@ -294,9 +294,9 @@ enum SearchResultSnippetMode: String, CaseIterable, Identifiable, Defaults.Seria var name: String { switch self { case .disabled: - return "enum.search_result_snippet_mode.disabled".localized + return LocalString.enum_search_result_snippet_mode_disabled case .matches: - return "enum.search_result_snippet_mode.matches".localized + return LocalString.enum_search_result_snippet_mode_matches } } } diff --git a/SwiftUI/Model/SearchOperation/SearchOperation.swift b/SwiftUI/Model/SearchOperation/SearchOperation.swift index 3e91ec22e..37d3a09b1 100644 --- a/SwiftUI/Model/SearchOperation/SearchOperation.swift +++ b/SwiftUI/Model/SearchOperation/SearchOperation.swift @@ -45,6 +45,7 @@ extension SearchOperation { // start sorting search results let searchText = searchText.lowercased() + // swiftlint:disable compiler_protocol_init // calculate score for all results for result in results { guard !isCancelled else { return } @@ -55,6 +56,7 @@ extension SearchOperation { result.score = NSNumber(integerLiteral: distance) } } + // swiftlint:enable compiler_protocol_init // sort the results guard !isCancelled else { return } diff --git a/Tests/BookmarkMigrationTests.swift b/Tests/BookmarkMigrationTests.swift index 3c75f0b3c..58ffedacb 100644 --- a/Tests/BookmarkMigrationTests.swift +++ b/Tests/BookmarkMigrationTests.swift @@ -35,7 +35,7 @@ final class BookmarkMigrationTests: XCTestCase { let testString = "\0\0\0\u{02}bplist00�\u{01}\u{02}\u{03}\u{04}\u{05}\u{06}^RenderTreeSize^IsAppInitiated^SessionHistory\u{10}\u{03}\t�\u{07}\u{08}\t\n\u{1C}\u{1C}_\u{10}\u{15}SessionHistoryEntries_\u{10}\u{1A}SessionHistoryCurrentIndex_\u{10}\u{15}SessionHistoryVersion�\u{0B}\u{16}�\u{0C}\r\u{0E}\u{0F}\u{10}\u{11}\u{12}\u{13}\u{14}\u{15}_\u{10}\u{17}SessionHistoryEntryData_\u{10}\u{18}SessionHistoryEntryTitle_\u{10}2SessionHistoryEntryShouldOpenExternalURLsPolicyKey_\u{10}\u{16}SessionHistoryEntryURL_\u{10}\u{1E}SessionHistoryEntryOriginalURLO\u{10}P\0\0\0\0\0\0\0\0\u{02}\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0�\u{07}�@�\u{13}\u{06}\0\0\0\0\0\0\0\0\0����\0\0\0\0�\u{07}�@�\u{13}\u{06}\0����\0\0\0\0�\u{03}\0\0\0\0�?\0\0\0\0����TDWDS\u{10}\u{01}_\u{10}2kiwix://64C3EA1A-5161-2B94-1F50-606DA5EC0035/index_\u{10}2kiwix://64C3EA1A-5161-2B94-1F50-606DA5EC0035/index�\u{0C}\r\u{0E}\u{0F}\u{10}\u{17}\u{18}\u{19}\u{1A}\u{1B}O\u{10}P\0\0\0\0\0\0\0\0\u{02}\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0V<�A�\u{13}\u{06}\0\0\0\0\0\0\0\0\0����\0\0\0\0U<�A�\u{13}\u{06}\0����\0\0\0\0\0\0\0\0\0\0�?\0\0\0\0����[hier und da\u{10}\u{02}_\u{10}\0?\0F\0^\0{\0�\0�\0�\0�\0�\u{01}\u{0B}\u{01}$\u{01}E\u{01}�\u{01}�\u{01}�\u{01}�\u{02}\t\u{02}\u{14}\u{02}g\u{02}s\u{02}u\u{02}�\u{02}�\0\0\0\0\0\0\u{02}\u{01}\0\0\0\0\0\0\0\u{1D}\0\0\0\0\0\0\0\0\0\0\0\0\0\0\u{02}�" let data = Data(testString.utf8) let newData = data.updateHost(to: newHost) - let outString = String(decoding: newData, as: UTF8.self) + let outString = String(bytes: newData, encoding: .utf8)! XCTAssertFalse(outString.contains("64C3EA1A-5161-2B94-1F50-606DA5EC0035")) XCTAssertTrue(outString.contains(newHost)) // swiftlint:disable:next line_length diff --git a/Tests/DataStreamTests.swift b/Tests/DataStreamTests.swift index 9037d27fc..40b2bf633 100644 --- a/Tests/DataStreamTests.swift +++ b/Tests/DataStreamTests.swift @@ -29,7 +29,7 @@ final class DataStreamTests: XCTestCase { } func test_small_data() async throws { - let data = "small test data".data(using: .utf8)! + let data = Data("small test data".utf8) let dataStream = DataStream( dataProvider: MockDataProvider(data: data), ranges: ByteRanges.rangesFor(contentLength: UInt(data.count), @@ -43,7 +43,7 @@ final class DataStreamTests: XCTestCase { } func test_small_data_with_large_rangeSize_returns_in_one_chunk() async throws { - let data = "small test data".data(using: .utf8)! + let data = Data("small test data".utf8) let dataStream = DataStream( dataProvider: MockDataProvider(data: data), ranges: ByteRanges.rangesFor(contentLength: UInt(data.count), diff --git a/ViewModel/BrowserViewModel.swift b/ViewModel/BrowserViewModel.swift index 14efa9a86..a584af8bf 100644 --- a/ViewModel/BrowserViewModel.swift +++ b/ViewModel/BrowserViewModel.swift @@ -588,13 +588,13 @@ final class BrowserViewModel: NSObject, ObservableObject, // open url actions.append( - UIAction(title: "common.dialog.button.open".localized, + UIAction(title: LocalString.common_dialog_button_open, image: UIImage(systemName: "doc.text")) { [weak self] _ in self?.webView.load(URLRequest(url: url)) } ) actions.append( - UIAction(title: "common.dialog.button.open_in_new_tab".localized, + UIAction(title: LocalString.common_dialog_button_open_in_new_tab, image: UIImage(systemName: "doc.badge.plus")) { [weak self] _ in guard let self else { return } Task { @MainActor in @@ -611,13 +611,13 @@ final class BrowserViewModel: NSObject, ObservableObject, if let bookmarks = try? context.fetch(request), !bookmarks.isEmpty { - return UIAction(title: "common.dialog.button.remove_bookmark".localized, + return UIAction(title: LocalString.common_dialog_button_remove_bookmark, image: UIImage(systemName: "star.slash.fill")) { [weak self] _ in self?.deleteBookmark(url: url) } } else { return UIAction( - title: "common.dialog.button.bookmark".localized, + title: LocalString.common_dialog_button_bookmark, image: UIImage(systemName: "star") ) { [weak self] _ in Task { @MainActor [weak self] in self?.createBookmark(url: url) } diff --git a/Views/Bookmarks.swift b/Views/Bookmarks.swift index eb2df052f..1af813be9 100644 --- a/Views/Bookmarks.swift +++ b/Views/Bookmarks.swift @@ -44,14 +44,14 @@ struct Bookmarks: View { } .modifier(GridCommon()) .modifier(ToolbarRoleBrowser()) - .navigationTitle("bookmark.navigation.title".localized) - .searchable(text: $searchText, prompt: "common.search".localized) + .navigationTitle(LocalString.bookmark_navigation_title) + .searchable(text: $searchText, prompt: LocalString.common_search) .onChange(of: searchText) { searchText in bookmarks.nsPredicate = Bookmarks.buildPredicate(searchText: searchText) } .overlay { if bookmarks.isEmpty { - Message(text: "bookmark.overlay.empty.title".localized) + Message(text: LocalString.bookmark_overlay_empty_title) } } .toolbar { @@ -61,7 +61,7 @@ struct Bookmarks: View { Button { NotificationCenter.toggleSidebar() } label: { - Label("bookmark.toolbar.show_sidebar.label".localized, systemImage: "sidebar.left") + Label(LocalString.bookmark_toolbar_show_sidebar_label, systemImage: "sidebar.left") } } } diff --git a/Views/BrowserTab.swift b/Views/BrowserTab.swift index 25e191a5f..0ec4ef8ae 100644 --- a/Views/BrowserTab.swift +++ b/Views/BrowserTab.swift @@ -38,7 +38,7 @@ struct BrowserTab: View { Button { NotificationCenter.toggleSidebar() } label: { - Label("browser_tab.toolbar.show_sidebar.label".localized, systemImage: "sidebar.left") + Label(LocalString.browser_tab_toolbar_show_sidebar_label, systemImage: "sidebar.left") } } NavigationButtons() @@ -62,7 +62,7 @@ struct BrowserTab: View { .focusedSceneValue(\.canGoBack, browser.canGoBack) .focusedSceneValue(\.canGoForward, browser.canGoForward) .modifier(ExternalLinkHandler(externalURL: $browser.externalURL)) - .searchable(text: $search.searchText, placement: .toolbar, prompt: "common.search".localized) + .searchable(text: $search.searchText, placement: .toolbar, prompt: LocalString.common_search) .onChange(of: scenePhase) { newValue in if case .active = newValue { browser.refreshVideoState() diff --git a/Views/BuildingBlocks/Attribute.swift b/Views/BuildingBlocks/Attribute.swift index b3002e80d..6b13e6bd3 100644 --- a/Views/BuildingBlocks/Attribute.swift +++ b/Views/BuildingBlocks/Attribute.swift @@ -23,7 +23,7 @@ struct Attribute: View { HStack { Text(title) Spacer() - Text(detail ?? "attribute.detail.unknown".localized).foregroundColor(.secondary) + Text(detail ?? LocalString.attribute_detail_unknown).foregroundColor(.secondary) } } } @@ -37,7 +37,7 @@ struct AttributeBool: View { Text(title) Spacer() #if os(macOS) - Text(detail ? "common.button.yes".localized : "common.button.no".localized).foregroundColor(.secondary) + Text(detail ? LocalString.common_button_yes : LocalString.common_button_no).foregroundColor(.secondary) #elseif os(iOS) if detail { Image(systemName: "checkmark.circle.fill").foregroundColor(.green) diff --git a/Views/BuildingBlocks/ContentSearchBar.swift b/Views/BuildingBlocks/ContentSearchBar.swift index f9369c7b3..2c242dec6 100644 --- a/Views/BuildingBlocks/ContentSearchBar.swift +++ b/Views/BuildingBlocks/ContentSearchBar.swift @@ -53,7 +53,7 @@ struct ContentSearchBar: View { private var field: some View { HStack { searchImage - TextField("common.search".localized, text: $viewModel.contentSearchText) + TextField(LocalString.common_search, text: $viewModel.contentSearchText) .textFieldStyle(.roundedBorder) HStack(spacing: 2) { leftButton diff --git a/Views/BuildingBlocks/ContentSearchButton.swift b/Views/BuildingBlocks/ContentSearchButton.swift index db08c573c..cef955020 100644 --- a/Views/BuildingBlocks/ContentSearchButton.swift +++ b/Views/BuildingBlocks/ContentSearchButton.swift @@ -22,7 +22,7 @@ struct ContentSearchButton: View { @EnvironmentObject private var browser: BrowserViewModel var body: some View { - Button("common.search".localized, + Button(LocalString.common_search, systemImage: "text.magnifyingglass", action: { browser.webView.isFindInteractionEnabled = true diff --git a/Views/BuildingBlocks/DownloadTaskCell.swift b/Views/BuildingBlocks/DownloadTaskCell.swift index 47aa67286..87c17564d 100644 --- a/Views/BuildingBlocks/DownloadTaskCell.swift +++ b/Views/BuildingBlocks/DownloadTaskCell.swift @@ -49,11 +49,11 @@ struct DownloadTaskCell: View { } VStack(alignment: .leading, spacing: 4) { if downloadZimFile.downloadTask?.error != nil { - Text("download_task_cell.status.failed".localized) + Text(LocalString.download_task_cell_status_failed) } else if downloadState.resumeData == nil { - Text("download_task_cell.status.downloading".localized) + Text(LocalString.download_task_cell_status_downloading) } else { - Text("download_task_cell.status.paused".localized) + Text(LocalString.download_task_cell_status_paused) } ProgressView( value: Float(downloadState.downloaded), diff --git a/Views/BuildingBlocks/FlavorTag.swift b/Views/BuildingBlocks/FlavorTag.swift index efec4548a..a39bafccf 100644 --- a/Views/BuildingBlocks/FlavorTag.swift +++ b/Views/BuildingBlocks/FlavorTag.swift @@ -48,11 +48,11 @@ struct FlavorTag: View { var help: String { switch flavor { case .max: - return "flavor_tag.help.max".localized + return LocalString.flavor_tag_help_max case .noPic: - return "flavor_tag.help.no_pic".localized + return LocalString.flavor_tag_help_no_pic case .mini: - return "flavor_tag.help.mini".localized + return LocalString.flavor_tag_help_mini } } } diff --git a/Views/BuildingBlocks/LibraryLastRefreshTime.swift b/Views/BuildingBlocks/LibraryLastRefreshTime.swift index 4607edcb3..da6815433 100644 --- a/Views/BuildingBlocks/LibraryLastRefreshTime.swift +++ b/Views/BuildingBlocks/LibraryLastRefreshTime.swift @@ -23,12 +23,12 @@ struct LibraryLastRefreshTime: View { var body: some View { if let lastRefresh = lastRefresh { if Date().timeIntervalSince(lastRefresh) < 120 { - Text("library_refresh_time.last".localized) + Text(LocalString.library_refresh_time_last) } else { Text(RelativeDateTimeFormatter().localizedString(for: lastRefresh, relativeTo: Date())) } } else { - Text("library_refresh_time.never".localized) + Text(LocalString.library_refresh_time_never) } } } diff --git a/Views/BuildingBlocks/LoadingView.swift b/Views/BuildingBlocks/LoadingView.swift index 30af9a547..0a62a5ecc 100644 --- a/Views/BuildingBlocks/LoadingView.swift +++ b/Views/BuildingBlocks/LoadingView.swift @@ -193,7 +193,7 @@ struct FetchingCatalogView: View { var body: some View { ZStack { LogoView() - LoadingMessageView(message: "welcome.button.status.fetching_catalog.text".localized) + LoadingMessageView(message: LocalString.welcome_button_status_fetching_catalog_text) }.ignoresSafeArea() } } @@ -202,7 +202,7 @@ struct LoadingDataView: View { var body: some View { ZStack { LogoView() - LoadingMessageView(message: "welcome.loading.data.text".localized) + LoadingMessageView(message: LocalString.welcome_loading_data_text) }.ignoresSafeArea() } } diff --git a/Views/BuildingBlocks/SheetContent.swift b/Views/BuildingBlocks/SheetContent.swift index 709b20fa1..d8c95800b 100644 --- a/Views/BuildingBlocks/SheetContent.swift +++ b/Views/BuildingBlocks/SheetContent.swift @@ -34,7 +34,7 @@ struct SheetContent: View { Button { dismiss() } label: { - Text("common.button.done".localized).fontWeight(.semibold) + Text(LocalString.common_button_done).fontWeight(.semibold) } } } diff --git a/Views/BuildingBlocks/TabLabel.swift b/Views/BuildingBlocks/TabLabel.swift index 9761e56d7..4d26b82c5 100644 --- a/Views/BuildingBlocks/TabLabel.swift +++ b/Views/BuildingBlocks/TabLabel.swift @@ -22,12 +22,12 @@ struct TabLabel: View { var body: some View { if let zimFile = tab.zimFile, let category = Category(rawValue: zimFile.category) { Label { - Text(tab.title ?? "common.tab.menu.new_tab".localized).lineLimit(1) + Text(tab.title ?? LocalString.common_tab_menu_new_tab).lineLimit(1) } icon: { Favicon(category: category, imageData: zimFile.faviconData).frame(width: 22, height: 22) } } else { - Label(tab.title ?? "common.tab.menu.new_tab".localized, systemImage: "square") + Label(tab.title ?? LocalString.common_tab_menu_new_tab, systemImage: "square") } } } diff --git a/Views/BuildingBlocks/ZimFileCell.swift b/Views/BuildingBlocks/ZimFileCell.swift index 7c182b45e..c79ef2ff9 100644 --- a/Views/BuildingBlocks/ZimFileCell.swift +++ b/Views/BuildingBlocks/ZimFileCell.swift @@ -70,7 +70,7 @@ struct ZimFileCell: View { HStack(alignment: .bottom) { VStack(alignment: .leading) { Text("\(zimFile.articleCount.formatted(.number.notation(.compactName))) " + - "zim_file_cell_article_count_suffix".localized) + LocalString.zim_file_cell_article_count_suffix) .font(.caption) Text(ZimFileCell.dateFormatter.string(from: zimFile.created)) .font(.caption) diff --git a/Views/BuildingBlocks/ZimFileMissingIndicator.swift b/Views/BuildingBlocks/ZimFileMissingIndicator.swift index 3d0553dcd..be50e3a4b 100644 --- a/Views/BuildingBlocks/ZimFileMissingIndicator.swift +++ b/Views/BuildingBlocks/ZimFileMissingIndicator.swift @@ -19,6 +19,6 @@ struct ZimFileMissingIndicator: View { var body: some View { Image(systemName: "exclamationmark.triangle.fill") .renderingMode(.original) - .help("zim_file_missing_indicator.help".localized) + .help(LocalString.zim_file_missing_indicator_help) } } diff --git a/Views/BuildingBlocks/ZimFileRow.swift b/Views/BuildingBlocks/ZimFileRow.swift index c039807ae..8ff986b8e 100644 --- a/Views/BuildingBlocks/ZimFileRow.swift +++ b/Views/BuildingBlocks/ZimFileRow.swift @@ -37,7 +37,7 @@ struct ZimFileRow: View { Formatter.size.string(fromByteCount: zimFile.size), { "\(zimFile.articleCount.formatted(.number.notation(.compactName))) " + - "zim_file_cell_article_count_suffix".localized + LocalString.zim_file_cell_article_count_suffix }() ].joined(separator: ", ")).font(.caption) } diff --git a/Views/Buttons/ArticleShortcutButtons.swift b/Views/Buttons/ArticleShortcutButtons.swift index 87a4fb68e..301b4505e 100644 --- a/Views/Buttons/ArticleShortcutButtons.swift +++ b/Views/Buttons/ArticleShortcutButtons.swift @@ -47,10 +47,10 @@ struct ArticleShortcutButtons: View { browser.loadMainArticle() dismissSearch() } label: { - Label("article_shortcut.main.button.title".localized, systemImage: "house") + Label(LocalString.article_shortcut_main_button_title, systemImage: "house") } .disabled(zimFiles.isEmpty) - .help("article_shortcut.main.button.help".localized) + .help(LocalString.article_shortcut_main_button_help) #elseif os(iOS) Menu { ForEach(zimFiles) { zimFile in @@ -60,13 +60,13 @@ struct ArticleShortcutButtons: View { } } } label: { - Label("article_shortcut.main.button.title".localized, systemImage: "house") + Label(LocalString.article_shortcut_main_button_title, systemImage: "house") } primaryAction: { browser.loadMainArticle() dismissSearch() } .disabled(zimFiles.isEmpty) - .help("article_shortcut.main.button.help".localized) + .help(LocalString.article_shortcut_main_button_help) #endif } @@ -76,10 +76,10 @@ struct ArticleShortcutButtons: View { browser.loadRandomArticle() dismissSearch() } label: { - Label("article_shortcut.random.button.title.mac".localized, systemImage: "die.face.5") + Label(LocalString.article_shortcut_random_button_title_mac, systemImage: "die.face.5") } .disabled(zimFiles.isEmpty) - .help("article_shortcut.random.button.help".localized) + .help(LocalString.article_shortcut_random_button_help) .keyboardShortcut(KeyEquivalent("r"), modifiers: [.command, .option]) #elseif os(iOS) @@ -91,13 +91,13 @@ struct ArticleShortcutButtons: View { } } } label: { - Label("article_shortcut.random.button.title.ios".localized, systemImage: "die.face.5") + Label(LocalString.article_shortcut_random_button_title_ios, systemImage: "die.face.5") } primaryAction: { browser.loadRandomArticle() dismissSearch() } .disabled(zimFiles.isEmpty) - .help("article_shortcut.random.button.help".localized) + .help(LocalString.article_shortcut_random_button_help) #endif } } diff --git a/Views/Buttons/BookmarkButton.swift b/Views/Buttons/BookmarkButton.swift index a5cba7151..8777d0e95 100644 --- a/Views/Buttons/BookmarkButton.swift +++ b/Views/Buttons/BookmarkButton.swift @@ -31,7 +31,7 @@ struct BookmarkButton: View { } label: { Label { Text(browser.articleBookmarked ? - "common.dialog.button.remove_bookmark".localized : "common.dialog.button.add_bookmark".localized) + LocalString.common_dialog_button_remove_bookmark : LocalString.common_dialog_button_add_bookmark) } icon: { Image(systemName: browser.articleBookmarked ? "star.fill" : "star") .renderingMode(browser.articleBookmarked ? .original : .template) @@ -43,23 +43,23 @@ struct BookmarkButton: View { Button(role: .destructive) { browser.deleteBookmark() } label: { - Label("common.dialog.button.remove_bookmark".localized, systemImage: "star.slash.fill") + Label(LocalString.common_dialog_button_remove_bookmark, systemImage: "star.slash.fill") } } else { Button { browser.createBookmark() } label: { - Label("common.dialog.button.add_bookmark".localized, systemImage: "star") + Label(LocalString.common_dialog_button_add_bookmark, systemImage: "star") } } Button { isShowingPopOver = true } label: { - Label("common.dialog.button.show_bookmarks".localized, systemImage: "list.star") + Label(LocalString.common_dialog_button_show_bookmarks, systemImage: "list.star") } } label: { Label { - Text("common.dialog.button.show_bookmarks".localized) + Text(LocalString.common_dialog_button_show_bookmarks) } icon: { Image(systemName: browser.articleBookmarked ? "star.fill" : "star") .renderingMode(browser.articleBookmarked ? .original : .template) @@ -67,7 +67,7 @@ struct BookmarkButton: View { } primaryAction: { isShowingPopOver = true } - .help("bookmark_button.show.help".localized) + .help(LocalString.bookmark_button_show_help) .popover(isPresented: $isShowingPopOver) { NavigationStack { Bookmarks().navigationBarTitleDisplayMode(.inline).toolbar { @@ -75,7 +75,7 @@ struct BookmarkButton: View { Button { isShowingPopOver = false } label: { - Text("common.button.done".localized).fontWeight(.semibold) + Text(LocalString.common_button_done).fontWeight(.semibold) } } ToolbarItem(placement: .navigationBarTrailing) { @@ -89,8 +89,8 @@ struct BookmarkButton: View { Label { Text( browser.articleBookmarked ? - "common.dialog.button.remove_bookmark".localized : - "common.dialog.button.add_bookmark".localized + LocalString.common_dialog_button_remove_bookmark : + LocalString.common_dialog_button_add_bookmark ) } icon: { Image(systemName: browser.articleBookmarked ? "star.fill" : "star") diff --git a/Views/Buttons/ExportButton.swift b/Views/Buttons/ExportButton.swift index 6235dca68..854a147d7 100644 --- a/Views/Buttons/ExportButton.swift +++ b/Views/Buttons/ExportButton.swift @@ -48,7 +48,7 @@ struct ExportButton: View { } } label: { Label { - Text("common.button.share".localized) + Text(LocalString.common_button_share) } icon: { Image(systemName: "square.and.arrow.up") } diff --git a/Views/Buttons/NavigationButtons.swift b/Views/Buttons/NavigationButtons.swift index 37d8fc19c..0099696f9 100644 --- a/Views/Buttons/NavigationButtons.swift +++ b/Views/Buttons/NavigationButtons.swift @@ -31,7 +31,7 @@ struct NavigationButtons: View { browser.webView.goBack() dismissSearch() } label: { - Label("common.button.go_back".localized, systemImage: "chevron.left") + Label(LocalString.common_button_go_back, systemImage: "chevron.left") }.disabled(!browser.canGoBack) } @@ -40,7 +40,7 @@ struct NavigationButtons: View { browser.webView.goForward() dismissSearch() } label: { - Label("common.button.go_forward".localized, systemImage: "chevron.right") + Label(LocalString.common_button_go_forward, systemImage: "chevron.right") }.disabled(!browser.canGoForward) } } diff --git a/Views/Buttons/OutlineButton.swift b/Views/Buttons/OutlineButton.swift index 909fafe86..782033c44 100644 --- a/Views/Buttons/OutlineButton.swift +++ b/Views/Buttons/OutlineButton.swift @@ -30,10 +30,10 @@ struct OutlineButton: View { } } } label: { - Label("outline_button.outline.title".localized, systemImage: "list.bullet") + Label(LocalString.outline_button_outline_title, systemImage: "list.bullet") } .disabled(browser.outlineItems.isEmpty) - .help("outline_button.outline.help".localized) + .help(LocalString.outline_button_outline_help) #elseif os(iOS) Button { isShowingOutline = true @@ -41,12 +41,12 @@ struct OutlineButton: View { Image(systemName: "list.bullet") } .disabled(browser.outlineItems.isEmpty) - .help("outline_button.outline.help".localized) + .help(LocalString.outline_button_outline_help) .popover(isPresented: $isShowingOutline) { NavigationStack { Group { if browser.outlineItemTree.isEmpty { - Message(text: "outline_button.outline.empty.message".localized) + Message(text: LocalString.outline_button_outline_empty_message) } else { List(browser.outlineItemTree) { item in OutlineNode(item: item) { item in @@ -64,7 +64,7 @@ struct OutlineButton: View { Button { isShowingOutline = false } label: { - Text("common.button.done".localized).fontWeight(.semibold) + Text(LocalString.common_button_done).fontWeight(.semibold) } } } diff --git a/Views/Buttons/PrintButton.swift b/Views/Buttons/PrintButton.swift index faf05623d..114c9946c 100644 --- a/Views/Buttons/PrintButton.swift +++ b/Views/Buttons/PrintButton.swift @@ -46,7 +46,7 @@ struct PrintButton: View { } } label: { Label { - Text("common.button.print".localized) + Text(LocalString.common_button_print) } icon: { Image(systemName: "printer") } diff --git a/Views/Buttons/SupportKiwixButton.swift b/Views/Buttons/SupportKiwixButton.swift index 5fbd5bc3b..8867f2d10 100644 --- a/Views/Buttons/SupportKiwixButton.swift +++ b/Views/Buttons/SupportKiwixButton.swift @@ -27,7 +27,7 @@ struct SupportKiwixButton: View { HStack { Image(systemName: "heart.fill") .foregroundStyle(.red) - Text("payment.support_button.label".localized) + Text(LocalString.payment_support_button_label) } #if os(macOS) .padding(6) diff --git a/Views/Buttons/TabsManagerButton.swift b/Views/Buttons/TabsManagerButton.swift index 1496ce943..1a80f99af 100644 --- a/Views/Buttons/TabsManagerButton.swift +++ b/Views/Buttons/TabsManagerButton.swift @@ -32,22 +32,22 @@ struct TabsManagerButton: View { Button { navigation.createTab() } label: { - Label("common.tab.menu.new_tab".localized, systemImage: "plus.square") + Label(LocalString.common_tab_menu_new_tab, systemImage: "plus.square") } Button(role: .destructive) { guard case .tab(let tabID) = navigation.currentItem else { return } navigation.deleteTab(tabID: tabID) } label: { - Label("common.tab.menu.close_this".localized, systemImage: "xmark.square") + Label(LocalString.common_tab_menu_close_this, systemImage: "xmark.square") } Button(role: .destructive) { navigation.deleteAllTabs() } label: { - Label("common.tab.menu.close_all".localized, systemImage: "xmark.square.fill") + Label(LocalString.common_tab_menu_close_all, systemImage: "xmark.square.fill") } } } label: { - Label("common.tab.manager.title".localized, systemImage: "square.stack") + Label(LocalString.common_tab_manager_title, systemImage: "square.stack") } primaryAction: { presentedSheet = .tabsManager } @@ -60,7 +60,7 @@ struct TabsManagerButton: View { Button { self.presentedSheet = nil } label: { - Text("common.button.done".localized).fontWeight(.semibold) + Text(LocalString.common_button_done).fontWeight(.semibold) } } } @@ -92,12 +92,12 @@ struct TabManager: View { Button(role: .destructive) { navigation.deleteTab(tabID: tab.objectID) } label: { - Label("common.tab.list.close".localized, systemImage: "xmark") + Label(LocalString.common_tab_list_close, systemImage: "xmark") } } } .listStyle(.plain) - .navigationTitle("common.tab.navigation.title".localized) + .navigationTitle(LocalString.common_tab_navigation_title) .navigationBarTitleDisplayMode(.inline) .toolbar { Menu { @@ -105,15 +105,15 @@ struct TabManager: View { guard case let .tab(tabID) = navigation.currentItem else { return } navigation.deleteTab(tabID: tabID) } label: { - Label("common.tab.menu.close_this".localized, systemImage: "xmark.square") + Label(LocalString.common_tab_menu_close_this, systemImage: "xmark.square") } Button(role: .destructive) { navigation.deleteAllTabs() } label: { - Label("common.tab.menu.close_all".localized, systemImage: "xmark.square.fill") + Label(LocalString.common_tab_menu_close_all, systemImage: "xmark.square.fill") } } label: { - Label("common.tab.menu.new_tab".localized, systemImage: "plus.square") + Label(LocalString.common_tab_menu_new_tab, systemImage: "plus.square") } primaryAction: { navigation.createTab() } diff --git a/Views/Commands.swift b/Views/Commands.swift index 82eb71d9e..f1ab6b4b8 100644 --- a/Views/Commands.swift +++ b/Views/Commands.swift @@ -61,10 +61,10 @@ struct NavigationCommands: View { @FocusedValue(\.browserViewModel) var browser: BrowserViewModel? var body: some View { - Button("common.button.go_back".localized) { browser?.webView.goBack() } + Button(LocalString.common_button_go_back) { browser?.webView.goBack() } .keyboardShortcut("[") .disabled(canGoBack != true) - Button("common.button.go_forward".localized) { browser?.webView.goForward() } + Button(LocalString.common_button_go_forward) { browser?.webView.goForward() } .keyboardShortcut("]") .disabled(canGoForward != true) } @@ -75,13 +75,13 @@ struct PageZoomCommands: View { @FocusedValue(\.browserViewModel) var browser: BrowserViewModel? var body: some View { - Button("commands.button.actual_size".localized) { webViewPageZoom = 1 } + Button(LocalString.commands_button_actual_size) { webViewPageZoom = 1 } .keyboardShortcut("0") .disabled(webViewPageZoom == 1 || browser?.url == nil) - Button("comments.button.zoom_in".localized) { webViewPageZoom += 0.1 } + Button(LocalString.comments_button_zoom_in) { webViewPageZoom += 0.1 } .keyboardShortcut("+") .disabled(webViewPageZoom >= 2 || browser?.url == nil) - Button("comments.button.zoom_out".localized) { webViewPageZoom -= 0.1 } + Button(LocalString.comments_button_zoom_out) { webViewPageZoom -= 0.1 } .keyboardShortcut("-") .disabled(webViewPageZoom <= 0.5 || browser?.url == nil) } diff --git a/Views/Library/Library.swift b/Views/Library/Library.swift index 9a562c993..3bcf3a8d0 100644 --- a/Views/Library/Library.swift +++ b/Views/Library/Library.swift @@ -100,7 +100,7 @@ struct LibraryZimFileDetailSidePanel: ViewModifier { if let zimFile = viewModel.selectedZimFile { ZimFileDetail(zimFile: zimFile, dismissParent: nil) } else { - Message(text: "library.zim_file_details.side_panel.message".localized) + Message(text: LocalString.library_zim_file_details_side_panel_message) .background(.thickMaterial) } }.frame(width: 275).background(.ultraThinMaterial) @@ -153,13 +153,13 @@ struct LibraryZimFileContext: ViewModifier { guard let url = await ZimFileService.shared.getMainPageURL(zimFileID: zimFile.fileID) else { return } NotificationCenter.openURL(url, inNewTab: true) } label: { - Label("library.zim_file_context.main_page.label".localized, systemImage: "house") + Label(LocalString.library_zim_file_context_main_page_label, systemImage: "house") } AsyncButton { guard let url = await ZimFileService.shared.getRandomPageURL(zimFileID: zimFile.fileID) else { return } NotificationCenter.openURL(url, inNewTab: true) } label: { - Label("library.zim_file_context.random.label".localized, systemImage: "die.face.5") + Label(LocalString.library_zim_file_context_random_label, systemImage: "die.face.5") } } @@ -174,7 +174,7 @@ struct LibraryZimFileContext: ViewModifier { UIPasteboard.general.setValue(downloadURL.absoluteString, forPasteboardType: UTType.url.identifier) #endif } label: { - Label("library.zim_file_context.copy_url".localized, systemImage: "doc.on.doc") + Label(LocalString.library_zim_file_context_copy_url, systemImage: "doc.on.doc") } } Button { @@ -185,7 +185,7 @@ struct LibraryZimFileContext: ViewModifier { UIPasteboard.general.setValue(zimFile.fileID.uuidString, forPasteboardType: UTType.plainText.identifier) #endif } label: { - Label("library.zim_file_context.copy_id".localized, systemImage: "barcode.viewfinder") + Label(LocalString.library_zim_file_context_copy_id, systemImage: "barcode.viewfinder") } } } diff --git a/Views/Library/ZimFileDetail.swift b/Views/Library/ZimFileDetail.swift index ff8f9a1e9..298602a20 100644 --- a/Views/Library/ZimFileDetail.swift +++ b/Views/Library/ZimFileDetail.swift @@ -41,12 +41,12 @@ struct ZimFileDetail: View { var body: some View { #if os(macOS) List { - Section("zim_file.list.name.text".localized) { Text(zimFile.name).lineLimit(nil) }.collapsible(false) - Section("zim_file.list.description.text".localized) { + Section(LocalString.zim_file_list_name_text) { Text(zimFile.name).lineLimit(nil) }.collapsible(false) + Section(LocalString.zim_file_list_description_text) { Text(zimFile.fileDescription).lineLimit(nil) }.collapsible(false) - Section("zim_file.list.actions.text".localized) { actions }.collapsible(false) - Section("zim_file.list.info.text".localized) { + Section(LocalString.zim_file_list_actions_text) { actions }.collapsible(false) + Section(LocalString.zim_file_list_info_text) { basicInfo boolInfo counts @@ -104,10 +104,10 @@ struct ZimFileDetail: View { if zimFile.downloadTask != nil { // zim file is being downloaded DownloadTaskDetail(downloadZimFile: zimFile) } else if zimFile.isMissing { // zim file was opened, but is now missing - Action(title: "zim_file.action.locate.title".localized) { isPresentingFileLocator = true } + Action(title: LocalString.zim_file_action_locate_title) { isPresentingFileLocator = true } unlinkAction } else if zimFile.fileURLBookmark != nil { // zim file is opened - Action(title: "zim_file.action.open_main_page.title".localized) { + Action(title: LocalString.zim_file_action_open_main_page_title) { guard let url = await ZimFileService.shared.getMainPageURL(zimFileID: zimFile.fileID) else { return } NotificationCenter.openURL(url, inNewTab: true) #if os(iOS) @@ -115,7 +115,7 @@ struct ZimFileDetail: View { #endif } #if os(macOS) - Action(title: "zim_file.action.reveal_in_finder.title".localized) { + Action(title: LocalString.zim_file_action_reveal_in_finder_title) { guard let url = await ZimFileService.shared.getFileURL(zimFileID: zimFile.id) else { return } NSWorkspace.shared.activateFileViewerSelecting([url]) } @@ -129,20 +129,20 @@ struct ZimFileDetail: View { #endif } else if zimFile.downloadURL != nil { // zim file can be downloaded #if os(iOS) - Toggle("zim_file.action.toggle_cellular".localized, isOn: $downloadUsingCellular) + Toggle(LocalString.zim_file_action_toggle_cellular, isOn: $downloadUsingCellular) #endif downloadAction } } var unlinkAction: some View { - Action(title: "zim_file.action.unlink.title".localized, isDestructive: true) { + Action(title: LocalString.zim_file_action_unlink_title, isDestructive: true) { isPresentingUnlinkAlert = true }.alert(isPresented: $isPresentingUnlinkAlert) { Alert( - title: Text("zim_file.action.unlink.title".localized + " " + zimFile.name), - message: Text("zim_file.action.unlink.message".localized), - primaryButton: .destructive(Text("zim_file.action.unlink.button.title".localized)) { + title: Text(LocalString.zim_file_action_unlink_title + " " + zimFile.name), + message: Text(LocalString.zim_file_action_unlink_message), + primaryButton: .destructive(Text(LocalString.zim_file_action_unlink_button_title)) { Task { await LibraryOperations.unlink(zimFileID: zimFile.fileID) #if os(iOS) @@ -156,13 +156,13 @@ struct ZimFileDetail: View { } var deleteAction: some View { - Action(title: "zim_file.action.delete.title".localized, isDestructive: true) { + Action(title: LocalString.zim_file_action_delete_title, isDestructive: true) { isPresentingDeleteAlert = true }.alert(isPresented: $isPresentingDeleteAlert) { Alert( - title: Text("zim_file.action.delete.title".localized + " " + zimFile.name), - message: Text("zim_file.action.delete.message".localized), - primaryButton: .destructive(Text("zim_file.action.delete.button.title".localized)) { + title: Text(LocalString.zim_file_action_delete_title + " " + zimFile.name), + message: Text(LocalString.zim_file_action_delete_message), + primaryButton: .destructive(Text(LocalString.zim_file_action_delete_button_title)) { Task { await LibraryOperations.delete(zimFileID: zimFile.fileID) #if os(iOS) @@ -176,7 +176,7 @@ struct ZimFileDetail: View { } var downloadAction: some View { - Action(title: "zim_file.action.download.title".localized) { + Action(title: LocalString.zim_file_action_download_title) { if let freeSpace = freeSpace, zimFile.size >= freeSpace - 10^9 { isPresentingDownloadAlert = true } else { @@ -184,15 +184,15 @@ struct ZimFileDetail: View { } }.alert(isPresented: $isPresentingDownloadAlert) { Alert( - title: Text("zim_file.action.download.warning.title".localized), + title: Text(LocalString.zim_file_action_download_warning_title), message: Text({ if let freeSpace = freeSpace, zimFile.size > freeSpace { - return "zim_file.action.download.warning.message".localized + return LocalString.zim_file_action_download_warning_message } else { - return "zim_file.action.download.warning.message1".localized + return LocalString.zim_file_action_download_warning_message1 } }()), - primaryButton: .default(Text("zim_file.action.download.button.anyway".localized)) { + primaryButton: .default(Text(LocalString.zim_file_action_download_button_anyway)) { DownloadService.shared.start( zimFileID: zimFile.id, allowsCellularAccess: false @@ -205,23 +205,23 @@ struct ZimFileDetail: View { @ViewBuilder var basicInfo: some View { - Attribute(title: "zim_file.base_info.attribute.language".localized, + Attribute(title: LocalString.zim_file_base_info_attribute_language, detail: zimFile.languageCodesListed) - Attribute(title: "zim_file.base_info.attribute.category".localized, + Attribute(title: LocalString.zim_file_base_info_attribute_category, detail: Category(rawValue: zimFile.category)?.name) - Attribute(title: "zim_file.base_info.attribute.size".localized, + Attribute(title: LocalString.zim_file_base_info_attribute_size, detail: Formatter.size.string(fromByteCount: zimFile.size)) - Attribute(title: "zim_file.base_info.attribute.created".localized, + Attribute(title: LocalString.zim_file_base_info_attribute_created, detail: Formatter.dateMedium.string(from: zimFile.created)) } @ViewBuilder var boolInfo: some View { - AttributeBool(title: "zim_file.bool_info.pictures".localized, detail: zimFile.hasPictures) - AttributeBool(title: "zim_file.bool_info.videos".localized, detail: zimFile.hasVideos) - AttributeBool(title: "zim_file.bool_info.details".localized, detail: zimFile.hasDetails) + AttributeBool(title: LocalString.zim_file_bool_info_pictures, detail: zimFile.hasPictures) + AttributeBool(title: LocalString.zim_file_bool_info_videos, detail: zimFile.hasVideos) + AttributeBool(title: LocalString.zim_file_bool_info_details, detail: zimFile.hasDetails) if zimFile.requiresServiceWorkers { - AttributeBool(title: "zim_file.bool_info.require_service_workers".localized, + AttributeBool(title: LocalString.zim_file_bool_info_require_service_workers, detail: zimFile.requiresServiceWorkers) } } @@ -229,18 +229,18 @@ struct ZimFileDetail: View { @ViewBuilder var counts: some View { Attribute( - title: "zim_file.counts.article_count".localized, + title: LocalString.zim_file_counts_article_count, detail: Formatter.number.string(from: NSNumber(value: zimFile.articleCount)) ) Attribute( - title: "zim_file.counts.article.media_count".localized, + title: LocalString.zim_file_counts_article_media_count, detail: Formatter.number.string(from: NSNumber(value: zimFile.mediaCount)) ) } @ViewBuilder var id: some View { - Attribute(title: "zim_file.detail.id.title".localized, detail: String(zimFile.fileID.uuidString.prefix(8))) + Attribute(title: LocalString.zim_file_detail_id_title, detail: String(zimFile.fileID.uuidString.prefix(8))) } private var freeSpace: Int64? { @@ -273,28 +273,28 @@ private struct DownloadTaskDetail: View { var body: some View { Group { - Action(title: "zim_file.download_task.action.title.cancel".localized, isDestructive: true) { + Action(title: LocalString.zim_file_download_task_action_title_cancel, isDestructive: true) { DownloadService.shared.cancel(zimFileID: downloadZimFile.fileID) viewModel.selectedZimFile = nil } if let error = downloadZimFile.downloadTask?.error { if downloadState.resumeData != nil { - Action(title: "zim_file.download_task.action.try_recover".localized) { + Action(title: LocalString.zim_file_download_task_action_try_recover) { DownloadService.shared.resume(zimFileID: downloadZimFile.fileID) } } - Attribute(title: "zim_file.download_task.action.failed".localized, detail: detail) + Attribute(title: LocalString.zim_file_download_task_action_failed, detail: detail) Text(error) } else if downloadState.resumeData == nil { - Action(title: "zim_file.download_task.action.pause".localized) { + Action(title: LocalString.zim_file_download_task_action_pause) { DownloadService.shared.pause(zimFileID: downloadZimFile.fileID) } - Attribute(title: "zim_file.download_task.action.downloading".localized, detail: detail) + Attribute(title: LocalString.zim_file_download_task_action_downloading, detail: detail) } else { - Action(title: "zim_file.download_task.action.resume".localized) { + Action(title: LocalString.zim_file_download_task_action_resume) { DownloadService.shared.resume(zimFileID: downloadZimFile.fileID) } - Attribute(title: "zim_file.download_task.action.paused".localized, detail: detail) + Attribute(title: LocalString.zim_file_download_task_action_paused, detail: detail) } }.onReceive( DownloadService.shared.progress.publisher @@ -357,7 +357,7 @@ private struct Action: View { private struct ServiceWorkerWarning: View { var body: some View { Label { - Text("service_worker_warning.label.description".localized) + Text(LocalString.service_worker_warning_label_description) } icon: { Image(systemName: "exclamationmark.triangle.fill").renderingMode(.original) } diff --git a/Views/Library/ZimFilesCategories.swift b/Views/Library/ZimFilesCategories.swift index 13edeed15..25d716bd7 100644 --- a/Views/Library/ZimFilesCategories.swift +++ b/Views/Library/ZimFilesCategories.swift @@ -44,13 +44,13 @@ struct ZimFilesCategories: View { Button { NotificationCenter.toggleSidebar() } label: { - Label("zim_file_opened.toolbar.show_sidebar.label".localized, systemImage: "sidebar.left") + Label(LocalString.zim_file_opened_toolbar_show_sidebar_label, systemImage: "sidebar.left") } } } #endif ToolbarItem { - Picker("zim_file_category.title".localized, selection: $selected) { + Picker(LocalString.zim_file_category_title, selection: $selected) { ForEach(categories) { Text($0.name).tag($0) } @@ -128,11 +128,11 @@ private struct CategoryGrid: View { if sections.isEmpty { switch viewModel.state { case .inProgress: - Message(text: "zim_file_catalog.fetching.message".localized) + Message(text: LocalString.zim_file_catalog_fetching_message) case .error: - Message(text: "library_refresh_error.retrieve.description".localized, color: .red) + Message(text: LocalString.library_refresh_error_retrieve_description, color: .red) case .initial, .complete: - Message(text: "zim_file_category.section.empty.message".localized) + Message(text: LocalString.zim_file_category_section_empty_message) } } else { LazyVGrid(columns: ([gridItem]), alignment: .leading, spacing: 12) { @@ -236,11 +236,11 @@ private struct CategoryList: View { if zimFiles.isEmpty { switch viewModel.state { case .inProgress: - Message(text: "zim_file_catalog.fetching.message".localized) + Message(text: LocalString.zim_file_catalog_fetching_message) case .error: - Message(text: "library_refresh_error.retrieve.description".localized, color: .red) + Message(text: LocalString.library_refresh_error_retrieve_description, color: .red) case .initial, .complete: - Message(text: "zim_file_category.section.empty.message".localized) + Message(text: LocalString.zim_file_category_section_empty_message) } } else { List(zimFiles, id: \.self, selection: $viewModel.selectedZimFile) { zimFile in diff --git a/Views/Library/ZimFilesDownloads.swift b/Views/Library/ZimFilesDownloads.swift index d4cab148a..0e28a270d 100644 --- a/Views/Library/ZimFilesDownloads.swift +++ b/Views/Library/ZimFilesDownloads.swift @@ -46,7 +46,7 @@ struct ZimFilesDownloads: View { .navigationTitle(NavigationItem.downloads.name) .overlay { if downloadTasks.isEmpty { - Message(text: "zim_file_downloads.overlay.empty.message".localized) + Message(text: LocalString.zim_file_downloads_overlay_empty_message) } } .toolbar { @@ -56,7 +56,7 @@ struct ZimFilesDownloads: View { Button { NotificationCenter.toggleSidebar() } label: { - Label("zim_file_downloads.toolbar.show_sidebar.label".localized, systemImage: "sidebar.left") + Label(LocalString.zim_file_downloads_toolbar_show_sidebar_label, systemImage: "sidebar.left") } } } diff --git a/Views/Library/ZimFilesNew.swift b/Views/Library/ZimFilesNew.swift index 1fd8ccfa5..276fc68b9 100644 --- a/Views/Library/ZimFilesNew.swift +++ b/Views/Library/ZimFilesNew.swift @@ -58,11 +58,11 @@ struct ZimFilesNew: View { if zimFiles.isEmpty { switch viewModel.state { case .inProgress: - Message(text: "zim_file_catalog.fetching.message".localized) + Message(text: LocalString.zim_file_catalog_fetching_message) case .error: - Message(text: "library_refresh_error.retrieve.description".localized, color: .red) + Message(text: LocalString.library_refresh_error_retrieve_description, color: .red) case .initial, .complete: - Message(text: "zim_file_new_overlay.empty".localized) + Message(text: LocalString.zim_file_new_overlay_empty) } } } @@ -73,7 +73,7 @@ struct ZimFilesNew: View { Button { NotificationCenter.toggleSidebar() } label: { - Label("zim_file_opened.toolbar.show_sidebar.label".localized, + Label(LocalString.zim_file_opened_toolbar_show_sidebar_label, systemImage: "sidebar.left") } } @@ -89,7 +89,7 @@ struct ZimFilesNew: View { Button { viewModel.start(isUserInitiated: true) } label: { - Label("zim_file_new_button_refresh".localized, + Label(LocalString.zim_file_new_button_refresh, systemImage: "arrow.triangle.2.circlepath.circle") } } diff --git a/Views/Library/ZimFilesOpened.swift b/Views/Library/ZimFilesOpened.swift index 62ab34f9a..c98123336 100644 --- a/Views/Library/ZimFilesOpened.swift +++ b/Views/Library/ZimFilesOpened.swift @@ -44,7 +44,7 @@ struct ZimFilesOpened: View { .navigationTitle(NavigationItem.opened.name) .overlay { if zimFiles.isEmpty { - Message(text: "zim_file_opened.overlay.no-opened.message".localized) + Message(text: LocalString.zim_file_opened_overlay_no_opened_message) } } .onChange(of: zimFiles.count) { _ in @@ -66,7 +66,7 @@ struct ZimFilesOpened: View { Button { NotificationCenter.toggleSidebar() } label: { - Label("zim_file_opened.toolbar.show_sidebar.label".localized, systemImage: "sidebar.left") + Label(LocalString.zim_file_opened_toolbar_show_sidebar_label, systemImage: "sidebar.left") } } } @@ -75,8 +75,8 @@ struct ZimFilesOpened: View { Button { isFileImporterPresented = true } label: { - Label("zim_file_opened.toolbar.open.title".localized, systemImage: "plus") - }.help("zim_file_opened.toolbar.open.help".localized) + Label(LocalString.zim_file_opened_toolbar_open_title, systemImage: "plus") + }.help(LocalString.zim_file_opened_toolbar_open_help) } } } diff --git a/Views/LocalLibraryList.swift b/Views/LocalLibraryList.swift index 01a0b9b52..f3df20692 100644 --- a/Views/LocalLibraryList.swift +++ b/Views/LocalLibraryList.swift @@ -36,7 +36,7 @@ struct LocalLibraryList: View { alignment: .leading, spacing: 12 ) { - GridSection(title: "welcome.main_page.title".localized) { + GridSection(title: LocalString.welcome_main_page_title) { ForEach(zimFiles) { zimFile in AsyncButtonView { guard let url = await ZimFileService.shared @@ -51,7 +51,7 @@ struct LocalLibraryList: View { } } if !bookmarks.isEmpty { - GridSection(title: "welcome.grid.bookmarks.title".localized) { + GridSection(title: LocalString.welcome_grid_bookmarks_title) { ForEach(bookmarks.prefix(6)) { bookmark in Button { browser.load(url: bookmark.articleURL) diff --git a/Views/Payment/CustomAmount.swift b/Views/Payment/CustomAmount.swift index fe2029d4b..27b8f65db 100644 --- a/Views/Payment/CustomAmount.swift +++ b/Views/Payment/CustomAmount.swift @@ -34,7 +34,7 @@ struct CustomAmount: View { Spacer() List { HStack { - TextField("payment.textfield.custom_amount.label".localized, + TextField(LocalString.payment_textfield_custom_amount_label, value: $customAmount, format: .number.precision(.fractionLength(2))) .focused($focusedField, equals: .customAmount) @@ -69,7 +69,7 @@ struct CustomAmount: View { ) } } label: { - Text("payment.confirm.button.title".localized) + Text(LocalString.payment_confirm_button_title) } .buttonStyle(BorderedProminentButtonStyle()) .padding() diff --git a/Views/Payment/ListOfAmounts.swift b/Views/Payment/ListOfAmounts.swift index 486a761fe..725b51345 100644 --- a/Views/Payment/ListOfAmounts.swift +++ b/Views/Payment/ListOfAmounts.swift @@ -51,9 +51,9 @@ struct ListOfAmounts: View { private func listing() -> some View { let items = isMonthly ? Payment.monthlies : Payment.oneTimes let averageText: String = if isMonthly { - "payment.selection.average_monthly_donation.subtitle".localized + LocalString.payment_selection_average_monthly_donation_subtitle } else { - "payment.selection.last_year_average.subtitle".localized + LocalString.payment_selection_last_year_average_subtitle } let defaultCurrency: String = Payment.defaultCurrencyCode return List { @@ -84,7 +84,7 @@ struct ListOfAmounts: View { Button(action: { listState = .customAmount }, label: { - Text("payment.selection.custom_amount".localized) + Text(LocalString.payment_selection_custom_amount) }) .padding(6) } diff --git a/Views/Payment/PaymentForm.swift b/Views/Payment/PaymentForm.swift index 966211950..78bda3d45 100644 --- a/Views/Payment/PaymentForm.swift +++ b/Views/Payment/PaymentForm.swift @@ -36,7 +36,7 @@ struct PaymentForm: View { #if os(iOS) HStack { Spacer() - Text("payment.donate.title".localized) + Text(LocalString.payment_donate_title) .font(.title) .padding(.init(top: 12, leading: 0, bottom: 8, trailing: 0)) Spacer() @@ -54,8 +54,8 @@ struct PaymentForm: View { VStack { // Re-enable as part of: https://github.com/kiwix/kiwix-apple/issues/1032 // Picker("", selection: $isMonthly) { -// Label("payment.selection.option.one_time".localized, systemImage: "heart.circle").tag(false) -// Label("payment.selection.option.monthly".localized, systemImage: "arrow.clockwise.heart").tag(true) +// Label(LocalString.payment_selection_option_one_time, systemImage: "heart.circle").tag(false) +// Label(LocalString.payment_selection_option_monthly, systemImage: "arrow.clockwise.heart").tag(true) // }.pickerStyle(.segmented) // .padding([.leading, .trailing, .bottom]) @@ -63,7 +63,7 @@ struct PaymentForm: View { } #if os(macOS) .padding() - .navigationTitle("payment.donate.title".localized) + .navigationTitle(LocalString.payment_donate_title) .onReceive(formReset.objectWillChange) { _ in reset() } diff --git a/Views/Payment/PaymentResultPopUp.swift b/Views/Payment/PaymentResultPopUp.swift index 0d8ffda74..46f98e9b6 100644 --- a/Views/Payment/PaymentResultPopUp.swift +++ b/Views/Payment/PaymentResultPopUp.swift @@ -42,14 +42,14 @@ struct PaymentResultPopUp: View { VStack(spacing: 16) { switch state { case .thankYou: - Text("payment.success.title".localized) + Text(LocalString.payment_success_title) .font(.title) - Text("payment.success.description".localized) + Text(LocalString.payment_success_description) .font(.headline) case .error: - Text("payment.error.title".localized) + Text(LocalString.payment_error_title) .font(.title) - Text("payment.error.description".localized) + Text(LocalString.payment_error_description) .font(.headline) } diff --git a/Views/Payment/PaymentSummary.swift b/Views/Payment/PaymentSummary.swift index 2ff62f512..7f0a7741a 100644 --- a/Views/Payment/PaymentSummary.swift +++ b/Views/Payment/PaymentSummary.swift @@ -34,14 +34,14 @@ struct PaymentSummary: View { var body: some View { VStack { - Text("payment.summary_page.title".localized) + Text(LocalString.payment_summary_page_title) .font(.largeTitle) .padding() if selectedAmount.isMonthly { - Text("payment.selection.option.monthly".localized).font(.title) + Text(LocalString.payment_selection_option_monthly).font(.title) .padding() } else { - Text("payment.selection.option.one_time".localized).font(.title) + Text(LocalString.payment_selection_option_one_time).font(.title) .padding() } Text(selectedAmount.value.formatted(.currency(code: selectedAmount.currency))).font(.title).bold() @@ -58,7 +58,7 @@ struct PaymentSummary: View { .frame(width: 186, height: 44) .padding() } else { - Text("payment.support_fallback_message".localized) + Text(LocalString.payment_support_fallback_message) .foregroundStyle(.red) .font(.callout) } diff --git a/Views/SearchResults.swift b/Views/SearchResults.swift index 2f102a996..3c26bf275 100644 --- a/Views/SearchResults.swift +++ b/Views/SearchResults.swift @@ -36,7 +36,7 @@ struct SearchResults: View { var body: some View { Group { if zimFiles.isEmpty { - Message(text: "search_result.zimfile.empty.message".localized) + Message(text: LocalString.search_result_zimfile_empty_message) } else if horizontalSizeClass == .regular { HStack(spacing: 0) { #if os(macOS) @@ -74,7 +74,7 @@ struct SearchResults: View { Spacer() } } else if viewModel.results.isEmpty { - Message(text: "search_result.zimfile.no_result.message".localized) + Message(text: LocalString.search_result_zimfile_no_result_message) } else { ScrollViewReader { scrollReader in ScrollView { @@ -137,7 +137,7 @@ struct SearchResults: View { Button(searchText) { viewModel.searchText = searchText }.swipeActions { - Button("search_result.sidebar.button.remove".localized, role: .destructive) { + Button(LocalString.search_result_sidebar_button_remove, role: .destructive) { recentSearchTexts.removeAll { $0 == searchText } } } @@ -168,33 +168,33 @@ struct SearchResults: View { private var recentSearchHeader: some View { HStack { - Text("search_result.header.text".localized) + Text(LocalString.search_result_header_text) Spacer() Button { recentSearchTexts.removeAll() } label: { - Text("search_result.button.clear".localized).font(.caption).fontWeight(.medium) + Text(LocalString.search_result_button_clear).font(.caption).fontWeight(.medium) } } } private var searchFilterHeader: some View { HStack { - Text("search_result.filter_hearder.text".localized) + Text(LocalString.search_result_filter_hearder_text) Spacer() if zimFiles.count == zimFiles.filter({ $0.includedInSearch }).count { Button { zimFiles.forEach { $0.includedInSearch = false } try? managedObjectContext.save() } label: { - Text("search_result.filter_hearder.button.none".localized).font(.caption).fontWeight(.medium) + Text(LocalString.search_result_filter_hearder_button_none).font(.caption).fontWeight(.medium) } } else { Button { zimFiles.forEach { $0.includedInSearch = true } try? managedObjectContext.save() } label: { - Text("search_result.filter_hearder.button.all".localized).font(.caption).fontWeight(.medium) + Text(LocalString.search_result_filter_hearder_button_all).font(.caption).fontWeight(.medium) } } } diff --git a/Views/Settings/About.swift b/Views/Settings/About.swift index 9eaea56db..ca9dcbffe 100644 --- a/Views/Settings/About.swift +++ b/Views/Settings/About.swift @@ -24,29 +24,29 @@ struct About: View { var body: some View { #if os(macOS) VStack(spacing: 16) { - SettingSection(name: "settings.about.title".localized) { + SettingSection(name: LocalString.settings_about_title) { about ourWebsite } - SettingSection(name: "settings.about.release".localized) { + SettingSection(name: LocalString.settings_about_release) { release HStack { source license } } - SettingSection(name: "settings.about.dependencies".localized, alignment: .top) { + SettingSection(name: LocalString.settings_about_dependencies, alignment: .top) { Table(dependencies) { - TableColumn("settings.about.dependencies.name".localized, value: \.name) - TableColumn("settings.about.dependencies.license".localized) { dependency in + TableColumn(LocalString.settings_about_dependencies_name, value: \.name) + TableColumn(LocalString.settings_about_dependencies_license) { dependency in Text(dependency.license ?? "") } - TableColumn("settings.about.dependencies.version".localized, value: \.version) + TableColumn(LocalString.settings_about_dependencies_version, value: \.version) }.tableStyle(.bordered(alternatesRowBackgrounds: true)) } } .padding() - .tabItem { Label("settings.about.title".localized, systemImage: "info.circle") } + .tabItem { Label(LocalString.settings_about_title, systemImage: "info.circle") } .task { await getDependencies() } .onChange(of: externalLinkURL) { url in guard let url = url else { return } @@ -58,14 +58,14 @@ struct About: View { about ourWebsite } - Section("settings.about.release".localized) { + Section(LocalString.settings_about_release) { release appVersion buildNumber source license } - Section("settings.about.dependencies".localized) { + Section(LocalString.settings_about_dependencies) { ForEach(dependencies) { dependency in HStack { Text(dependency.name) @@ -79,7 +79,7 @@ struct About: View { } } } - .navigationTitle("settings.about.title".localized) + .navigationTitle(LocalString.settings_about_title) .navigationBarTitleDisplayMode(.inline) .onChange(of: externalLinkURL) { url in guard let url = url else { return } @@ -94,33 +94,33 @@ struct About: View { } private var release: some View { - Text("settings.about.license-description".localized) + Text(LocalString.settings_about_license_description) } private var appVersion: some View { - Attribute(title: "settings.about.appverion.title".localized, + Attribute(title: LocalString.settings_about_appverion_title, detail: Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String) } private var buildNumber: some View { - Attribute(title: "settings.about.build.title".localized, + Attribute(title: LocalString.settings_about_build_title, detail: Bundle.main.infoDictionary?["CFBundleVersion"] as? String) } private var ourWebsite: some View { - Button("settings.about.our_website.button".localized) { + Button(LocalString.settings_about_our_website_button) { externalLinkURL = URL(string: "\(Brand.aboutWebsite)") } } private var source: some View { - Button("settings.about.source.title".localized) { + Button(LocalString.settings_about_source_title) { externalLinkURL = URL(string: "https://github.com/kiwix/kiwix-apple") } } private var license: some View { - Button("settings.about.button.license".localized) { + Button(LocalString.settings_about_button_license) { externalLinkURL = URL(string: "https://www.gnu.org/licenses/gpl-3.0.en.html") } } diff --git a/Views/Settings/LanguageSelector.swift b/Views/Settings/LanguageSelector.swift index 18948d0b6..fb48035dc 100644 --- a/Views/Settings/LanguageSelector.swift +++ b/Views/Settings/LanguageSelector.swift @@ -38,8 +38,8 @@ struct LanguageSelector: View { } }) }.width(14) - TableColumn("language_selector.name.title".localized, value: \.name) - TableColumn("language_selector.count.table.title".localized, value: \.count) { language in + TableColumn(LocalString.language_selector_name_title, value: \.name) + TableColumn(LocalString.language_selector_count_table_title, value: \.count) { language in Text(language.count.formatted()) } } @@ -72,21 +72,21 @@ struct LanguageSelector: View { List { Section { if showing.isEmpty { - Text("language_selector.no_language.title".localized).foregroundColor(.secondary) + Text(LocalString.language_selector_no_language_title).foregroundColor(.secondary) } else { ForEach(showing) { language in Button { hide(language) } label: { LanguageLabel(language: language) } } } - } header: { Text("language_selector.showing.header".localized) } + } header: { Text(LocalString.language_selector_showing_header) } Section { ForEach(hiding) { language in Button { show(language) } label: { LanguageLabel(language: language) } } - } header: { Text("language_selector.hiding.header".localized) } + } header: { Text(LocalString.language_selector_hiding_header) } } .listStyle(.insetGrouped) - .navigationTitle("language_selector.navitation.title".localized) + .navigationTitle(LocalString.language_selector_navitation_title) .navigationBarTitleDisplayMode(.inline) .toolbar { Picker(selection: $sortingMode) { @@ -94,7 +94,7 @@ struct LanguageSelector: View { Text(sortingMode.name).tag(sortingMode) } } label: { - Label("language_selector.toolbar.sorting".localized, systemImage: "arrow.up.arrow.down") + Label(LocalString.language_selector_toolbar_sorting, systemImage: "arrow.up.arrow.down") }.pickerStyle(.menu) } .onAppear { diff --git a/Views/Settings/Settings.swift b/Views/Settings/Settings.swift index c86bc99f1..7cbe67da9 100644 --- a/Views/Settings/Settings.swift +++ b/Views/Settings/Settings.swift @@ -33,17 +33,17 @@ struct ReadingSettings: View { searchResultSnippetMode = isOn ? .matches : .disabled } VStack(spacing: 16) { - SettingSection(name: "reading_settings.zoom.title".localized) { + SettingSection(name: LocalString.reading_settings_zoom_title) { HStack { Stepper(webViewPageZoom.formatted(.percent), value: $webViewPageZoom, in: 0.5...2, step: 0.05) Spacer() - Button("reading_settings.zoom.reset.button".localized) { + Button(LocalString.reading_settings_zoom_reset_button) { webViewPageZoom = 1 }.disabled(webViewPageZoom == 1) } } if FeatureFlags.showExternalLinkOptionInSettings { - SettingSection(name: "reading_settings.external_link.title".localized) { + SettingSection(name: LocalString.reading_settings_external_link_title) { Picker(selection: $externalLinkLoadingPolicy) { ForEach(ExternalLinkLoadingPolicy.allCases) { loadingPolicy in Text(loadingPolicy.name).tag(loadingPolicy) @@ -52,13 +52,13 @@ struct ReadingSettings: View { } } if FeatureFlags.showSearchSnippetInSettings { - SettingSection(name: "reading_settings.search_snippet.title".localized) { + SettingSection(name: LocalString.reading_settings_search_snippet_title) { Toggle(" ", isOn: isSnippet) } } } .padding() - .tabItem { Label("reading_settings.tab.reading".localized, systemImage: "book") } + .tabItem { Label(LocalString.reading_settings_tab_reading, systemImage: "book") } } } @@ -68,9 +68,9 @@ struct LibrarySettings: View { var body: some View { VStack(spacing: 16) { - SettingSection(name: "library_settings.catalog.title".localized, alignment: .top) { + SettingSection(name: LocalString.library_settings_catalog_title, alignment: .top) { HStack(spacing: 6) { - Button("library_settings.button.refresh_now".localized) { + Button(LocalString.library_settings_button_refresh_now) { library.start(isUserInitiated: true) }.disabled(library.state == .inProgress) if library.state == .inProgress { @@ -78,25 +78,25 @@ struct LibrarySettings: View { } Spacer() if library.state == .error { - Text("library_refresh_error.retrieve.description".localized).foregroundColor(.red) + Text(LocalString.library_refresh_error_retrieve_description).foregroundColor(.red) } else { - Text("library_settings.last_refresh.text".localized + ":").foregroundColor(.secondary) + Text(LocalString.library_settings_last_refresh_text + ":").foregroundColor(.secondary) LibraryLastRefreshTime().foregroundColor(.secondary) } } VStack(alignment: .leading) { - Toggle("library_settings.auto_refresh.toggle".localized, isOn: $libraryAutoRefresh) - Text("library_settings.catalog_warning.text".localized) + Toggle(LocalString.library_settings_auto_refresh_toggle, isOn: $libraryAutoRefresh) + Text(LocalString.library_settings_catalog_warning_text) .foregroundColor(.secondary) } } - SettingSection(name: "library_settings.languages.title".localized, alignment: .top) { + SettingSection(name: LocalString.library_settings_languages_title, alignment: .top) { LanguageSelector() } } .padding() - .tabItem { Label("library_settings.tab.library.title".localized, systemImage: "folder.badge.gearshape") } + .tabItem { Label(LocalString.library_settings_tab_library_title, systemImage: "folder.badge.gearshape") } } } @@ -167,14 +167,14 @@ struct Settings: View { miscellaneous } .modifier(ToolbarRoleBrowser()) - .navigationTitle("settings.navigation.title".localized) + .navigationTitle(LocalString.settings_navigation_title) } else { List { readingSettings miscellaneous } .modifier(ToolbarRoleBrowser()) - .navigationTitle("settings.navigation.title".localized) + .navigationTitle(LocalString.settings_navigation_title) } } .sheet(isPresented: $showDonationPopUp, onDismiss: { @@ -239,20 +239,20 @@ struct Settings: View { } set: { isOn in searchResultSnippetMode = isOn ? .matches : .disabled } - return Section("reading_settings.tab.reading".localized) { + return Section(LocalString.reading_settings_tab_reading) { Stepper(value: $webViewPageZoom, in: 0.5...2, step: 0.05) { - Text("reading_settings.zoom.title".localized + + Text(LocalString.reading_settings_zoom_title + ": \(Formatter.percent.string(from: NSNumber(value: webViewPageZoom)) ?? "")") } if FeatureFlags.showExternalLinkOptionInSettings { - Picker("reading_settings.external_link.title".localized, selection: $externalLinkLoadingPolicy) { + Picker(LocalString.reading_settings_external_link_title, selection: $externalLinkLoadingPolicy) { ForEach(ExternalLinkLoadingPolicy.allCases) { loadingPolicy in Text(loadingPolicy.name).tag(loadingPolicy) } } } if FeatureFlags.showSearchSnippetInSettings { - Toggle("reading_settings.search_snippet.title".localized, isOn: isSnippet) + Toggle(LocalString.reading_settings_search_snippet_title, isOn: isSnippet) } } } @@ -264,11 +264,11 @@ struct Settings: View { } label: { SelectedLanaguageLabel() }.disabled(library.state != .complete) - Toggle("library_settings.toggle.cellular".localized, isOn: $downloadUsingCellular) + Toggle(LocalString.library_settings_toggle_cellular, isOn: $downloadUsingCellular) } header: { - Text("library_settings.tab.library.title".localized) + Text(LocalString.library_settings_tab_library_title) } footer: { - Text("library_settings.new-download-task-description".localized) + Text(LocalString.library_settings_new_download_task_description) } } @@ -276,58 +276,58 @@ struct Settings: View { Section { HStack { if library.state == .error { - Text("library_refresh_error.retrieve.description".localized).foregroundColor(.red) + Text(LocalString.library_refresh_error_retrieve_description).foregroundColor(.red) } else { - Text("catalog_settings.last_refresh.text".localized) + Text(LocalString.catalog_settings_last_refresh_text) Spacer() LibraryLastRefreshTime().foregroundColor(.secondary) } } if library.state == .inProgress { HStack { - Text("catalog_settings.refreshing.text".localized).foregroundColor(.secondary) + Text(LocalString.catalog_settings_refreshing_text).foregroundColor(.secondary) Spacer() ProgressView().progressViewStyle(.circular) } } else { - Button("catalog_settings.refresh_now.button".localized) { + Button(LocalString.catalog_settings_refresh_now_button) { library.start(isUserInitiated: true) } } - Toggle("catalog_settings.auto_refresh.toggle".localized, isOn: $libraryAutoRefresh) + Toggle(LocalString.catalog_settings_auto_refresh_toggle, isOn: $libraryAutoRefresh) } header: { - Text("catalog_settings.header.text".localized) + Text(LocalString.catalog_settings_header_text) } footer: { - Text("catalog_settings.footer.text".localized) + Text(LocalString.catalog_settings_footer_text) } } var backupSettings: some View { Section { - Toggle("backup_settings.toggle.title".localized, isOn: $backupDocumentDirectory) + Toggle(LocalString.backup_settings_toggle_title, isOn: $backupDocumentDirectory) } header: { - Text("backup_settings.header.text".localized) + Text(LocalString.backup_settings_header_text) } footer: { - Text("backup_settings.footer.text".localized) + Text(LocalString.backup_settings_footer_text) }.onChange(of: backupDocumentDirectory) { LibraryOperations.applyFileBackupSetting(isEnabled: $0) } } var miscellaneous: some View { - Section("settings.miscellaneous.title".localized) { + Section(LocalString.settings_miscellaneous_title) { if Payment.paymentButtonType() != nil { SupportKiwixButton { openDonation() } } - Button("settings.miscellaneous.button.feedback".localized) { + Button(LocalString.settings_miscellaneous_button_feedback) { UIApplication.shared.open(URL(string: "mailto:feedback@kiwix.org")!) } - Button("settings.miscellaneous.button.rate_app".localized) { + Button(LocalString.settings_miscellaneous_button_rate_app) { let url = URL(appStoreReviewForName: Brand.appName.lowercased(), appStoreID: Brand.appStoreId) UIApplication.shared.open(url) } - NavigationLink("settings.miscellaneous.navigation.about".localized) { About() } + NavigationLink(LocalString.settings_miscellaneous_navigation_about) { About() } } } } @@ -337,7 +337,7 @@ private struct SelectedLanaguageLabel: View { var body: some View { HStack { - Text("settings.selected_language.title".localized) + Text(LocalString.settings_selected_language_title) Spacer() if languageCodes.count == 1, let languageCode = languageCodes.first, diff --git a/Views/ViewModifiers/AlertHandler.swift b/Views/ViewModifiers/AlertHandler.swift index e7488a85a..70b085d32 100644 --- a/Views/ViewModifiers/AlertHandler.swift +++ b/Views/ViewModifiers/AlertHandler.swift @@ -28,9 +28,9 @@ struct AlertHandler: ViewModifier { .alert(item: $activeAlert) { alert in switch alert { case .articleFailedToLoad: - return Alert(title: Text("alert_handler.alert.failed.title".localized)) + return Alert(title: Text(LocalString.alert_handler_alert_failed_title)) case .downloadFailed: - return Alert(title: Text("download_service.failed.description".localized)) + return Alert(title: Text(LocalString.download_service_failed_description)) } } } diff --git a/Views/ViewModifiers/BookmarkContextMenu.swift b/Views/ViewModifiers/BookmarkContextMenu.swift index f16cb3b53..d3fc8849a 100644 --- a/Views/ViewModifiers/BookmarkContextMenu.swift +++ b/Views/ViewModifiers/BookmarkContextMenu.swift @@ -28,13 +28,13 @@ struct BookmarkContextMenu: ViewModifier { Button { NotificationCenter.openURL(bookmark.articleURL) } label: { - Label("bookmark_context_menu.view.title".localized, systemImage: "doc.richtext") + Label(LocalString.bookmark_context_menu_view_title, systemImage: "doc.richtext") } Button(role: .destructive) { managedObjectContext.delete(bookmark) try? managedObjectContext.save() } label: { - Label("bookmark_context_menu.remove.title".localized, systemImage: "star.slash.fill") + Label(LocalString.bookmark_context_menu_remove_title, systemImage: "star.slash.fill") } } } diff --git a/Views/ViewModifiers/ExternalLinkHandler.swift b/Views/ViewModifiers/ExternalLinkHandler.swift index 7d4332b82..90371c014 100644 --- a/Views/ViewModifiers/ExternalLinkHandler.swift +++ b/Views/ViewModifiers/ExternalLinkHandler.swift @@ -46,24 +46,24 @@ struct ExternalLinkHandler: ViewModifier { activeAlert = .notLoading } } - .alert("external_link_handler.alert.title".localized, + .alert(LocalString.external_link_handler_alert_title, isPresented: $isAlertPresented, presenting: activeAlert) { alert in if case .ask(let url) = alert { - Button("external_link_handler.alert.button.load.link".localized) { + Button(LocalString.external_link_handler_alert_button_load_link) { load(url: url) externalURL = nil // important to nil out, so the same link tapped will trigger onChange again } - Button("common.button.cancel".localized, role: .cancel) { + Button(LocalString.common_button_cancel, role: .cancel) { externalURL = nil // important to nil out, so the same link tapped will trigger onChange again } } } message: { alert in switch alert { case .ask: - Text("external_link_handler.alert.ask.description".localized) + Text(LocalString.external_link_handler_alert_ask_description) case .notLoading: - Text("external_link_handler.alert.not_loading.description".localized) + Text(LocalString.external_link_handler_alert_not_loading_description) } } } diff --git a/Views/ViewModifiers/FileImport.swift b/Views/ViewModifiers/FileImport.swift index 8241e84d8..4eed417e1 100644 --- a/Views/ViewModifiers/FileImport.swift +++ b/Views/ViewModifiers/FileImport.swift @@ -44,7 +44,7 @@ struct OpenFileButton: View { guard case let .success(urls) = result else { return } NotificationCenter.openFiles(urls, context: context) } - .help("import-open-zim-file".localized) + .help(LocalString.common_dialog_button_open) .keyboardShortcut("o") } } @@ -108,13 +108,13 @@ struct OpenFileHandler: ViewModifier { activeAlert = .unableToOpen(filenames: invalidURLs.map({ $0.lastPathComponent })) } } - }.alert("file_import.alert.no_open.title".localized, + }.alert(LocalString.file_import_alert_no_open_title, isPresented: $isAlertPresented, presenting: activeAlert) { _ in } message: { alert in switch alert { case .unableToOpen(let filenames): let name = ListFormatter.localizedString(byJoining: filenames) - Text("file_import.alert.no_open.message".localizedWithFormat(withArgs: name)) + Text(LocalString.file_import_alert_no_open_message(withArgs: name)) } } } diff --git a/Views/ViewModifiers/SaveContentHandler.swift b/Views/ViewModifiers/SaveContentHandler.swift index 8325d32af..a94a963ca 100644 --- a/Views/ViewModifiers/SaveContentHandler.swift +++ b/Views/ViewModifiers/SaveContentHandler.swift @@ -24,6 +24,7 @@ struct SaveContentHandler: ViewModifier { @State private var urlAndContent: (URL, URLContent)? #endif + // swiftlint:disable:next function_body_length func body(content: Content) -> some View { content.onReceive(saveContentToFile) { notification in guard let url = notification.userInfo?["url"] as? URL, @@ -38,11 +39,11 @@ struct SaveContentHandler: ViewModifier { } #if os(iOS) .alert(isPresented: Binding.constant($kiwixURL.wrappedValue != nil)) { - Alert(title: Text("common.export_file.alert.title".localized), - message: Text("common.export_file.alert.description" - .localizedWithFormat(withArgs: kiwixURL?.lastPathComponent ?? "") + Alert(title: Text(LocalString.common_export_file_alert_title), + message: Text( + LocalString.common_export_file_alert_description(withArgs: kiwixURL?.lastPathComponent ?? "") ), - primaryButton: .default(Text("common.export_file.alert.button.title".localized)) { + primaryButton: .default(Text(LocalString.common_export_file_alert_button_title)) { Task { @MainActor in if let kiwixURL, let urlContent = await ZimFileService.shared.getURLContent(url: kiwixURL) { diff --git a/Views/WelcomeCatalog.swift b/Views/WelcomeCatalog.swift index d85c6d8cd..2b28fbe79 100644 --- a/Views/WelcomeCatalog.swift +++ b/Views/WelcomeCatalog.swift @@ -46,7 +46,7 @@ struct WelcomeCatalog: View { y: logoCalc.buttonCenterY) .frame(maxWidth: logoCalc.buttonsWidth) if viewState == .error { - Text("library_refresh_error.retrieve.description".localized) + Text(LocalString.library_refresh_error_retrieve_description) .foregroundColor(.red) .position( x: geometry.size.width * 0.5, @@ -75,7 +75,7 @@ struct WelcomeCatalog: View { OpenFileButton(context: .welcomeScreen) { HStack { Spacer() - Text("welcome.actions.open_file".localized) + Text(LocalString.welcome_actions_open_file) Spacer() }.padding(6) } @@ -90,9 +90,9 @@ struct WelcomeCatalog: View { HStack { Spacer() if viewState == .loading { - Text("welcome.button.status.fetching_catalog.text".localized) + Text(LocalString.welcome_button_status_fetching_catalog_text) } else { - Text("welcome.button.status.fetch_catalog.text".localized) + Text(LocalString.welcome_button_status_fetch_catalog_text) } Spacer() }.padding(6) diff --git a/localizations.py b/localizations.py new file mode 100644 index 000000000..46b1f4147 --- /dev/null +++ b/localizations.py @@ -0,0 +1,139 @@ +import os +import argparse +import re +import glob +from pathlib import Path + +# example usages: +# python localizations.py generate +# python localizations.py validate + +parser = argparse.ArgumentParser() +parser.add_argument('command', type=str, help="Possible options: generate | validate") +arguments = parser.parse_args() + +command = arguments.command +if command not in ['generate', 'validate']: + parser.print_help() + exit() + +input_file_name = Path("Support/en.lproj/Localizable.strings") +comment_file_name = Path("Support/qqq.lproj/Localizable.strings") +enum_name = "LocalString" +target_dir = "Support" +template_file_name = "StringLocalExtension.swift_temp" + +class Generate: + def __init__(self, input_file_name, template_file, enum_name, target_dir): + self.enum_name = enum_name + reader = Reader(input_file_name) + vars = self.__variables(reader) + + with open(os.path.join(target_dir, template_file)) as template_file: + template_content = template_file.read() + + output_path = os.path.join(target_dir, enum_name + ".swift") + file = open(output_path, 'w') + file.write("""// +// !! DO NOT EDIT THIS FILE DIRECTLY !! +// !! IT HAS BEEN AUTO-GENERATED !! +// +""") + file.write(template_content) + file.write(self.__code_for("\n\t".join(vars))) + file.close() + + def __variables(self, reader): + vars = list() + for key, has_arguments in sorted(reader.keys()): + if has_arguments: + vars.append(self.__static_func_for(key)) + else: + vars.append(self.__static_let_for(key)) + return vars + + def __code_for(self, variables): + return """enum {} {{ + {} +}} +""".format(self.enum_name, variables) + + def __static_let_for(self, key): + return """static let {} = "{}".localized""".format(self.__get_var_name(key), key) + + def __static_func_for(self, key): + return """static func {}(withArgs args: CVarArg...) -> String {{ "{}".localizedWithFormat(withArgs: args) }}""".format(self.__get_var_name(key), key) + + def __get_var_name(self, key): + return re.sub('[^a-z0-9]', '_', key.lower()) + + +class Reader: + def __init__(self, input_file_name): + self.input_file_name = input_file_name + + def keys(self): + pattern = re.compile(r'"(?P.+)"\s{1,}=\s{1,}"(?P.+)"') + with open(self.input_file_name) as input_file: + for line in input_file: + match = pattern.match(line) + if match: + groups = match.groupdict() + key = groups.get('key') + value = groups.get('value') + has_arguments = "%@" in value + yield key, has_arguments + +class Validate: + def __init__(self, input_file_name, comment_file_name, enum_name, search_directory=os.getcwd()): + reader = Reader(input_file_name) + vars = list() + for key, _ in reader.keys(): + assert "." in key, "Invalid translation key: {}, it should contain at least one '.' (dot)".format(key) + vars.append(key) + + vars = sorted(vars) + + matches = dict() + counter = dict() + for var in vars: + swift_var = self.__get_var_name(var) + counter[swift_var] = 0 + + for swift_file_name in glob.iglob(os.path.join(search_directory, '**/*.swift'), recursive=True): + if Path(swift_file_name).name != "{}.swift".format(enum_name): + with open(swift_file_name, 'r') as swift_file: + content = swift_file.read() + for var in vars: + if var in content: + if var in matches: + matches[var].append(swift_file_name) + else: + matches[var] = [swift_file_name] + swift_var = self.__get_var_name(var) + if swift_var in content: + counter[swift_var] += 1 + + assert len(matches.keys()) == 0, "localization strings cannot not be directly used in swift (use LocalString instead): {}".format(matches) + unused_swift_vars = {k: v for k, v in counter.items() if v == 0 }.keys() + assert len(unused_swift_vars) == 0, "unused localizations entries (delete them from localizations, and run: python localizations.py generate): {}".format(sorted(unused_swift_vars)) + + comment_keys = list() + comment_reader = Reader(comment_file_name) + for comment_key, _ in comment_reader.keys(): + assert comment_key in vars, "extra qqq key found: {}".format(comment_key) + comment_keys.append(comment_key) + + missing = sorted(set(vars).difference(comment_keys)) + assert len(missing) == 0, "undocumented keys (please add them to qqq): {}".format(missing) + + def __get_var_name(self, key): + return re.sub('[^a-z0-9]', '_', key.lower()) + +match command: + case "generate": + Generate(input_file_name, template_file_name, enum_name, target_dir) + case "validate": + Validate(input_file_name, comment_file_name, enum_name) + case _: + exit(-1) \ No newline at end of file