From 0980cdffcd585348fea3a91c115430e90c0b8ee0 Mon Sep 17 00:00:00 2001 From: Max Goedjen Date: Mon, 1 Sep 2025 19:25:14 -0700 Subject: [PATCH] WIP --- Sources/Packages/Localizable.xcstrings | 549 +++++++++--------- Sources/Secretive/Views/AgentStatusView.swift | 18 +- .../Secretive/Views/IntegrationsView.swift | 34 +- Sources/Secretive/Views/SetupView.swift | 6 +- 4 files changed, 317 insertions(+), 290 deletions(-) diff --git a/Sources/Packages/Localizable.xcstrings b/Sources/Packages/Localizable.xcstrings index 503e754..7022a66 100644 --- a/Sources/Packages/Localizable.xcstrings +++ b/Sources/Packages/Localizable.xcstrings @@ -3,6 +3,94 @@ "strings" : { "" : { + }, + "agent_details_could_not_start_error" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Secretive was unable to get SecretAgent to launch. Please try restarting your Mac, and if that doesn't work, file an issue on GitHub." + } + } + } + }, + "agent_details_disable_agent_button" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Disable Agent" + } + } + } + }, + "agent_details_restart_agent_button" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Restart Agent" + } + } + } + }, + "agent_details_running_since_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Running Since" + } + } + } + }, + "agent_details_socket_path_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Socket Path" + } + } + } + }, + "agent_details_start_agent_button" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Start Agent" + } + } + } + }, + "agent_details_start_agent_button_starting" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Starting Agent" + } + } + } + }, + "agent_details_version_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Version" + } + } + } }, "agent_not_running_notice_detail_description" : { "extractionState" : "manual", @@ -400,6 +488,17 @@ } } }, + "agentDetailsLocationTitle" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Secret Agent Location" + } + } + } + }, "app_menu_help_button" : { "extractionState" : "manual", "localizations" : { @@ -785,16 +884,6 @@ } } }, - "Apps" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Apps" - } - } - } - }, "auth_context_persist_for_duration" : { "comment" : "When the user clicks the notification to leave a secret unlocked, they are shown a prompt to approve the action. This is the description, showing which secret will used. The first placeholder is the name of the secret. The second placeholder is a localized description of the time period it will remain unlocked for (eg: \"five minutes\")", "extractionState" : "manual", @@ -1185,46 +1274,6 @@ } } }, - "Configuration File" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuration File" - } - } - } - }, - "Configure" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configure" - } - } - } - }, - "Configure Integrations" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configure Integrations" - } - } - } - }, - "Configuring Tools for Secretive" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuring Tools for Secretive" - } - } - } - }, "Copy" : { "localizations" : { "en" : { @@ -2555,16 +2604,6 @@ } } }, - "Disable Agent" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Disable Agent" - } - } - } - }, "Done" : { "localizations" : { "en" : { @@ -3112,46 +3151,6 @@ } } }, - "If you don't known what shell you use and haven't changed it, you're probably using `%@`." : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "If you don't known what shell you use and haven't changed it, you're probably using `%@`." - } - } - } - }, - "If you're trying to authenticate with an SSH server or authenticating with a service like GitHub over SSH, configure your SSH client." : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "If you're trying to authenticate with an SSH server or authenticating with a service like GitHub over SSH, configure your SSH client." - } - } - } - }, - "If you're trying to configure anything your command line runs to use Secretive, configure your shell." : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "If you're trying to configure anything your command line runs to use Secretive, configure your shell." - } - } - } - }, - "If you're trying to sign your git commits, set up Git Signing." : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "If you're trying to sign your git commits, set up Git Signing." - } - } - } - }, "Integrations" : { "localizations" : { "en" : { @@ -3163,6 +3162,7 @@ } }, "integrations_add_this_title" : { + "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { @@ -3172,22 +3172,78 @@ } } }, + "integrations_apps_row_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Apps" + } + } + } + }, + "integrations_community_apps_list_description" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "There's a community-maintained list of instructions for apps on GitHub. If the app you're looking for isn't supported, create an issue and the community may be able to help." + } + } + } + }, + "integrations_community_shell_list_description" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "There's a community-maintained list of shell instructions on GitHub. If the shell you're looking for isn't supported, create an issue and the community may be able to help." + } + } + } + }, + "integrations_path_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configuration File" + } + } + } + }, + "integrations_view_other_github_link" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "View on GitHub" + } + } + } + }, + "integrations_web_link" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "View Documentation on Web" + } + } + } + }, "Integrations..." : { "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "Add This:" - } - } - } - }, - "Most tools will try and look for SSH keys on disk in `~/.ssh`. To use Secretive, we need to configure those tools to talk to Secretive instead." : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Most tools will try and look for SSH keys on disk in `~/.ssh`. To use Secretive, we need to configure those tools to talk to Secretive instead." + "value" : "Integrations…" } } } @@ -3423,6 +3479,127 @@ } } }, + "onboarding_getting_started_multiple_config" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "You can configure more than one tool, they generally won't interfere with each other." + } + } + } + }, + "onboarding_getting_started_suggestion_git" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "If you're trying to sign your git commits, set up Git Signing." + } + } + } + }, + "onboarding_getting_started_suggestion_shell" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "If you're trying to configure anything your command line runs to use Secretive, configure your shell." + } + } + } + }, + "onboarding_getting_started_suggestion_shell_default" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "If you don't known what shell you use and haven't changed it, you're probably using `%(shellName)@`." + } + } + } + }, + "onboarding_getting_started_suggestion_ssh" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "If you're trying to authenticate with an SSH server or authenticating with a service like GitHub over SSH, configure your SSH client." + } + } + } + }, + "onboarding_getting_started_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configuring Tools for Secretive" + } + } + } + }, + "onboarding_getting_started_title_description" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Most tools will try and look for SSH keys on disk in `~/.ssh`. To use Secretive, we need to configure those tools to talk to Secretive instead." + } + } + } + }, + "onboarding_getting_started_what_should_i_configure_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "What Should I Configure?" + } + } + } + }, + "onboarding_integrations_button_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configure" + } + } + } + }, + "onboarding_integrations_description" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tell the tools you use how to talk to Secretive." + } + } + } + }, + "onboarding_integrations_title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configure Integrations" + } + } + } + }, "other" : { }, @@ -3585,16 +3762,6 @@ } } }, - "Restart Agent" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Restart Agent" - } - } - } - }, "Reveal in Finder" : { "localizations" : { "en" : { @@ -3605,26 +3772,6 @@ } } }, - "Running Since" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Running Since" - } - } - } - }, - "Secret Agent Location" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Secret Agent Location" - } - } - } - }, "secret_detail_md5_fingerprint_label" : { "extractionState" : "manual", "localizations" : { @@ -4051,16 +4198,6 @@ } } }, - "Secretive was unable to get SecretAgent to launch. Please try restarting your Mac, and if that doesn't work, file an issue on GitHub." : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Secretive was unable to get SecretAgent to launch. Please try restarting your Mac, and if that doesn't work, file an issue on GitHub." - } - } - } - }, "secure_enclave" : { "extractionState" : "manual", "localizations" : { @@ -5450,36 +5587,6 @@ } } }, - "Socket Path" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Socket Path" - } - } - } - }, - "Start Agent" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Start Agent" - } - } - } - }, - "Starting Agent" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Starting Agent" - } - } - } - }, "System" : { "localizations" : { "en" : { @@ -5490,36 +5597,6 @@ } } }, - "Tell the tools you use how to talk to Secretive." : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Tell the tools you use how to talk to Secretive." - } - } - } - }, - "There's a community-maintained list of instructions for apps on GitHub. If the app you're looking for isn't supported, create an issue and the community may be able to help." : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "There's a community-maintained list of instructions for apps on GitHub. If the app you're looking for isn't supported, create an issue and the community may be able to help." - } - } - } - }, - "There's a community-maintained list of shell instructions on GitHub. If the shell you're looking for isn't supported, create an issue and the community may be able to help." : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "There's a community-maintained list of shell instructions on GitHub. If the shell you're looking for isn't supported, create an issue and the community may be able to help." - } - } - } - }, "unnamed_secret" : { "extractionState" : "manual", "localizations" : { @@ -6465,56 +6542,6 @@ } } } - }, - "Version" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Version" - } - } - } - }, - "View Documentation on Web" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "View Documentation on Web" - } - } - } - }, - "View on GitHub" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "View on GitHub" - } - } - } - }, - "What Should I Configure?" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "What Should I Configure?" - } - } - } - }, - "You can configure more than one tool, they generally won't interfere with each other." : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "You can configure more than one tool, they generally won't interfere with each other." - } - } - } } }, "version" : "1.0" diff --git a/Sources/Secretive/Views/AgentStatusView.swift b/Sources/Secretive/Views/AgentStatusView.swift index 931f449..082eccf 100644 --- a/Sources/Secretive/Views/AgentStatusView.swift +++ b/Sources/Secretive/Views/AgentStatusView.swift @@ -22,22 +22,22 @@ struct AgentRunningView: View { Section { if let process = agentStatusChecker.process { ConfigurationItemView( - title: "Secret Agent Location", + title: LocalizedStringResource.agentDetailsLocationTitle, value: process.bundleURL!.path(), action: .revealInFinder(process.bundleURL!.path()), ) ConfigurationItemView( - title: "Socket Path", + title: LocalizedStringResource.agentDetailsSocketPathTitle, value: socketPath, action: .copy(socketPath), ) ConfigurationItemView( - title: "Version", + title: LocalizedStringResource.agentDetailsVersionTitle, value: Bundle(url: process.bundleURL!)!.infoDictionary!["CFBundleShortVersionString"] as! String ) if let launchDate = process.launchDate { ConfigurationItemView( - title: "Running Since", + title: LocalizedStringResource.agentDetailsRunningSinceTitle, value: launchDate.formatted() ) } @@ -51,8 +51,8 @@ struct AgentRunningView: View { Text(.agentRunningNoticeDetailDescription) HStack { Spacer() - Menu("Restart Agent") { - Button("Disable Agent") { + Menu(.agentDetailsRestartAgentButton) { + Button(.agentDetailsDisableAgentButton) { Task { _ = await LaunchAgentController() .uninstall() @@ -118,10 +118,10 @@ struct AgentNotRunningView: View { } } label: { if !loading { - Text("Start Agent") + Text(.agentDetailsStartAgentButton) } else { HStack { - Text("Starting Agent") + Text(.agentDetailsStartAgentButtonStarting) ProgressView() .controlSize(.mini) } @@ -129,7 +129,7 @@ struct AgentNotRunningView: View { } .primaryButton() } else { - Text("Secretive was unable to get SecretAgent to launch. Please try restarting your Mac, and if that doesn't work, file an issue on GitHub.") + Text(.agentDetailsCouldNotStartError) .bold() .foregroundStyle(.red) } diff --git a/Sources/Secretive/Views/IntegrationsView.swift b/Sources/Secretive/Views/IntegrationsView.swift index fa53196..01be401 100644 --- a/Sources/Secretive/Views/IntegrationsView.swift +++ b/Sources/Secretive/Views/IntegrationsView.swift @@ -80,24 +80,24 @@ struct IntegrationsDetailView: View { switch selectedInstruction.id { case .gettingStarted: Form { - Section("Configuring Tools for Secretive") { - Text("Most tools will try and look for SSH keys on disk in `~/.ssh`. To use Secretive, we need to configure those tools to talk to Secretive instead.") + Section(.onboardingGettingStartedTitle) { + Text(.onboardingGettingStartedTitleDescription) } Section { Group { - Text("If you're trying to authenticate with an SSH server or authenticating with a service like GitHub over SSH, configure your SSH client.") + Text(.onboardingGettingStartedSuggestionSsh) .onTapGesture { self.selectedInstruction = instructions.ssh } VStack(alignment: .leading, spacing: 5) { - Text("If you're trying to configure anything your command line runs to use Secretive, configure your shell.") - Text("If you don't known what shell you use and haven't changed it, you're probably using `\(instructions.defaultShell.tool)`.") + Text(.onboardingGettingStartedSuggestionShell) + Text(.onboardingGettingStartedSuggestionShellDefault(shellName: instructions.defaultShell.tool)) .font(.caption2) } .onTapGesture { self.selectedInstruction = instructions.defaultShell } - Text("If you're trying to sign your git commits, set up Git Signing.") + Text(.onboardingGettingStartedSuggestionGit) .onTapGesture { self.selectedInstruction = instructions.git } @@ -105,10 +105,10 @@ struct IntegrationsDetailView: View { .foregroundStyle(.link) } header: { - Text("What Should I Configure?") + Text(.onboardingGettingStartedWhatShouldIConfigureTitle) } footer: { - Text("You can configure more than one tool, they generally won't interfere with each other.") + Text(.onboardingGettingStartedMultipleConfig) } } .formStyle(.grouped) @@ -116,9 +116,9 @@ struct IntegrationsDetailView: View { Form { ForEach(selectedInstruction.steps) { stepGroup in Section { - ConfigurationItemView(title: "Configuration File", value: stepGroup.path, action: .revealInFinder(stepGroup.path)) + ConfigurationItemView(title: LocalizedStringResource.integrationsPathTitle, value: stepGroup.path, action: .revealInFinder(stepGroup.path)) ForEach(stepGroup.steps, id: \.self) { step in - ConfigurationItemView(title: "integrations_add_this_title", action: .copy(step)) { + ConfigurationItemView(title: LocalizedStringResource.integrationsAddThisTitle, action: .copy(step)) { HStack { Text(step) .padding(8) @@ -144,7 +144,7 @@ struct IntegrationsDetailView: View { Section { Link(destination: url) { VStack(alignment: .leading, spacing: 5) { - Text("View Documentation on Web") + Text(.integrationsWebLink) .font(.headline) Text(url.absoluteString) .font(.caption2) @@ -157,9 +157,9 @@ struct IntegrationsDetailView: View { case .otherShell: Form { Section { - Link("View on GitHub", destination: URL(string: "https://github.com/maxgoedjen/secretive-config-instructions/tree/main/shells")!) + Link(.integrationsViewOtherGithubLink, destination: URL(string: "https://github.com/maxgoedjen/secretive-config-instructions/tree/main/shells")!) } header: { - Text("There's a community-maintained list of shell instructions on GitHub. If the shell you're looking for isn't supported, create an issue and the community may be able to help.") + Text(.integrationsCommunityShellListDescription) .font(.body) } } @@ -168,9 +168,9 @@ struct IntegrationsDetailView: View { case .otherApp: Form { Section { - Link("View on GitHub", destination: URL(string: "https://github.com/maxgoedjen/secretive-config-instructions/tree/main/apps")!) + Link(.integrationsViewOtherGithubLink, destination: URL(string: "https://github.com/maxgoedjen/secretive-config-instructions/tree/main/apps")!) } header: { - Text("There's a community-maintained list of instructions for apps on GitHub. If the app you're looking for isn't supported, create an issue and the community may be able to help.") + Text(.integrationsCommunityAppsListDescription) .font(.body) } } @@ -243,7 +243,7 @@ private struct Instructions { var instructions: [ConfigurationGroup] { [ - ConfigurationGroup(name:"Integrations", instructions: [ + ConfigurationGroup(name: "Integrations", instructions: [ gettingStarted ]), ConfigurationGroup( @@ -268,7 +268,7 @@ private struct Instructions { ConfigurationFileInstructions("other", id: .otherShell), ]), ConfigurationGroup(name: "Other", instructions: [ - ConfigurationFileInstructions("Apps", id: .otherApp), + ConfigurationFileInstructions(LocalizedStringResource.integrationsAppsRowTitle, id: .otherApp), ]), ] } diff --git a/Sources/Secretive/Views/SetupView.swift b/Sources/Secretive/Views/SetupView.swift index 0eed09f..ad26638 100644 --- a/Sources/Secretive/Views/SetupView.swift +++ b/Sources/Secretive/Views/SetupView.swift @@ -50,12 +50,12 @@ struct SetupView: View { } Divider() StepView( - title: "Configure Integrations", - description: "Tell the tools you use how to talk to Secretive.", + title: .onboardingIntegrationsTitle, + description: LocalizedStringResource.onboardingIntegrationsDescription, systemImage: "firewall", ) { OnboardingButton( - "Configure", + LocalizedStringResource.onboardingIntegrationsButtonTitle, complete: integrations, width: buttonWidth ) {