mirror of
https://github.com/maxgoedjen/secretive.git
synced 2025-09-16 09:20:56 +00:00
WIP
This commit is contained in:
parent
f0a6f2e43b
commit
cbf903deb7
@ -1,6 +1,9 @@
|
|||||||
{
|
{
|
||||||
"sourceLanguage" : "en",
|
"sourceLanguage" : "en",
|
||||||
"strings" : {
|
"strings" : {
|
||||||
|
"Add Automatically" : {
|
||||||
|
|
||||||
|
},
|
||||||
"agent_not_running_notice_title" : {
|
"agent_not_running_notice_title" : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@ -4323,6 +4326,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"setup_ssh_add_to_config_button_%@" : {
|
||||||
|
|
||||||
},
|
},
|
||||||
"setup_ssh_added_manually_button" : {
|
"setup_ssh_added_manually_button" : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
@ -5189,9 +5195,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"Test" : {
|
|
||||||
|
|
||||||
},
|
},
|
||||||
"unnamed_secret" : {
|
"unnamed_secret" : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
5099A02423FD2AAA0062B6F2 /* CreateSecretView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5099A02323FD2AAA0062B6F2 /* CreateSecretView.swift */; };
|
5099A02423FD2AAA0062B6F2 /* CreateSecretView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5099A02323FD2AAA0062B6F2 /* CreateSecretView.swift */; };
|
||||||
50A3B79424026B7600D209EA /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 50A3B79324026B7600D209EA /* Preview Assets.xcassets */; };
|
50A3B79424026B7600D209EA /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 50A3B79324026B7600D209EA /* Preview Assets.xcassets */; };
|
||||||
50A3B79724026B7600D209EA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 50A3B79524026B7600D209EA /* Main.storyboard */; };
|
50A3B79724026B7600D209EA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 50A3B79524026B7600D209EA /* Main.storyboard */; };
|
||||||
|
50AE97002E5C1A420018C710 /* ConfigurationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50AE96FF2E5C1A420018C710 /* ConfigurationView.swift */; };
|
||||||
50B8550D24138C4F009958AC /* DeleteSecretView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50B8550C24138C4F009958AC /* DeleteSecretView.swift */; };
|
50B8550D24138C4F009958AC /* DeleteSecretView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50B8550C24138C4F009958AC /* DeleteSecretView.swift */; };
|
||||||
50BB046B2418AAAE00D6E079 /* EmptyStoreView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50BB046A2418AAAE00D6E079 /* EmptyStoreView.swift */; };
|
50BB046B2418AAAE00D6E079 /* EmptyStoreView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50BB046A2418AAAE00D6E079 /* EmptyStoreView.swift */; };
|
||||||
50C385A52407A76D00AF2719 /* SecretDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50C385A42407A76D00AF2719 /* SecretDetailView.swift */; };
|
50C385A52407A76D00AF2719 /* SecretDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50C385A42407A76D00AF2719 /* SecretDetailView.swift */; };
|
||||||
@ -137,6 +138,7 @@
|
|||||||
50A3B79624026B7600D209EA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
50A3B79624026B7600D209EA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
||||||
50A3B79824026B7600D209EA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
50A3B79824026B7600D209EA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
50A3B79924026B7600D209EA /* SecretAgent.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SecretAgent.entitlements; sourceTree = "<group>"; };
|
50A3B79924026B7600D209EA /* SecretAgent.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SecretAgent.entitlements; sourceTree = "<group>"; };
|
||||||
|
50AE96FF2E5C1A420018C710 /* ConfigurationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigurationView.swift; sourceTree = "<group>"; };
|
||||||
50B8550C24138C4F009958AC /* DeleteSecretView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeleteSecretView.swift; sourceTree = "<group>"; };
|
50B8550C24138C4F009958AC /* DeleteSecretView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeleteSecretView.swift; sourceTree = "<group>"; };
|
||||||
50BB046A2418AAAE00D6E079 /* EmptyStoreView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyStoreView.swift; sourceTree = "<group>"; };
|
50BB046A2418AAAE00D6E079 /* EmptyStoreView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyStoreView.swift; sourceTree = "<group>"; };
|
||||||
50C385A42407A76D00AF2719 /* SecretDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretDetailView.swift; sourceTree = "<group>"; };
|
50C385A42407A76D00AF2719 /* SecretDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretDetailView.swift; sourceTree = "<group>"; };
|
||||||
@ -251,6 +253,7 @@
|
|||||||
506772C82425BB8500034DED /* NoStoresView.swift */,
|
506772C82425BB8500034DED /* NoStoresView.swift */,
|
||||||
50153E1F250AFCB200525160 /* UpdateView.swift */,
|
50153E1F250AFCB200525160 /* UpdateView.swift */,
|
||||||
5066A6C12516F303004B5A36 /* SetupView.swift */,
|
5066A6C12516F303004B5A36 /* SetupView.swift */,
|
||||||
|
50AE96FF2E5C1A420018C710 /* ConfigurationView.swift */,
|
||||||
5066A6C72516FE6E004B5A36 /* CopyableView.swift */,
|
5066A6C72516FE6E004B5A36 /* CopyableView.swift */,
|
||||||
);
|
);
|
||||||
path = Views;
|
path = Views;
|
||||||
@ -443,6 +446,7 @@
|
|||||||
508A58B3241ED2180069DC07 /* AgentStatusChecker.swift in Sources */,
|
508A58B3241ED2180069DC07 /* AgentStatusChecker.swift in Sources */,
|
||||||
50C385A52407A76D00AF2719 /* SecretDetailView.swift in Sources */,
|
50C385A52407A76D00AF2719 /* SecretDetailView.swift in Sources */,
|
||||||
5099A02423FD2AAA0062B6F2 /* CreateSecretView.swift in Sources */,
|
5099A02423FD2AAA0062B6F2 /* CreateSecretView.swift in Sources */,
|
||||||
|
50AE97002E5C1A420018C710 /* ConfigurationView.swift in Sources */,
|
||||||
50153E20250AFCB200525160 /* UpdateView.swift in Sources */,
|
50153E20250AFCB200525160 /* UpdateView.swift in Sources */,
|
||||||
50571E0524393D1500F76F6C /* LaunchAgentController.swift in Sources */,
|
50571E0524393D1500F76F6C /* LaunchAgentController.swift in Sources */,
|
||||||
5066A6C82516FE6E004B5A36 /* CopyableView.swift in Sources */,
|
5066A6C82516FE6E004B5A36 /* CopyableView.swift in Sources */,
|
||||||
|
@ -71,7 +71,7 @@ struct Secretive: App {
|
|||||||
NSWorkspace.shared.open(Constants.helpURL)
|
NSWorkspace.shared.open(Constants.helpURL)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CommandGroup(after: .help) {
|
CommandGroup(before: .help) {
|
||||||
Button(.appMenuSetupButton) {
|
Button(.appMenuSetupButton) {
|
||||||
showingSetup = true
|
showingSetup = true
|
||||||
}
|
}
|
||||||
|
@ -24,13 +24,14 @@ import Observation
|
|||||||
}
|
}
|
||||||
|
|
||||||
// All processes, including ones from older versions, etc
|
// All processes, including ones from older versions, etc
|
||||||
var secretAgentProcesses: [NSRunningApplication] {
|
var allSecretAgentProcesses: [NSRunningApplication] {
|
||||||
NSRunningApplication.runningApplications(withBundleIdentifier: Bundle.main.agentBundleID)
|
NSRunningApplication.runningApplications(withBundleIdentifier: Bundle.agentBundleID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// The process corresponding to this instance of Secretive
|
// The process corresponding to this instance of Secretive
|
||||||
var instanceSecretAgentProcess: NSRunningApplication? {
|
var instanceSecretAgentProcess: NSRunningApplication? {
|
||||||
let agents = secretAgentProcesses
|
// FIXME: CHECK VERSION
|
||||||
|
let agents = allSecretAgentProcesses
|
||||||
for agent in agents {
|
for agent in agents {
|
||||||
guard let url = agent.bundleURL else { continue }
|
guard let url = agent.bundleURL else { continue }
|
||||||
if url.absoluteString.hasPrefix(Bundle.main.bundleURL.absoluteString) {
|
if url.absoluteString.hasPrefix(Bundle.main.bundleURL.absoluteString) {
|
||||||
@ -40,7 +41,6 @@ import Observation
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Whether Secretive is being run in an Xcode environment.
|
// Whether Secretive is being run in an Xcode environment.
|
||||||
var developmentBuild: Bool {
|
var developmentBuild: Bool {
|
||||||
Bundle.main.bundleURL.absoluteString.contains("/Library/Developer/Xcode")
|
Bundle.main.bundleURL.absoluteString.contains("/Library/Developer/Xcode")
|
||||||
|
@ -36,7 +36,7 @@ struct LaunchAgentController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func setEnabled(_ enabled: Bool) -> Bool {
|
private func setEnabled(_ enabled: Bool) -> Bool {
|
||||||
let service = SMAppService.loginItem(identifier: Bundle.main.agentBundleID)
|
let service = SMAppService.loginItem(identifier: Bundle.agentBundleID)
|
||||||
do {
|
do {
|
||||||
if enabled {
|
if enabled {
|
||||||
try service.register()
|
try service.register()
|
||||||
|
@ -4,7 +4,7 @@ import SecretKit
|
|||||||
|
|
||||||
struct ShellConfigurationController {
|
struct ShellConfigurationController {
|
||||||
|
|
||||||
let socketPath = (NSHomeDirectory().replacingOccurrences(of: Bundle.main.hostBundleID, with: Bundle.main.agentBundleID) as NSString).appendingPathComponent("socket.ssh") as String
|
let socketPath = (NSHomeDirectory().replacingOccurrences(of: Bundle.hostBundleID, with: Bundle.agentBundleID) as NSString).appendingPathComponent("socket.ssh") as String
|
||||||
|
|
||||||
var shellInstructions: [ShellConfigInstruction] {
|
var shellInstructions: [ShellConfigInstruction] {
|
||||||
[
|
[
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
extension Bundle {
|
extension Bundle {
|
||||||
public var agentBundleID: String {(self.bundleIdentifier?.replacingOccurrences(of: "Host", with: "SecretAgent"))!}
|
public static var agentBundleID: String {
|
||||||
public var hostBundleID: String {(self.bundleIdentifier?.replacingOccurrences(of: "SecretAgent", with: "Host"))!}
|
Bundle.main.bundleIdentifier!.replacingOccurrences(of: "Host", with: "SecretAgent")
|
||||||
|
}
|
||||||
|
|
||||||
|
public static var hostBundleID: String {
|
||||||
|
Bundle.main.bundleIdentifier!.replacingOccurrences(of: "SecretAgent", with: "Host")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
47
Sources/Secretive/Views/ConfigurationView.swift
Normal file
47
Sources/Secretive/Views/ConfigurationView.swift
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct ConfigurationView: View {
|
||||||
|
|
||||||
|
@Binding var visible: Bool
|
||||||
|
|
||||||
|
@State var running = true
|
||||||
|
@State var sshConfig = false
|
||||||
|
|
||||||
|
@Environment(\.agentStatusChecker) var agentStatusChecker
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack(spacing: 0) {
|
||||||
|
NewStepView(title: "setup_agent_title", description: "setup_agent_description") {
|
||||||
|
OnboardingButton("setup_agent_install_button", running) {
|
||||||
|
Task {
|
||||||
|
_ = await LaunchAgentController().forceLaunch()
|
||||||
|
agentStatusChecker.check()
|
||||||
|
running = agentStatusChecker.running
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Divider()
|
||||||
|
Divider()
|
||||||
|
NewStepView(title: "setup_ssh_title", description: "setup_ssh_description") {
|
||||||
|
HStack {
|
||||||
|
OnboardingButton("setup_ssh_added_manually_button", false) {
|
||||||
|
sshConfig = true
|
||||||
|
}
|
||||||
|
OnboardingButton("Add Automatically", false) {
|
||||||
|
// let controller = ShellConfigurationController()
|
||||||
|
// if controller.addToShell(shellInstructions: selectedShellInstruction) {
|
||||||
|
// }
|
||||||
|
sshConfig = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.background(.white.opacity(0.1), in: RoundedRectangle(cornerRadius: 10))
|
||||||
|
.frame(minWidth: 500, idealWidth: 500, minHeight: 500, idealHeight: 500)
|
||||||
|
.padding()
|
||||||
|
.task {
|
||||||
|
running = agentStatusChecker.running
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -6,8 +6,8 @@ struct SecretDetailView<SecretType: Secret>: View {
|
|||||||
let secret: SecretType
|
let secret: SecretType
|
||||||
|
|
||||||
private let keyWriter = OpenSSHPublicKeyWriter()
|
private let keyWriter = OpenSSHPublicKeyWriter()
|
||||||
private let publicKeyFileStoreController = PublicKeyFileStoreController(homeDirectory: NSHomeDirectory().replacingOccurrences(of: Bundle.main.hostBundleID, with: Bundle.main.agentBundleID))
|
private let publicKeyFileStoreController = PublicKeyFileStoreController(homeDirectory: URL.agentHomePath)
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
ScrollView {
|
ScrollView {
|
||||||
Form {
|
Form {
|
||||||
@ -37,6 +37,14 @@ struct SecretDetailView<SecretType: Secret>: View {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension URL {
|
||||||
|
|
||||||
|
static var agentHomePath: String {
|
||||||
|
URL.homeDirectory.path().replacingOccurrences(of: Bundle.hostBundleID, with: Bundle.agentBundleID)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
|
||||||
struct SecretDetailView_Previews: PreviewProvider {
|
struct SecretDetailView_Previews: PreviewProvider {
|
||||||
|
@ -2,6 +2,124 @@ import SwiftUI
|
|||||||
|
|
||||||
struct SetupView: View {
|
struct SetupView: View {
|
||||||
|
|
||||||
|
@Binding var visible: Bool
|
||||||
|
@Binding var setupComplete: Bool
|
||||||
|
|
||||||
|
@State var installed = false
|
||||||
|
@State var updates = false
|
||||||
|
@State var sshConfig = false
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack(spacing: 0) {
|
||||||
|
NewStepView(title: "setup_agent_title", description: "setup_agent_description") {
|
||||||
|
OnboardingButton("setup_agent_install_button", installed) {
|
||||||
|
Task {
|
||||||
|
await LaunchAgentController().install()
|
||||||
|
installed = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Divider()
|
||||||
|
NewStepView(title: "setup_updates_title", description: "setup_updates_description") {
|
||||||
|
OnboardingButton("setup_updates_ok", false) {
|
||||||
|
Task {
|
||||||
|
updates = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Divider()
|
||||||
|
NewStepView(title: "setup_ssh_title", description: "setup_ssh_description") {
|
||||||
|
HStack {
|
||||||
|
OnboardingButton("setup_ssh_added_manually_button", false) {
|
||||||
|
sshConfig = true
|
||||||
|
}
|
||||||
|
OnboardingButton("Add Automatically", false) {
|
||||||
|
// let controller = ShellConfigurationController()
|
||||||
|
// if controller.addToShell(shellInstructions: selectedShellInstruction) {
|
||||||
|
// }
|
||||||
|
sshConfig = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.background(.white.opacity(0.1), in: RoundedRectangle(cornerRadius: 10))
|
||||||
|
.frame(minWidth: 500, idealWidth: 500, minHeight: 500, idealHeight: 500)
|
||||||
|
.padding()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
struct OnboardingButton: View {
|
||||||
|
|
||||||
|
let label: LocalizedStringResource
|
||||||
|
let complete: Bool
|
||||||
|
let action: () -> Void
|
||||||
|
|
||||||
|
init(_ label: LocalizedStringResource, _ complete: Bool, action: @escaping () -> Void) {
|
||||||
|
self.label = label
|
||||||
|
self.complete = complete
|
||||||
|
self.action = action
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
Button(action: action) {
|
||||||
|
HStack(spacing: 6) {
|
||||||
|
Text(label)
|
||||||
|
if complete {
|
||||||
|
Image(systemName: "checkmark.circle.fill")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.padding(.vertical, 2)
|
||||||
|
}
|
||||||
|
.disabled(complete)
|
||||||
|
.styled
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension View {
|
||||||
|
|
||||||
|
@ViewBuilder
|
||||||
|
var styled: some View {
|
||||||
|
if #available(macOS 26.0, *) {
|
||||||
|
buttonStyle(.glassProminent)
|
||||||
|
} else {
|
||||||
|
buttonStyle(.borderedProminent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
struct NewStepView<Content: View>: View {
|
||||||
|
|
||||||
|
let title: LocalizedStringResource
|
||||||
|
let description: LocalizedStringResource
|
||||||
|
let actions: Content
|
||||||
|
|
||||||
|
init(title: LocalizedStringResource, description: LocalizedStringResource, actions: () -> Content) {
|
||||||
|
self.title = title
|
||||||
|
self.description = description
|
||||||
|
self.actions = actions()
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
HStack {
|
||||||
|
VStack(alignment: .leading, spacing: 6) {
|
||||||
|
Text(title)
|
||||||
|
.bold()
|
||||||
|
Text(description)
|
||||||
|
}
|
||||||
|
Spacer(minLength: 20)
|
||||||
|
actions
|
||||||
|
}
|
||||||
|
.padding(20)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
struct OldSetupView: View {
|
||||||
|
|
||||||
@State var stepIndex = 0
|
@State var stepIndex = 0
|
||||||
@Binding var visible: Bool
|
@Binding var visible: Bool
|
||||||
@Binding var setupComplete: Bool
|
@Binding var setupComplete: Bool
|
||||||
@ -61,7 +179,7 @@ struct StepView: View {
|
|||||||
Circle()
|
Circle()
|
||||||
.foregroundColor(.green)
|
.foregroundColor(.green)
|
||||||
.frame(width: Constants.circleWidth, height: Constants.circleWidth)
|
.frame(width: Constants.circleWidth, height: Constants.circleWidth)
|
||||||
Text(.setupStepCompleteSymbol)
|
Text("setup_step_complete_symbol")
|
||||||
.foregroundColor(.white)
|
.foregroundColor(.white)
|
||||||
.bold()
|
.bold()
|
||||||
} else {
|
} else {
|
||||||
@ -101,14 +219,14 @@ extension StepView {
|
|||||||
|
|
||||||
struct SetupStepView<Content> : View where Content : View {
|
struct SetupStepView<Content> : View where Content : View {
|
||||||
|
|
||||||
let title: LocalizedStringResource
|
let title: LocalizedStringKey
|
||||||
let image: Image
|
let image: Image
|
||||||
let bodyText: LocalizedStringResource
|
let bodyText: LocalizedStringKey
|
||||||
let buttonTitle: LocalizedStringResource
|
let buttonTitle: LocalizedStringKey
|
||||||
let buttonAction: () -> Void
|
let buttonAction: () -> Void
|
||||||
let content: Content
|
let content: Content
|
||||||
|
|
||||||
init(title: LocalizedStringResource, image: Image, bodyText: LocalizedStringResource, buttonTitle: LocalizedStringResource, buttonAction: @escaping () -> Void = {}, @ViewBuilder content: () -> Content) {
|
init(title: LocalizedStringKey, image: Image, bodyText: LocalizedStringKey, buttonTitle: LocalizedStringKey, buttonAction: @escaping () -> Void = {}, @ViewBuilder content: () -> Content) {
|
||||||
self.title = title
|
self.title = title
|
||||||
self.image = image
|
self.image = image
|
||||||
self.bodyText = bodyText
|
self.bodyText = bodyText
|
||||||
@ -145,12 +263,12 @@ struct SecretAgentSetupView: View {
|
|||||||
let buttonAction: () -> Void
|
let buttonAction: () -> Void
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
SetupStepView(title: .setupAgentTitle,
|
SetupStepView(title: "setup_agent_title",
|
||||||
image: Image(nsImage: NSApplication.shared.applicationIconImage),
|
image: Image(nsImage: NSApplication.shared.applicationIconImage),
|
||||||
bodyText: .setupAgentDescription,
|
bodyText: "setup_agent_description",
|
||||||
buttonTitle: .setupAgentInstallButton,
|
buttonTitle: "setup_agent_install_button",
|
||||||
buttonAction: install) {
|
buttonAction: install) {
|
||||||
Text(.setupAgentActivityMonitorDescription)
|
Text("setup_agent_activity_monitor_description")
|
||||||
.multilineTextAlignment(.center)
|
.multilineTextAlignment(.center)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -172,12 +290,12 @@ struct SSHAgentSetupView: View {
|
|||||||
@State private var selectedShellInstruction: ShellConfigInstruction = controller.shellInstructions.first!
|
@State private var selectedShellInstruction: ShellConfigInstruction = controller.shellInstructions.first!
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
SetupStepView(title: .setupSshTitle,
|
SetupStepView(title: "setup_ssh_title",
|
||||||
image: Image(systemName: "terminal"),
|
image: Image(systemName: "terminal"),
|
||||||
bodyText: .setupSshDescription,
|
bodyText: "setup_ssh_description",
|
||||||
buttonTitle: .setupSshAddedManuallyButton,
|
buttonTitle: "setup_ssh_added_manually_button",
|
||||||
buttonAction: buttonAction) {
|
buttonAction: buttonAction) {
|
||||||
Link(.setupThirdPartyFaqLink, destination: URL(string: "https://github.com/maxgoedjen/secretive/blob/main/APP_CONFIG.md")!)
|
Link("setup_third_party_faq_link", destination: URL(string: "https://github.com/maxgoedjen/secretive/blob/main/APP_CONFIG.md")!)
|
||||||
Picker(selection: $selectedShellInstruction, label: EmptyView()) {
|
Picker(selection: $selectedShellInstruction, label: EmptyView()) {
|
||||||
ForEach(SSHAgentSetupView.controller.shellInstructions) { instruction in
|
ForEach(SSHAgentSetupView.controller.shellInstructions) { instruction in
|
||||||
Text(instruction.shell)
|
Text(instruction.shell)
|
||||||
@ -185,8 +303,8 @@ struct SSHAgentSetupView: View {
|
|||||||
.padding()
|
.padding()
|
||||||
}
|
}
|
||||||
}.pickerStyle(SegmentedPickerStyle())
|
}.pickerStyle(SegmentedPickerStyle())
|
||||||
CopyableView(title: .setupSshAddToConfigButton(configPath: selectedShellInstruction.shellConfigPath), image: Image(systemName: "greaterthan.square"), text: selectedShellInstruction.text)
|
CopyableView(title: "setup_ssh_add_to_config_button_\(selectedShellInstruction.shellConfigPath)", image: Image(systemName: "greaterthan.square"), text: selectedShellInstruction.text)
|
||||||
Button(.setupSshAddForMeButton) {
|
Button("setup_ssh_add_for_me_button") {
|
||||||
let controller = ShellConfigurationController()
|
let controller = ShellConfigurationController()
|
||||||
if controller.addToShell(shellInstructions: selectedShellInstruction) {
|
if controller.addToShell(shellInstructions: selectedShellInstruction) {
|
||||||
buttonAction()
|
buttonAction()
|
||||||
@ -216,12 +334,12 @@ struct UpdaterExplainerView: View {
|
|||||||
let buttonAction: () -> Void
|
let buttonAction: () -> Void
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
SetupStepView(title: .setupUpdatesTitle,
|
SetupStepView(title: "setup_updates_title",
|
||||||
image: Image(systemName: "dot.radiowaves.left.and.right"),
|
image: Image(systemName: "dot.radiowaves.left.and.right"),
|
||||||
bodyText: .setupUpdatesDescription,
|
bodyText: "setup_updates_description",
|
||||||
buttonTitle: .setupUpdatesOk,
|
buttonTitle: "setup_updates_ok",
|
||||||
buttonAction: buttonAction) {
|
buttonAction: buttonAction) {
|
||||||
Link(.setupUpdatesReadmore, destination: SetupView.Constants.updaterFAQURL)
|
Link("setup_updates_readmore", destination: SetupView.Constants.updaterFAQURL)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user