87 lines
3.5 KiB
Swift
87 lines
3.5 KiB
Swift
import SwiftUI
|
|
|
|
struct SessionView: View {
|
|
let profile: ConnectionProfile
|
|
@Binding var statusMessage: String
|
|
@EnvironmentObject var store: ProfileStore
|
|
@ObservedObject var term: PTYSession
|
|
var onClose: () -> Void
|
|
|
|
var isSSH: Bool { profile.proto == .ssh || profile.proto == .sftp }
|
|
var canConnect: Bool { !profile.host.isEmpty && !profile.username.isEmpty }
|
|
|
|
var body: some View {
|
|
VStack(alignment: .leading, spacing: 8) {
|
|
HStack {
|
|
Image(systemName: profile.proto.systemImage).font(.title2)
|
|
VStack(alignment: .leading) {
|
|
Text(profile.name).font(.headline)
|
|
Text("\(profile.proto.rawValue) · \(profile.username)@\(profile.host):\(profile.port)")
|
|
.font(.subheadline).foregroundStyle(.secondary)
|
|
}
|
|
Spacer()
|
|
if isSSH {
|
|
Button("In Terminal.app öffnen") {
|
|
SSHService.openInTerminal(profile: profile, key: store.key(for: profile))
|
|
}
|
|
Button("Befehl kopieren") {
|
|
SSHService.copyCommandToClipboard(profile: profile, key: store.key(for: profile))
|
|
statusMessage = "SSH-Befehl kopiert."
|
|
}
|
|
} else if profile.proto == .rdp {
|
|
Button("RDP erneut verbinden") { RDPService.connect(profile: profile) }
|
|
}
|
|
Button("Tab schließen") { onClose() }
|
|
}
|
|
.padding(.horizontal)
|
|
|
|
if isSSH {
|
|
// In-App-Terminal (Dracula) — kein externes Fenster mehr nötig
|
|
EmbeddedTerminalView(term: term, canConnect: canConnect)
|
|
.frame(minHeight: 380)
|
|
.padding(.horizontal)
|
|
}
|
|
|
|
GroupBox("Verbindungsdetails") {
|
|
let key = store.key(for: profile)
|
|
let cmd = isSSH
|
|
? SSHService.sshCommandString(for: profile, key: key)
|
|
: "\(profile.proto.rawValue) \(profile.host):\(profile.port)"
|
|
Text(cmd)
|
|
.font(.system(.body, design: .monospaced))
|
|
.textSelection(.enabled)
|
|
.frame(maxWidth: .infinity, alignment: .leading)
|
|
.padding(8)
|
|
}
|
|
.padding(.horizontal)
|
|
|
|
GroupBox("Hinweis") {
|
|
Text(hintText)
|
|
.font(.callout).foregroundStyle(.secondary)
|
|
.frame(maxWidth: .infinity, alignment: .leading)
|
|
.padding(8)
|
|
}
|
|
.padding(.horizontal)
|
|
|
|
Spacer()
|
|
}
|
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
|
.padding(.top, 8)
|
|
}
|
|
|
|
var hintText: String {
|
|
switch profile.proto {
|
|
case .ssh:
|
|
return "In-App-Terminal (Dracula-Theme) — läuft direkt in diesem Tab über ein PTY. Alternativ: In Terminal.app öffnen."
|
|
case .sftp:
|
|
return "SFTP-Sitzung läuft im Terminal oben. Alternativ extern nutzen: sftp -P \(profile.port) \(profile.username)@\(profile.host)."
|
|
case .rdp:
|
|
return RDPService.freeRDPPath != nil
|
|
? "Verbunden über xfreerdp (\(RDPService.freeRDPPath!))."
|
|
: "Kein xfreerdp gefunden (brew install freerdp). Fallback: Microsoft Remote Desktop wird geöffnet."
|
|
case .vnc:
|
|
return "VNC wird über die System-Freigabe (open vnc://) geöffnet."
|
|
}
|
|
}
|
|
}
|