From dd3ede37e7d3fa57a76dad86ce178979b26df526 Mon Sep 17 00:00:00 2001 From: Max Goedjen Date: Sun, 17 Aug 2025 12:57:18 -0500 Subject: [PATCH] Switch to string symbols --- Sources/SecretAgent/Notifier.swift | 18 +-- Sources/Secretive/App.swift | 6 +- Sources/Secretive/Localizable.xcstrings | 142 ++++++++---------- Sources/Secretive/Views/ContentView.swift | 18 +-- Sources/Secretive/Views/CopyableView.swift | 8 +- .../Secretive/Views/CreateSecretView.swift | 22 +-- .../Secretive/Views/DeleteSecretView.swift | 10 +- Sources/Secretive/Views/EmptyStoreView.swift | 10 +- Sources/Secretive/Views/NoStoresView.swift | 6 +- .../Secretive/Views/RenameSecretView.swift | 6 +- .../Secretive/Views/SecretDetailView.swift | 8 +- .../Secretive/Views/SecretListItemView.swift | 4 +- Sources/Secretive/Views/SetupView.swift | 38 ++--- Sources/Secretive/Views/UpdateView.swift | 8 +- 14 files changed, 146 insertions(+), 158 deletions(-) diff --git a/Sources/SecretAgent/Notifier.swift b/Sources/SecretAgent/Notifier.swift index 2e53260..7b00ed6 100644 --- a/Sources/SecretAgent/Notifier.swift +++ b/Sources/SecretAgent/Notifier.swift @@ -10,8 +10,8 @@ final class Notifier: Sendable { private let notificationDelegate = NotificationDelegate() init() { - let updateAction = UNNotificationAction(identifier: Constants.updateActionIdentitifier, title: String(localized: "update_notification_update_button"), options: []) - let ignoreAction = UNNotificationAction(identifier: Constants.ignoreActionIdentitifier, title: String(localized: "update_notification_ignore_button"), options: []) + let updateAction = UNNotificationAction(identifier: Constants.updateActionIdentitifier, title: String(localized: .updateNotificationUpdateButton), options: []) + let ignoreAction = UNNotificationAction(identifier: Constants.ignoreActionIdentitifier, title: String(localized: .updateNotificationIgnoreButton), options: []) let updateCategory = UNNotificationCategory(identifier: Constants.updateCategoryIdentitifier, actions: [updateAction, ignoreAction], intentIdentifiers: [], options: []) let criticalUpdateCategory = UNNotificationCategory(identifier: Constants.criticalUpdateCategoryIdentitifier, actions: [updateAction], intentIdentifiers: [], options: []) @@ -22,7 +22,7 @@ final class Notifier: Sendable { Measurement(value: 24, unit: UnitDuration.hours) ] - let doNotPersistAction = UNNotificationAction(identifier: Constants.doNotPersistActionIdentitifier, title: String(localized: "persist_authentication_decline_button"), options: []) + let doNotPersistAction = UNNotificationAction(identifier: Constants.doNotPersistActionIdentitifier, title: String(localized: .persistAuthenticationDeclineButton), options: []) var allPersistenceActions = [doNotPersistAction] let formatter = DateComponentsFormatter() @@ -41,7 +41,7 @@ final class Notifier: Sendable { let persistAuthenticationCategory = UNNotificationCategory(identifier: Constants.persistAuthenticationCategoryIdentitifier, actions: allPersistenceActions, intentIdentifiers: [], options: []) if persistAuthenticationCategory.responds(to: Selector(("actionsMenuTitle"))) { - persistAuthenticationCategory.setValue(String(localized: "persist_authentication_accept_button"), forKey: "_actionsMenuTitle") + persistAuthenticationCategory.setValue(String(localized: .persistAuthenticationAcceptButton), forKey: "_actionsMenuTitle") } UNUserNotificationCenter.current().setNotificationCategories([updateCategory, criticalUpdateCategory, persistAuthenticationCategory]) UNUserNotificationCenter.current().delegate = notificationDelegate @@ -64,8 +64,8 @@ final class Notifier: Sendable { await notificationDelegate.state.setPending(secret: secret, store: store) let notificationCenter = UNUserNotificationCenter.current() let notificationContent = UNMutableNotificationContent() - notificationContent.title = String(localized: "signed_notification_title_\(provenance.origin.displayName)") - notificationContent.subtitle = String(localized: "signed_notification_description_\(secret.name)") + notificationContent.title = String(localized: .signedNotificationTitle(provenance.origin.displayName)) + notificationContent.subtitle = String(localized: .signedNotificationDescription(secret.name)) notificationContent.userInfo[Constants.persistSecretIDKey] = secret.id.description notificationContent.userInfo[Constants.persistStoreIDKey] = store.id.description notificationContent.interruptionLevel = .timeSensitive @@ -85,11 +85,11 @@ final class Notifier: Sendable { let notificationContent = UNMutableNotificationContent() if update.critical { notificationContent.interruptionLevel = .critical - notificationContent.title = String(localized: "update_notification_update_critical_title_\(update.name)") + notificationContent.title = String(localized: .updateNotificationUpdateCriticalTitle(update.name)) } else { - notificationContent.title = String(localized: "update_notification_update_normal_title_\(update.name)") + notificationContent.title = String(localized: .updateNotificationUpdateNormalTitle(update.name)) } - notificationContent.subtitle = String(localized: "update_notification_update_description") + notificationContent.subtitle = String(localized: .updateNotificationUpdateDescription) notificationContent.body = update.body notificationContent.categoryIdentifier = update.critical ? Constants.criticalUpdateCategoryIdentitifier : Constants.updateCategoryIdentitifier let request = UNNotificationRequest(identifier: UUID().uuidString, content: notificationContent, trigger: nil) diff --git a/Sources/Secretive/App.swift b/Sources/Secretive/App.swift index 5505964..2c1ec9d 100644 --- a/Sources/Secretive/App.swift +++ b/Sources/Secretive/App.swift @@ -59,18 +59,18 @@ struct Secretive: App { } .commands { CommandGroup(after: CommandGroupPlacement.newItem) { - Button("app_menu_new_secret_button") { + Button(.appMenuNewSecretButton) { showingCreation = true } .keyboardShortcut(KeyboardShortcut(KeyEquivalent("N"), modifiers: [.command, .shift])) } CommandGroup(replacing: .help) { - Button("app_menu_help_button") { + Button(.appMenuHelpButton) { NSWorkspace.shared.open(Constants.helpURL) } } CommandGroup(after: .help) { - Button("app_menu_setup_button") { + Button(.appMenuSetupButton) { showingSetup = true } } diff --git a/Sources/Secretive/Localizable.xcstrings b/Sources/Secretive/Localizable.xcstrings index 063d2fc..6dd48ed 100644 --- a/Sources/Secretive/Localizable.xcstrings +++ b/Sources/Secretive/Localizable.xcstrings @@ -2,6 +2,7 @@ "sourceLanguage" : "en", "strings" : { "agent_not_running_notice_title" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -78,6 +79,7 @@ } }, "agent_running_notice_detail_description" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -154,6 +156,7 @@ } }, "agent_running_notice_detail_title" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -230,6 +233,7 @@ } }, "agent_running_notice_title" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -306,6 +310,7 @@ } }, "agent_setup_notice_title" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -382,6 +387,7 @@ } }, "app_menu_help_button" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -458,6 +464,7 @@ } }, "app_menu_new_secret_button" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -534,6 +541,7 @@ } }, "app_menu_setup_button" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -610,6 +618,7 @@ } }, "app_not_in_applications_notice_detail_description" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -686,6 +695,7 @@ } }, "app_not_in_applications_notice_title" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -1308,6 +1318,7 @@ } }, "copyable_click_to_copy_button" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -1384,6 +1395,7 @@ } }, "copyable_copied" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -1460,6 +1472,7 @@ } }, "create_secret_cancel_button" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -1536,6 +1549,7 @@ } }, "create_secret_create_button" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -1612,6 +1626,7 @@ } }, "create_secret_name_label" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -1688,6 +1703,7 @@ } }, "create_secret_name_placeholder" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -1764,6 +1780,7 @@ } }, "create_secret_notify_description" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -1840,6 +1857,7 @@ } }, "create_secret_notify_title" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -1916,6 +1934,7 @@ } }, "create_secret_require_authentication_description" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -1992,6 +2011,7 @@ } }, "create_secret_require_authentication_title" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -2068,6 +2088,7 @@ } }, "create_secret_title" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -2144,6 +2165,7 @@ } }, "delete_confirmation_cancel_button" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -2220,6 +2242,7 @@ } }, "delete_confirmation_confirm_name_label" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -2296,6 +2319,7 @@ } }, "delete_confirmation_delete_button" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -2372,6 +2396,7 @@ } }, "delete_confirmation_description_%@_%@" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -2448,6 +2473,7 @@ } }, "delete_confirmation_title_%@" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -2524,6 +2550,7 @@ } }, "empty_store_modifiable_click_here_description" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -2600,83 +2627,7 @@ } }, "empty_store_modifiable_click_here_title" : { - "localizations" : { - "ca" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sense secrets" - } - }, - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Keine Secrets" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "No Secrets" - } - }, - "fi" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ei salaisuuksia" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Aucun secret" - } - }, - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nessun Segreto" - } - }, - "ja" : { - "stringUnit" : { - "state" : "translated", - "value" : "シークレットがありません" - } - }, - "ko" : { - "stringUnit" : { - "state" : "translated", - "value" : "비밀이 없음" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Brak sekretów" - } - }, - "pt-BR" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sem Segredos" - } - }, - "ru" : { - "stringUnit" : { - "state" : "translated", - "value" : "Нет секретов" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "没有密钥串" - } - } - } - }, - "empty_store_modifiable_title" : { - "extractionState" : "stale", + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -2753,6 +2704,7 @@ } }, "empty_store_nonmodifiable_description" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -2829,6 +2781,7 @@ } }, "empty_store_nonmodifiable_supported_key_types" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -2905,6 +2858,7 @@ } }, "empty_store_nonmodifiable_title" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -2981,6 +2935,7 @@ } }, "no_secure_storage_description" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -3057,6 +3012,7 @@ } }, "no_secure_storage_title" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -3133,6 +3089,7 @@ } }, "no_secure_storage_yubico_link" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -3365,6 +3322,7 @@ } }, "rename_cancel_button" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -3435,6 +3393,7 @@ } }, "rename_rename_button" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -3505,6 +3464,7 @@ } }, "rename_title_%@" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -3575,6 +3535,7 @@ } }, "secret_detail_md5_fingerprint_label" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -3645,6 +3606,7 @@ } }, "secret_detail_public_key_label" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -3715,6 +3677,7 @@ } }, "secret_detail_public_key_path_label" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -3785,6 +3748,7 @@ } }, "secret_detail_sha256_fingerprint_label" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -3855,6 +3819,7 @@ } }, "secret_list_delete_button" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -3925,6 +3890,7 @@ } }, "secret_list_rename_button" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -4066,6 +4032,7 @@ } }, "setup_agent_activity_monitor_description" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -4136,6 +4103,7 @@ } }, "setup_agent_description" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -4206,6 +4174,7 @@ } }, "setup_agent_install_button" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -4276,6 +4245,7 @@ } }, "setup_agent_title" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -4346,6 +4316,7 @@ } }, "setup_ssh_add_for_me_button" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -4416,6 +4387,7 @@ } }, "setup_ssh_add_to_config_button_%@" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -4486,6 +4458,7 @@ } }, "setup_ssh_added_manually_button" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -4556,6 +4529,7 @@ } }, "setup_ssh_description" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -4626,6 +4600,7 @@ } }, "setup_ssh_title" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -4696,6 +4671,7 @@ } }, "setup_step_complete_symbol" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -4766,6 +4742,7 @@ } }, "setup_third_party_faq_link" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -4836,6 +4813,7 @@ } }, "setup_updates_description" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -4906,6 +4884,7 @@ } }, "setup_updates_ok" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -4976,6 +4955,7 @@ } }, "setup_updates_readmore" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -5046,6 +5026,7 @@ } }, "setup_updates_title" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -5402,6 +5383,7 @@ } }, "update_critical_notice_title" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -5472,6 +5454,7 @@ } }, "update_ignore_button" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -5542,6 +5525,7 @@ } }, "update_normal_notice_title" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -5972,6 +5956,7 @@ } }, "update_release_notes_title" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -6042,6 +6027,7 @@ } }, "update_test_notice_title" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -6112,6 +6098,7 @@ } }, "update_update_button" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { @@ -6182,6 +6169,7 @@ } }, "update_version_name_%@" : { + "extractionState" : "manual", "localizations" : { "ca" : { "stringUnit" : { diff --git a/Sources/Secretive/Views/ContentView.swift b/Sources/Secretive/Views/ContentView.swift index cb21882..ab4d675 100644 --- a/Sources/Secretive/Views/ContentView.swift +++ b/Sources/Secretive/Views/ContentView.swift @@ -64,7 +64,7 @@ extension ContentView { } } - var updateNoticeContent: (LocalizedStringKey, Color)? { + var updateNoticeContent: (LocalizedStringResource, Color)? { guard let update = updater.update else { return nil } if update.critical { return ("update_critical_notice_title", .red) @@ -121,13 +121,13 @@ extension ContentView { }, label: { Group { if hasRunSetup && !agentStatusChecker.running { - Text("agent_not_running_notice_title") + Text(.agentNotRunningNoticeTitle) } else { - Text("agent_setup_notice_title") + Text(.agentSetupNoticeTitle) } } .font(.headline) - .foregroundColor(.white) + }) .buttonStyle(ToolbarButtonStyle(color: .orange)) } @@ -138,7 +138,7 @@ extension ContentView { showingAgentInfo = true }, label: { HStack { - Text("agent_running_notice_title") + Text(.agentRunningNoticeTitle) .font(.headline) .foregroundColor(colorScheme == .light ? Color(white: 0.3) : .white) Circle() @@ -149,10 +149,10 @@ extension ContentView { .buttonStyle(ToolbarButtonStyle(lightColor: .black.opacity(0.05), darkColor: .white.opacity(0.05))) .popover(isPresented: $showingAgentInfo, attachmentAnchor: attachmentAnchor, arrowEdge: .bottom) { VStack { - Text("agent_running_notice_detail_title") + Text(.agentRunningNoticeDetailTitle) .font(.title) .padding(5) - Text("agent_running_notice_detail_description") + Text(.agentRunningNoticeDetailDescription) .frame(width: 300) } .padding() @@ -166,7 +166,7 @@ extension ContentView { showingAppPathNotice = true }, label: { Group { - Text("app_not_in_applications_notice_title") + Text(.appNotInApplicationsNoticeTitle) } .font(.headline) .foregroundColor(.white) @@ -178,7 +178,7 @@ extension ContentView { .resizable() .aspectRatio(contentMode: .fit) .frame(width: 64) - Text("app_not_in_applications_notice_detail_description") + Text(.appNotInApplicationsNoticeDetailDescription) .frame(maxWidth: 300) } .padding() diff --git a/Sources/Secretive/Views/CopyableView.swift b/Sources/Secretive/Views/CopyableView.swift index 8b2630f..c62e595 100644 --- a/Sources/Secretive/Views/CopyableView.swift +++ b/Sources/Secretive/Views/CopyableView.swift @@ -3,7 +3,7 @@ import UniformTypeIdentifiers struct CopyableView: View { - var title: LocalizedStringKey + var title: LocalizedStringResource var image: Image var text: String @@ -66,12 +66,12 @@ struct CopyableView: View { ) } - var hoverText: LocalizedStringKey { + var hoverText: LocalizedStringResource { switch interactionState { case .hovering: - return "copyable_click_to_copy_button" + return .copyableClickToCopyButton case .clicking: - return "copyable_copied" + return .copyableCopied case .normal: fatalError() } diff --git a/Sources/Secretive/Views/CreateSecretView.swift b/Sources/Secretive/Views/CreateSecretView.swift index 9bddcd2..7900f16 100644 --- a/Sources/Secretive/Views/CreateSecretView.swift +++ b/Sources/Secretive/Views/CreateSecretView.swift @@ -14,30 +14,30 @@ struct CreateSecretView: View { HStack { VStack { HStack { - Text("create_secret_title") + Text(.createSecretTitle) .font(.largeTitle) Spacer() } HStack { - Text("create_secret_name_label") - TextField("create_secret_name_placeholder", text: $name) + Text(.createSecretNameLabel) + TextField(String(localized: .createSecretNamePlaceholder), text: $name) .focusable() } ThumbnailPickerView(items: [ - ThumbnailPickerView.Item(value: true, name: "create_secret_require_authentication_title", description: "create_secret_require_authentication_description", thumbnail: AuthenticationView()), - ThumbnailPickerView.Item(value: false, name: "create_secret_notify_title", - description: "create_secret_notify_description", + ThumbnailPickerView.Item(value: true, name: .createSecretRequireAuthenticationTitle, description: .createSecretRequireAuthenticationDescription, thumbnail: AuthenticationView()), + ThumbnailPickerView.Item(value: false, name: .createSecretNotifyTitle, + description: .createSecretNotifyDescription, thumbnail: NotificationView()) ], selection: $requiresAuthentication) } } HStack { Spacer() - Button("create_secret_cancel_button") { + Button(.createSecretCancelButton) { showing = false } .keyboardShortcut(.cancelAction) - Button("create_secret_create_button", action: save) + Button(.createSecretCreateButton, action: save) .disabled(name.isEmpty) .keyboardShortcut(.defaultAction) } @@ -98,11 +98,11 @@ extension ThumbnailPickerView { struct Item: Identifiable { let id = UUID() let value: InnerValueType - let name: LocalizedStringKey - let description: LocalizedStringKey + let name: LocalizedStringResource + let description: LocalizedStringResource let thumbnail: AnyView - init(value: InnerValueType, name: LocalizedStringKey, description: LocalizedStringKey, thumbnail: ViewType) { + init(value: InnerValueType, name: LocalizedStringResource, description: LocalizedStringResource, thumbnail: ViewType) { self.value = value self.name = name self.description = description diff --git a/Sources/Secretive/Views/DeleteSecretView.swift b/Sources/Secretive/Views/DeleteSecretView.swift index 3be07c2..90eae09 100644 --- a/Sources/Secretive/Views/DeleteSecretView.swift +++ b/Sources/Secretive/Views/DeleteSecretView.swift @@ -18,24 +18,24 @@ struct DeleteSecretView: View { .padding() VStack { HStack { - Text("delete_confirmation_title_\(secret.name)").bold() + Text(.deleteConfirmationTitle(secret.name)).bold() Spacer() } HStack { - Text("delete_confirmation_description_\(secret.name)_\(secret.name)") + Text(.deleteConfirmationDescription(secret.name, secret.name)) Spacer() } HStack { - Text("delete_confirmation_confirm_name_label") + Text(.deleteConfirmationConfirmNameLabel) TextField(secret.name, text: $confirm) } } } HStack { Spacer() - Button("delete_confirmation_delete_button", action: delete) + Button(.deleteConfirmationDeleteButton, action: delete) .disabled(confirm != secret.name) - Button("delete_confirmation_cancel_button") { + Button(.deleteConfirmationCancelButton) { dismissalBlock(false) } .keyboardShortcut(.cancelAction) diff --git a/Sources/Secretive/Views/EmptyStoreView.swift b/Sources/Secretive/Views/EmptyStoreView.swift index b6593c0..3f0bd81 100644 --- a/Sources/Secretive/Views/EmptyStoreView.swift +++ b/Sources/Secretive/Views/EmptyStoreView.swift @@ -18,9 +18,9 @@ struct EmptyStoreImmutableView: View { var body: some View { VStack { - Text("empty_store_nonmodifiable_title").bold() - Text("empty_store_nonmodifiable_description") - Text("empty_store_nonmodifiable_supported_key_types") + Text(.emptyStoreNonmodifiableTitle).bold() + Text(.emptyStoreNonmodifiableDescription) + Text(.emptyStoreNonmodifiableSupportedKeyTypes) }.frame(maxWidth: .infinity, maxHeight: .infinity) } @@ -49,8 +49,8 @@ struct EmptyStoreModifiableView: View { path.addLine(to: CGPoint(x: g.size.width - 3, y: 0)) }.fill() }.frame(height: (windowGeometry.size.height/2) - 20).padding() - Text("empty_store_modifiable_click_here_title").bold() - Text("empty_store_modifiable_click_here_description") + Text(.emptyStoreModifiableClickHereTitle).bold() + Text(.emptyStoreModifiableClickHereDescription) Spacer() }.frame(maxWidth: .infinity, maxHeight: .infinity) } diff --git a/Sources/Secretive/Views/NoStoresView.swift b/Sources/Secretive/Views/NoStoresView.swift index 3ac4841..497138d 100644 --- a/Sources/Secretive/Views/NoStoresView.swift +++ b/Sources/Secretive/Views/NoStoresView.swift @@ -4,10 +4,10 @@ struct NoStoresView: View { var body: some View { VStack { - Text("no_secure_storage_title") + Text(.noSecureStorageTitle) .bold() - Text("no_secure_storage_description") - Link("no_secure_storage_yubico_link", destination: URL(string: "https://www.yubico.com/products/compare-yubikey-5-series/")!) + Text(.noSecureStorageDescription) + Link(.noSecureStorageYubicoLink, destination: URL(string: "https://www.yubico.com/products/compare-yubikey-5-series/")!) }.padding() } diff --git a/Sources/Secretive/Views/RenameSecretView.swift b/Sources/Secretive/Views/RenameSecretView.swift index 0a417cb..ded813d 100644 --- a/Sources/Secretive/Views/RenameSecretView.swift +++ b/Sources/Secretive/Views/RenameSecretView.swift @@ -18,7 +18,7 @@ struct RenameSecretView: View { .padding() VStack { HStack { - Text("rename_title_\(secret.name)") + Text(.renameTitle(secret.name)) Spacer() } HStack { @@ -28,10 +28,10 @@ struct RenameSecretView: View { } HStack { Spacer() - Button("rename_rename_button", action: rename) + Button(.renameRenameButton, action: rename) .disabled(newName.count == 0) .keyboardShortcut(.return) - Button("rename_cancel_button") { + Button(.renameCancelButton) { dismissalBlock(false) }.keyboardShortcut(.cancelAction) } diff --git a/Sources/Secretive/Views/SecretDetailView.swift b/Sources/Secretive/Views/SecretDetailView.swift index 75dde47..a361bbc 100644 --- a/Sources/Secretive/Views/SecretDetailView.swift +++ b/Sources/Secretive/Views/SecretDetailView.swift @@ -12,16 +12,16 @@ struct SecretDetailView: View { ScrollView { Form { Section { - CopyableView(title: "secret_detail_sha256_fingerprint_label", image: Image(systemName: "touchid"), text: keyWriter.openSSHSHA256Fingerprint(secret: secret)) + CopyableView(title: .secretDetailSha256FingerprintLabel, image: Image(systemName: "touchid"), text: keyWriter.openSSHSHA256Fingerprint(secret: secret)) Spacer() .frame(height: 20) - CopyableView(title: "secret_detail_md5_fingerprint_label", image: Image(systemName: "touchid"), text: keyWriter.openSSHMD5Fingerprint(secret: secret)) + CopyableView(title: .secretDetailMd5FingerprintLabel, image: Image(systemName: "touchid"), text: keyWriter.openSSHMD5Fingerprint(secret: secret)) Spacer() .frame(height: 20) - CopyableView(title: "secret_detail_public_key_label", image: Image(systemName: "key"), text: keyString) + CopyableView(title: .secretDetailPublicKeyLabel, image: Image(systemName: "key"), text: keyString) Spacer() .frame(height: 20) - CopyableView(title: "secret_detail_public_key_path_label", image: Image(systemName: "lock.doc"), text: publicKeyFileStoreController.publicKeyPath(for: secret)) + CopyableView(title: .secretDetailPublicKeyPathLabel, image: Image(systemName: "lock.doc"), text: publicKeyFileStoreController.publicKeyPath(for: secret)) Spacer() } } diff --git a/Sources/Secretive/Views/SecretListItemView.swift b/Sources/Secretive/Views/SecretListItemView.swift index 38a6f36..58b0f32 100644 --- a/Sources/Secretive/Views/SecretListItemView.swift +++ b/Sources/Secretive/Views/SecretListItemView.swift @@ -39,10 +39,10 @@ struct SecretListItemView: View { .contextMenu { if store is AnySecretStoreModifiable { Button(action: { isRenaming = true }) { - Text("secret_list_rename_button") + Text(.secretListRenameButton) } Button(action: { isDeleting = true }) { - Text("secret_list_delete_button") + Text(.secretListDeleteButton) } } } diff --git a/Sources/Secretive/Views/SetupView.swift b/Sources/Secretive/Views/SetupView.swift index 8f71bc0..6eca787 100644 --- a/Sources/Secretive/Views/SetupView.swift +++ b/Sources/Secretive/Views/SetupView.swift @@ -61,7 +61,7 @@ struct StepView: View { Circle() .foregroundColor(.green) .frame(width: Constants.circleWidth, height: Constants.circleWidth) - Text("setup_step_complete_symbol") + Text(.setupStepCompleteSymbol) .foregroundColor(.white) .bold() } else { @@ -101,14 +101,14 @@ extension StepView { struct SetupStepView : View where Content : View { - let title: LocalizedStringKey + let title: LocalizedStringResource let image: Image - let bodyText: LocalizedStringKey - let buttonTitle: LocalizedStringKey + let bodyText: LocalizedStringResource + let buttonTitle: LocalizedStringResource let buttonAction: () -> Void let content: Content - init(title: LocalizedStringKey, image: Image, bodyText: LocalizedStringKey, buttonTitle: LocalizedStringKey, buttonAction: @escaping () -> Void = {}, @ViewBuilder content: () -> Content) { + init(title: LocalizedStringResource, image: Image, bodyText: LocalizedStringResource, buttonTitle: LocalizedStringResource, buttonAction: @escaping () -> Void = {}, @ViewBuilder content: () -> Content) { self.title = title self.image = image self.bodyText = bodyText @@ -145,12 +145,12 @@ struct SecretAgentSetupView: View { let buttonAction: () -> Void var body: some View { - SetupStepView(title: "setup_agent_title", + SetupStepView(title: .setupAgentTitle, image: Image(nsImage: NSApplication.shared.applicationIconImage), - bodyText: "setup_agent_description", - buttonTitle: "setup_agent_install_button", + bodyText: .setupAgentDescription, + buttonTitle: .setupAgentInstallButton, buttonAction: install) { - Text("setup_agent_activity_monitor_description") + Text(.setupAgentActivityMonitorDescription) .multilineTextAlignment(.center) } } @@ -172,12 +172,12 @@ struct SSHAgentSetupView: View { @State private var selectedShellInstruction: ShellConfigInstruction = controller.shellInstructions.first! var body: some View { - SetupStepView(title: "setup_ssh_title", + SetupStepView(title: .setupSshTitle, image: Image(systemName: "terminal"), - bodyText: "setup_ssh_description", - buttonTitle: "setup_ssh_added_manually_button", + bodyText: .setupSshDescription, + buttonTitle: .setupSshAddedManuallyButton, buttonAction: buttonAction) { - Link("setup_third_party_faq_link", destination: URL(string: "https://github.com/maxgoedjen/secretive/blob/main/APP_CONFIG.md")!) + Link(.setupThirdPartyFaqLink, destination: URL(string: "https://github.com/maxgoedjen/secretive/blob/main/APP_CONFIG.md")!) Picker(selection: $selectedShellInstruction, label: EmptyView()) { ForEach(SSHAgentSetupView.controller.shellInstructions) { instruction in Text(instruction.shell) @@ -185,8 +185,8 @@ struct SSHAgentSetupView: View { .padding() } }.pickerStyle(SegmentedPickerStyle()) - CopyableView(title: "setup_ssh_add_to_config_button_\(selectedShellInstruction.shellConfigPath)", image: Image(systemName: "greaterthan.square"), text: selectedShellInstruction.text) - Button("setup_ssh_add_for_me_button") { + CopyableView(title: .setupSshAddToConfigButton(selectedShellInstruction.shellConfigPath), image: Image(systemName: "greaterthan.square"), text: selectedShellInstruction.text) + Button(.setupSshAddForMeButton) { let controller = ShellConfigurationController() if controller.addToShell(shellInstructions: selectedShellInstruction) { buttonAction() @@ -216,12 +216,12 @@ struct UpdaterExplainerView: View { let buttonAction: () -> Void var body: some View { - SetupStepView(title: "setup_updates_title", + SetupStepView(title: .setupUpdatesTitle, image: Image(systemName: "dot.radiowaves.left.and.right"), - bodyText: "setup_updates_description", - buttonTitle: "setup_updates_ok", + bodyText: .setupUpdatesDescription, + buttonTitle: .setupUpdatesOk, buttonAction: buttonAction) { - Link("setup_updates_readmore", destination: SetupView.Constants.updaterFAQURL) + Link(.setupUpdatesReadmore, destination: SetupView.Constants.updaterFAQURL) } } diff --git a/Sources/Secretive/Views/UpdateView.swift b/Sources/Secretive/Views/UpdateView.swift index bebbcc5..f4dfa2c 100644 --- a/Sources/Secretive/Views/UpdateView.swift +++ b/Sources/Secretive/Views/UpdateView.swift @@ -9,22 +9,22 @@ struct UpdateDetailView: View { var body: some View { VStack { - Text("update_version_name_\(update.name)").font(.title) - GroupBox(label: Text("update_release_notes_title")) { + Text(.updateVersionName(update.name)).font(.title) + GroupBox(label: Text(.updateReleaseNotesTitle)) { ScrollView { attributedBody } } HStack { if !update.critical { - Button("update_ignore_button") { + Button(.updateIgnoreButton) { Task { await updater.ignore(release: update) } } Spacer() } - Button("update_update_button") { + Button(.updateUpdateButton) { NSWorkspace.shared.open(update.html_url) } .keyboardShortcut(.defaultAction)