mirror of
https://github.com/samsonjs/vibetunnel.git
synced 2026-04-27 15:17:38 +00:00
226 lines
11 KiB
Swift
226 lines
11 KiB
Swift
import SwiftUI
|
|
|
|
/// Advanced settings tab for power user options
|
|
struct AdvancedSettingsView: View {
|
|
@AppStorage("debugMode")
|
|
private var debugMode = false
|
|
@AppStorage("cleanupOnStartup")
|
|
private var cleanupOnStartup = true
|
|
@State private var cliInstaller = CLIInstaller()
|
|
|
|
var body: some View {
|
|
NavigationStack {
|
|
Form {
|
|
// Integration section
|
|
Section {
|
|
VStack(alignment: .leading, spacing: 8) {
|
|
HStack {
|
|
Text("Install CLI Tool")
|
|
Spacer()
|
|
if cliInstaller.isInstalled {
|
|
HStack {
|
|
Image(systemName: "checkmark.circle.fill")
|
|
.foregroundColor(.green)
|
|
Text("CLI tool is installed")
|
|
.foregroundColor(.secondary)
|
|
}
|
|
} else {
|
|
Button("Install 'vt' Command") {
|
|
Task {
|
|
await cliInstaller.install()
|
|
}
|
|
}
|
|
.buttonStyle(.bordered)
|
|
.disabled(cliInstaller.isInstalling)
|
|
}
|
|
}
|
|
|
|
if cliInstaller.isInstalling {
|
|
ProgressView()
|
|
.scaleEffect(0.8)
|
|
}
|
|
|
|
if let error = cliInstaller.lastError {
|
|
Text(error)
|
|
.font(.caption)
|
|
.foregroundColor(.red)
|
|
} else if cliInstaller.isInstalled {
|
|
Text("The 'vt' command line tool is installed at /usr/local/bin/vt")
|
|
.font(.caption)
|
|
.foregroundStyle(.secondary)
|
|
} else {
|
|
Text("Install the 'vt' command line tool to /usr/local/bin for terminal access.")
|
|
.font(.caption)
|
|
.foregroundStyle(.secondary)
|
|
}
|
|
}
|
|
} header: {
|
|
Text("Integration")
|
|
.font(.headline)
|
|
}
|
|
|
|
// Terminal preference section
|
|
TerminalPreferenceSection()
|
|
|
|
// Advanced section
|
|
Section {
|
|
VStack(alignment: .leading, spacing: 4) {
|
|
Toggle("Clean up old sessions on startup", isOn: $cleanupOnStartup)
|
|
Text("Automatically remove terminated sessions when the app starts.")
|
|
.font(.caption)
|
|
.foregroundStyle(.secondary)
|
|
}
|
|
} header: {
|
|
Text("Advanced")
|
|
.font(.headline)
|
|
}
|
|
|
|
// Debug section
|
|
Section {
|
|
VStack(alignment: .leading, spacing: 4) {
|
|
Toggle("Debug mode", isOn: $debugMode)
|
|
Text("Enable additional logging and debugging features.")
|
|
.font(.caption)
|
|
.foregroundStyle(.secondary)
|
|
}
|
|
} header: {
|
|
Text("Debug")
|
|
.font(.headline)
|
|
}
|
|
}
|
|
.formStyle(.grouped)
|
|
.scrollContentBackground(.hidden)
|
|
.navigationTitle("Advanced Settings")
|
|
}
|
|
.onAppear {
|
|
cliInstaller.checkInstallationStatus()
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - Terminal Preference Section
|
|
|
|
private struct TerminalPreferenceSection: View {
|
|
@AppStorage("preferredTerminal") private var preferredTerminal = Terminal.terminal.rawValue
|
|
@State private var terminalLauncher = TerminalLauncher.shared
|
|
@State private var showingError = false
|
|
@State private var errorMessage = ""
|
|
@State private var errorTitle = "Terminal Launch Failed"
|
|
|
|
var body: some View {
|
|
Section {
|
|
VStack(alignment: .leading, spacing: 8) {
|
|
HStack {
|
|
Text("Preferred Terminal")
|
|
Spacer()
|
|
Picker("", selection: $preferredTerminal) {
|
|
ForEach(Terminal.installed, id: \.rawValue) { terminal in
|
|
HStack {
|
|
if let icon = terminal.appIcon {
|
|
Image(nsImage: icon)
|
|
.resizable()
|
|
.frame(width: 16, height: 16)
|
|
}
|
|
Text(terminal.displayName)
|
|
}
|
|
.tag(terminal.rawValue)
|
|
}
|
|
}
|
|
.pickerStyle(.menu)
|
|
.labelsHidden()
|
|
}
|
|
Text("Select which terminal application to use when creating new sessions")
|
|
.font(.caption)
|
|
.foregroundStyle(.secondary)
|
|
|
|
// Test button
|
|
HStack {
|
|
Text("Test Terminal")
|
|
Spacer()
|
|
Button("Test with 'echo'") {
|
|
Task {
|
|
do {
|
|
try terminalLauncher.launchCommand("echo 'VibeTunnel Terminal Test: Success!'")
|
|
} catch {
|
|
// Log the error
|
|
print("Failed to launch terminal test: \(error)")
|
|
|
|
// Set up alert content based on error type
|
|
if let terminalError = error as? TerminalLauncherError {
|
|
switch terminalError {
|
|
case .appleScriptPermissionDenied:
|
|
errorTitle = "Permission Denied"
|
|
errorMessage = "VibeTunnel needs permission to control terminal applications.\n\nPlease grant Automation permission in System Settings > Privacy & Security > Automation."
|
|
case .accessibilityPermissionDenied:
|
|
errorTitle = "Accessibility Permission Required"
|
|
errorMessage = "VibeTunnel needs Accessibility permission to send keystrokes to \(Terminal(rawValue: preferredTerminal)?.displayName ?? "terminal").\n\nPlease grant permission in System Settings > Privacy & Security > Accessibility."
|
|
case .terminalNotFound:
|
|
errorTitle = "Terminal Not Found"
|
|
errorMessage = "The selected terminal application could not be found. Please select a different terminal."
|
|
case .appleScriptExecutionFailed(let details, let errorCode):
|
|
if let code = errorCode {
|
|
switch code {
|
|
case -1_743:
|
|
errorTitle = "Permission Denied"
|
|
errorMessage = "VibeTunnel needs permission to control terminal applications.\n\nPlease grant Automation permission in System Settings > Privacy & Security > Automation."
|
|
case -1_728:
|
|
errorTitle = "Terminal Not Available"
|
|
errorMessage = "The terminal application is not running or cannot be controlled.\n\nDetails: \(details)"
|
|
case -1_708:
|
|
errorTitle = "Terminal Communication Error"
|
|
errorMessage = "The terminal did not respond to the command.\n\nDetails: \(details)"
|
|
case -25211:
|
|
errorTitle = "Accessibility Permission Required"
|
|
errorMessage = "System Events requires Accessibility permission to send keystrokes.\n\nPlease grant permission in System Settings > Privacy & Security > Accessibility."
|
|
default:
|
|
errorTitle = "Terminal Launch Failed"
|
|
errorMessage = "AppleScript error \(code): \(details)"
|
|
}
|
|
} else {
|
|
errorTitle = "Terminal Launch Failed"
|
|
errorMessage = "Failed to launch terminal: \(details)"
|
|
}
|
|
case .processLaunchFailed(let details):
|
|
errorTitle = "Process Launch Failed"
|
|
errorMessage = "Failed to start terminal process: \(details)"
|
|
}
|
|
} else {
|
|
errorTitle = "Terminal Launch Failed"
|
|
errorMessage = error.localizedDescription
|
|
}
|
|
|
|
showingError = true
|
|
}
|
|
}
|
|
}
|
|
.buttonStyle(.bordered)
|
|
}
|
|
Text("Opens a new terminal window with a test command")
|
|
.font(.caption)
|
|
.foregroundStyle(.secondary)
|
|
}
|
|
} header: {
|
|
Text("Terminal")
|
|
.font(.headline)
|
|
} footer: {
|
|
Text(
|
|
"VibeTunnel will use this terminal when launching new terminal sessions."
|
|
)
|
|
.font(.caption)
|
|
.frame(maxWidth: .infinity)
|
|
.multilineTextAlignment(.center)
|
|
}
|
|
.alert(errorTitle, isPresented: $showingError) {
|
|
Button("OK") { }
|
|
if errorTitle == "Permission Denied" {
|
|
Button("Open System Settings") {
|
|
if let url = URL(string: "x-apple.systempreferences:com.apple.preference.security?Privacy_Automation") {
|
|
NSWorkspace.shared.open(url)
|
|
}
|
|
}
|
|
}
|
|
} message: {
|
|
Text(errorMessage)
|
|
}
|
|
}
|
|
}
|