This commit is contained in:
Max Goedjen 2025-09-01 19:37:59 -07:00
parent 74ddb9595b
commit df2b7881c4
No known key found for this signature in database
4 changed files with 182 additions and 174 deletions

View File

@ -2604,9 +2604,6 @@
} }
} }
} }
},
"Done" : {
}, },
"edit_cancel_button" : { "edit_cancel_button" : {
"extractionState" : "manual", "extractionState" : "manual",
@ -3179,6 +3176,17 @@
} }
} }
}, },
"integrations_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."
}
}
}
},
"integrations_getting_started_row_title" : { "integrations_getting_started_row_title" : {
"extractionState" : "manual", "extractionState" : "manual",
"localizations" : { "localizations" : {
@ -3201,6 +3209,83 @@
} }
} }
}, },
"integrations_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."
}
}
}
},
"integrations_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."
}
}
}
},
"integrations_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)@`."
}
}
}
},
"integrations_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."
}
}
}
},
"integrations_getting_started_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Configuring Tools for Secretive"
}
}
}
},
"integrations_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."
}
}
}
},
"integrations_getting_started_what_should_i_configure_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "What Should I Configure?"
}
}
}
},
"integrations_other_section_title" : { "integrations_other_section_title" : {
"extractionState" : "manual", "extractionState" : "manual",
"localizations" : { "localizations" : {
@ -3520,138 +3605,6 @@
} }
} }
}, },
"onboarding_done_button" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Done"
}
}
}
},
"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" : {
"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"
}
}
}
},
"persist_authentication_accept_button" : { "persist_authentication_accept_button" : {
"comment" : "When the user authorizes an action using a secret that requires unlock, they're shown a notification offering to leave the secret unlocked for a set period of time. This is the title for the notification.", "comment" : "When the user authorizes an action using a secret that requires unlock, they're shown a notification offering to leave the secret unlocked for a set period of time. This is the title for the notification.",
"extractionState" : "manual", "extractionState" : "manual",
@ -4610,6 +4563,50 @@
} }
} }
}, },
"setup_done_button" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Done"
}
}
}
},
"setup_integrations_button" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Configure"
}
}
}
},
"setup_integrations_description" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tell the tools you use how to talk to Secretive."
}
}
}
},
"setup_integrations_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Configure Integrations"
}
}
}
},
"setup_ssh_add_for_me_button" : { "setup_ssh_add_for_me_button" : {
"extractionState" : "manual", "extractionState" : "manual",
"localizations" : { "localizations" : {
@ -5184,7 +5181,7 @@
} }
} }
}, },
"setup_updates_ok" : { "setup_updates_ok_button" : {
"extractionState" : "manual", "extractionState" : "manual",
"localizations" : { "localizations" : {
"ca" : { "ca" : {
@ -5397,6 +5394,17 @@
} }
} }
}, },
"setupStepCompleteButton" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Done"
}
}
}
},
"signed_notification_description" : { "signed_notification_description" : {
"comment" : "When the user performs an action using a secret, they're shown a notification describing what happened. This is the description, showing which secret was used. The placeholder is the name of the secret.", "comment" : "When the user performs an action using a secret, they're shown a notification describing what happened. This is the description, showing which secret was used. The placeholder is the name of the secret.",
"extractionState" : "manual", "extractionState" : "manual",

View File

@ -22,22 +22,22 @@ struct AgentRunningView: View {
Section { Section {
if let process = agentStatusChecker.process { if let process = agentStatusChecker.process {
ConfigurationItemView( ConfigurationItemView(
title: LocalizedStringResource.agentDetailsLocationTitle, title: .agentDetailsLocationTitle,
value: process.bundleURL!.path(), value: process.bundleURL!.path(),
action: .revealInFinder(process.bundleURL!.path()), action: .revealInFinder(process.bundleURL!.path()),
) )
ConfigurationItemView( ConfigurationItemView(
title: LocalizedStringResource.agentDetailsSocketPathTitle, title: .agentDetailsSocketPathTitle,
value: socketPath, value: socketPath,
action: .copy(socketPath), action: .copy(socketPath),
) )
ConfigurationItemView( ConfigurationItemView(
title: LocalizedStringResource.agentDetailsVersionTitle, title: .agentDetailsVersionTitle,
value: Bundle(url: process.bundleURL!)!.infoDictionary!["CFBundleShortVersionString"] as! String value: Bundle(url: process.bundleURL!)!.infoDictionary!["CFBundleShortVersionString"] as! String
) )
if let launchDate = process.launchDate { if let launchDate = process.launchDate {
ConfigurationItemView( ConfigurationItemView(
title: LocalizedStringResource.agentDetailsRunningSinceTitle, title: .agentDetailsRunningSinceTitle,
value: launchDate.formatted() value: launchDate.formatted()
) )
} }

View File

@ -23,7 +23,7 @@ struct IntegrationsView: View {
} detail: { } detail: {
IntegrationsDetailView(selectedInstruction: $selectedInstruction) IntegrationsDetailView(selectedInstruction: $selectedInstruction)
.fauxToolbar { .fauxToolbar {
Button(.onboardingDoneButton) { Button(.setupDoneButton) {
dismiss() dismiss()
} }
.normalButton() .normalButton()
@ -80,24 +80,24 @@ struct IntegrationsDetailView: View {
switch selectedInstruction.id { switch selectedInstruction.id {
case .gettingStarted: case .gettingStarted:
Form { Form {
Section(.onboardingGettingStartedTitle) { Section(.integrationsGettingStartedTitle) {
Text(.onboardingGettingStartedTitleDescription) Text(.integrationsGettingStartedTitleDescription)
} }
Section { Section {
Group { Group {
Text(.onboardingGettingStartedSuggestionSsh) Text(.integrationsGettingStartedSuggestionSsh)
.onTapGesture { .onTapGesture {
self.selectedInstruction = instructions.ssh self.selectedInstruction = instructions.ssh
} }
VStack(alignment: .leading, spacing: 5) { VStack(alignment: .leading, spacing: 5) {
Text(.onboardingGettingStartedSuggestionShell) Text(.integrationsGettingStartedSuggestionShell)
Text(.onboardingGettingStartedSuggestionShellDefault(shellName: instructions.defaultShell.tool)) Text(.integrationsGettingStartedSuggestionShellDefault(shellName: instructions.defaultShell.tool))
.font(.caption2) .font(.caption2)
} }
.onTapGesture { .onTapGesture {
self.selectedInstruction = instructions.defaultShell self.selectedInstruction = instructions.defaultShell
} }
Text(.onboardingGettingStartedSuggestionGit) Text(.integrationsGettingStartedSuggestionGit)
.onTapGesture { .onTapGesture {
self.selectedInstruction = instructions.git self.selectedInstruction = instructions.git
} }
@ -105,10 +105,10 @@ struct IntegrationsDetailView: View {
.foregroundStyle(.link) .foregroundStyle(.link)
} header: { } header: {
Text(.onboardingGettingStartedWhatShouldIConfigureTitle) Text(.integrationsGettingStartedWhatShouldIConfigureTitle)
} }
footer: { footer: {
Text(.onboardingGettingStartedMultipleConfig) Text(.integrationsGettingStartedMultipleConfig)
} }
} }
.formStyle(.grouped) .formStyle(.grouped)
@ -116,9 +116,9 @@ struct IntegrationsDetailView: View {
Form { Form {
ForEach(selectedInstruction.steps) { stepGroup in ForEach(selectedInstruction.steps) { stepGroup in
Section { Section {
ConfigurationItemView(title: LocalizedStringResource.integrationsPathTitle, value: stepGroup.path, action: .revealInFinder(stepGroup.path)) ConfigurationItemView(title: .integrationsPathTitle, value: stepGroup.path, action: .revealInFinder(stepGroup.path))
ForEach(stepGroup.steps, id: \.self) { step in ForEach(stepGroup.steps, id: \.self) { step in
ConfigurationItemView(title: LocalizedStringResource.integrationsAddThisTitle, action: .copy(step)) { ConfigurationItemView(title: .integrationsAddThisTitle, action: .copy(step)) {
HStack { HStack {
Text(step) Text(step)
.padding(8) .padding(8)
@ -190,7 +190,7 @@ private struct Instructions {
zsh zsh
} }
var gettingStarted: ConfigurationFileInstructions = ConfigurationFileInstructions(LocalizedStringResource.integrationsGettingStartedRowTitle, id: .gettingStarted) var gettingStarted: ConfigurationFileInstructions = ConfigurationFileInstructions(.integrationsGettingStartedRowTitle, id: .gettingStarted)
var ssh: ConfigurationFileInstructions { var ssh: ConfigurationFileInstructions {
ConfigurationFileInstructions( ConfigurationFileInstructions(
@ -243,17 +243,17 @@ private struct Instructions {
var instructions: [ConfigurationGroup] { var instructions: [ConfigurationGroup] {
[ [
ConfigurationGroup(name: LocalizedStringResource.integrationsGettingStartedSectionTitle, instructions: [ ConfigurationGroup(name: .integrationsGettingStartedSectionTitle, instructions: [
gettingStarted gettingStarted
]), ]),
ConfigurationGroup( ConfigurationGroup(
name: LocalizedStringResource.integrationsSystemSectionTitle, name: .integrationsSystemSectionTitle,
instructions: [ instructions: [
ssh, ssh,
git, git,
] ]
), ),
ConfigurationGroup(name: LocalizedStringResource.integrationsShellSectionTitle, instructions: [ ConfigurationGroup(name: .integrationsShellSectionTitle, instructions: [
zsh, zsh,
ConfigurationFileInstructions( ConfigurationFileInstructions(
tool: "bash", tool: "bash",
@ -265,10 +265,10 @@ private struct Instructions {
configPath: "~/.config/fish/config.fish", configPath: "~/.config/fish/config.fish",
configText: "set -x SSH_AUTH_SOCK \(socketPath)" configText: "set -x SSH_AUTH_SOCK \(socketPath)"
), ),
ConfigurationFileInstructions(LocalizedStringResource.integrationsOtherShellRowTitle, id: .otherShell), ConfigurationFileInstructions(.integrationsOtherShellRowTitle, id: .otherShell),
]), ]),
ConfigurationGroup(name: LocalizedStringResource.integrationsOtherSectionTitle, instructions: [ ConfigurationGroup(name: .integrationsOtherSectionTitle, instructions: [
ConfigurationFileInstructions(LocalizedStringResource.integrationsAppsRowTitle, id: .otherApp), ConfigurationFileInstructions(.integrationsAppsRowTitle, id: .otherApp),
]), ]),
] ]
} }

View File

@ -19,12 +19,12 @@ struct SetupView: View {
VStack { VStack {
VStack(alignment: .leading, spacing: 0) { VStack(alignment: .leading, spacing: 0) {
StepView( StepView(
title: "setup_agent_title", title: .setupAgentTitle,
description: "setup_agent_description", description: .setupAgentDescription,
systemImage: "lock.laptopcomputer", systemImage: "lock.laptopcomputer",
) { ) {
OnboardingButton( setupButton(
"setup_agent_install_button", .setupAgentInstallButton,
complete: installed, complete: installed,
width: buttonWidth width: buttonWidth
) { ) {
@ -36,12 +36,12 @@ struct SetupView: View {
} }
Divider() Divider()
StepView( StepView(
title: "setup_updates_title", title: .setupUpdatesTitle,
description: "setup_updates_description", description: .setupUpdatesDescription,
systemImage: "network.badge.shield.half.filled", systemImage: "network.badge.shield.half.filled",
) { ) {
OnboardingButton( setupButton(
"setup_updates_ok", .setupUpdatesOkButton,
complete: updates, complete: updates,
width: buttonWidth width: buttonWidth
) { ) {
@ -50,12 +50,12 @@ struct SetupView: View {
} }
Divider() Divider()
StepView( StepView(
title: .onboardingIntegrationsTitle, title: .setupIntegrationsTitle,
description: LocalizedStringResource.onboardingIntegrationsDescription, description: .setupIntegrationsDescription,
systemImage: "firewall", systemImage: "firewall",
) { ) {
OnboardingButton( setupButton(
LocalizedStringResource.onboardingIntegrationsButton, .setupIntegrationsButton,
complete: integrations, complete: integrations,
width: buttonWidth width: buttonWidth
) { ) {
@ -63,14 +63,14 @@ struct SetupView: View {
} }
} }
} }
.onPreferenceChange(OnboardingButton.WidthKey.self) { width in .onPreferenceChange(setupButton.WidthKey.self) { width in
buttonWidth = width buttonWidth = width
} }
.background(.white.opacity(0.1), in: RoundedRectangle(cornerRadius: 10)) .background(.white.opacity(0.1), in: RoundedRectangle(cornerRadius: 10))
.frame(minWidth: 700, maxWidth: .infinity) .frame(minWidth: 700, maxWidth: .infinity)
HStack { HStack {
Spacer() Spacer()
Button(.onboardingDoneButton) { Button(.setupDoneButton) {
setupComplete = true setupComplete = true
dismiss() dismiss()
} }
@ -88,7 +88,7 @@ struct SetupView: View {
} }
} }
struct OnboardingButton: View { struct setupButton: View {
struct WidthKey: @MainActor PreferenceKey { struct WidthKey: @MainActor PreferenceKey {
@MainActor static var defaultValue: CGFloat? = nil @MainActor static var defaultValue: CGFloat? = nil
@ -117,7 +117,7 @@ struct OnboardingButton: View {
Button(action: action) { Button(action: action) {
HStack(spacing: 6) { HStack(spacing: 6) {
if complete { if complete {
Text("Done") Text(.setupStepCompleteButton)
Image(systemName: "checkmark.circle.fill") Image(systemName: "checkmark.circle.fill")
} else { } else {
Text(label) Text(label)