mirror of
https://github.com/neon443/ShhShell.git
synced 2026-03-11 13:26:16 +00:00
added hostpreview to preview hosts
added a thingy in hostsmanager to load test data if inited with previews = true added a context menu to hosts with a nice preview
This commit is contained in:
@@ -22,6 +22,7 @@
|
|||||||
A923172A2E07113100ECE1E6 /* TerminalController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A92317292E07113100ECE1E6 /* TerminalController.swift */; };
|
A923172A2E07113100ECE1E6 /* TerminalController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A92317292E07113100ECE1E6 /* TerminalController.swift */; };
|
||||||
A923172D2E07138000ECE1E6 /* SSHTerminalDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A923172C2E07138000ECE1E6 /* SSHTerminalDelegate.swift */; };
|
A923172D2E07138000ECE1E6 /* SSHTerminalDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A923172C2E07138000ECE1E6 /* SSHTerminalDelegate.swift */; };
|
||||||
A923172F2E08851200ECE1E6 /* ShellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A923172E2E08851200ECE1E6 /* ShellView.swift */; };
|
A923172F2E08851200ECE1E6 /* ShellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A923172E2E08851200ECE1E6 /* ShellView.swift */; };
|
||||||
|
A9231A572E52041500974753 /* HostPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9231A562E52041500974753 /* HostPreview.swift */; };
|
||||||
A92538C82DEE0742007E0A18 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A92538C52DEE0742007E0A18 /* ContentView.swift */; };
|
A92538C82DEE0742007E0A18 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A92538C52DEE0742007E0A18 /* ContentView.swift */; };
|
||||||
A92538C92DEE0742007E0A18 /* ShhShellApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = A92538C62DEE0742007E0A18 /* ShhShellApp.swift */; };
|
A92538C92DEE0742007E0A18 /* ShhShellApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = A92538C62DEE0742007E0A18 /* ShhShellApp.swift */; };
|
||||||
A92538CA2DEE0742007E0A18 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A92538C42DEE0742007E0A18 /* Assets.xcassets */; };
|
A92538CA2DEE0742007E0A18 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A92538C42DEE0742007E0A18 /* Assets.xcassets */; };
|
||||||
@@ -151,6 +152,7 @@
|
|||||||
A92317292E07113100ECE1E6 /* TerminalController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TerminalController.swift; sourceTree = "<group>"; };
|
A92317292E07113100ECE1E6 /* TerminalController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TerminalController.swift; sourceTree = "<group>"; };
|
||||||
A923172C2E07138000ECE1E6 /* SSHTerminalDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SSHTerminalDelegate.swift; sourceTree = "<group>"; };
|
A923172C2E07138000ECE1E6 /* SSHTerminalDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SSHTerminalDelegate.swift; sourceTree = "<group>"; };
|
||||||
A923172E2E08851200ECE1E6 /* ShellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ShellView.swift; path = ShhShell/Views/Terminal/ShellView.swift; sourceTree = SOURCE_ROOT; };
|
A923172E2E08851200ECE1E6 /* ShellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ShellView.swift; path = ShhShell/Views/Terminal/ShellView.swift; sourceTree = SOURCE_ROOT; };
|
||||||
|
A9231A562E52041500974753 /* HostPreview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HostPreview.swift; sourceTree = "<group>"; };
|
||||||
A925389A2DEE06DC007E0A18 /* ShhShell.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ShhShell.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
A925389A2DEE06DC007E0A18 /* ShhShell.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ShhShell.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
A92538A72DEE06DE007E0A18 /* ShhShellTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ShhShellTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
A92538A72DEE06DE007E0A18 /* ShhShellTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ShhShellTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
A92538B12DEE06DE007E0A18 /* ShhShellUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ShhShellUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
A92538B12DEE06DE007E0A18 /* ShhShellUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ShhShellUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
@@ -513,7 +515,6 @@
|
|||||||
A96C6B012E0C49E800F377FE /* CenteredLabel.swift */,
|
A96C6B012E0C49E800F377FE /* CenteredLabel.swift */,
|
||||||
A93143C52DF61FE300FCD5DB /* ViewModifiers.swift */,
|
A93143C52DF61FE300FCD5DB /* ViewModifiers.swift */,
|
||||||
A96C90A02E12B87900724253 /* TextBox.swift */,
|
A96C90A02E12B87900724253 /* TextBox.swift */,
|
||||||
A9DA97722E0D40C100142DDC /* HostSymbolPreview.swift */,
|
|
||||||
A9835C3B2E17CCA500969508 /* TrafficLights.swift */,
|
A9835C3B2E17CCA500969508 /* TrafficLights.swift */,
|
||||||
);
|
);
|
||||||
path = Misc;
|
path = Misc;
|
||||||
@@ -526,6 +527,8 @@
|
|||||||
A985545C2E055D4D009051BD /* ConnectionView.swift */,
|
A985545C2E055D4D009051BD /* ConnectionView.swift */,
|
||||||
A98CAB432E4229F7005E4C42 /* HostSymbolPicker.swift */,
|
A98CAB432E4229F7005E4C42 /* HostSymbolPicker.swift */,
|
||||||
A9CC786A2E4E681400FAEE58 /* RecentsView.swift */,
|
A9CC786A2E4E681400FAEE58 /* RecentsView.swift */,
|
||||||
|
A9231A562E52041500974753 /* HostPreview.swift */,
|
||||||
|
A9DA97722E0D40C100142DDC /* HostSymbolPreview.swift */,
|
||||||
);
|
);
|
||||||
path = Hosts;
|
path = Hosts;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -805,6 +808,7 @@
|
|||||||
A9C060ED2E3FBCD000CA9374 /* SnippetPicker.swift in Sources */,
|
A9C060ED2E3FBCD000CA9374 /* SnippetPicker.swift in Sources */,
|
||||||
A96BE6A62E113DB000C0FEE9 /* ColorCodable.swift in Sources */,
|
A96BE6A62E113DB000C0FEE9 /* ColorCodable.swift in Sources */,
|
||||||
A92538C82DEE0742007E0A18 /* ContentView.swift in Sources */,
|
A92538C82DEE0742007E0A18 /* ContentView.swift in Sources */,
|
||||||
|
A9231A572E52041500974753 /* HostPreview.swift in Sources */,
|
||||||
A96BE6A42E113D9400C0FEE9 /* ThemeCodable.swift in Sources */,
|
A96BE6A42E113D9400C0FEE9 /* ThemeCodable.swift in Sources */,
|
||||||
A9FD375F2E14648E005319A8 /* KeyImporterView.swift in Sources */,
|
A9FD375F2E14648E005319A8 /* KeyImporterView.swift in Sources */,
|
||||||
A93143C02DF61B3200FCD5DB /* Host.swift in Sources */,
|
A93143C02DF61B3200FCD5DB /* Host.swift in Sources */,
|
||||||
|
|||||||
@@ -30,12 +30,18 @@ class HostsManager: ObservableObject, @unchecked Sendable {
|
|||||||
selectedTheme.ansi[selectedAnsi].suiColor
|
selectedTheme.ansi[selectedAnsi].suiColor
|
||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
init(previews: Bool = false) {
|
||||||
loadHosts()
|
loadHosts()
|
||||||
loadThemes()
|
loadThemes()
|
||||||
loadFonts()
|
loadFonts()
|
||||||
loadSnippets()
|
loadSnippets()
|
||||||
loadHistory()
|
loadHistory()
|
||||||
|
if previews {
|
||||||
|
self.hosts = [Host.debug, Host.blank]
|
||||||
|
self.themes = [Theme.defaultTheme]
|
||||||
|
self.snippets = [Snippet(name: "kys", content: "ls\npwd\n")]
|
||||||
|
self.history = [History(host: Host.debug, count: 3)]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadHistory() {
|
func loadHistory() {
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ Hostkey fingerprint is \(handler.getHostkey() ?? "nil")
|
|||||||
Button() {
|
Button() {
|
||||||
withAnimation { showIconPicker.toggle() }
|
withAnimation { showIconPicker.toggle() }
|
||||||
} label: {
|
} label: {
|
||||||
HostSymbolPreview(symbol: handler.host.symbol, label: handler.host.label, small: true)
|
HostSymbolPreview(symbol: handler.host.symbol, label: handler.host.label, horizontal: true)
|
||||||
.id(handler.host)
|
.id(handler.host)
|
||||||
}
|
}
|
||||||
.popover(isPresented: $showIconPicker) {
|
.popover(isPresented: $showIconPicker) {
|
||||||
|
|||||||
66
ShhShell/Views/Hosts/HostPreview.swift
Normal file
66
ShhShell/Views/Hosts/HostPreview.swift
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
//
|
||||||
|
// HostPreview.swift
|
||||||
|
// ShhShell
|
||||||
|
//
|
||||||
|
// Created by neon443 on 17/08/2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct HostPreview: View {
|
||||||
|
@ObservedObject var hostsManager: HostsManager
|
||||||
|
@ObservedObject var keyManager: KeyManager
|
||||||
|
@State var host: Host
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
List {
|
||||||
|
HStack {
|
||||||
|
Image(systemName: "info.circle")
|
||||||
|
Text("Info for \"\(host.description)\"")
|
||||||
|
.monospaced()
|
||||||
|
Spacer()
|
||||||
|
HostSymbolPreview(symbol: host.symbol, label: host.label)
|
||||||
|
.frame(maxHeight: 30)
|
||||||
|
}
|
||||||
|
|
||||||
|
Section {
|
||||||
|
TextBox(label: "Name", text: $host.name, prompt: "")
|
||||||
|
|
||||||
|
TextBox(label: "Address", text: $host.address, prompt: "")
|
||||||
|
|
||||||
|
TextBox(label: "Port", text: Binding(
|
||||||
|
get: { String(host.port) },
|
||||||
|
set: {
|
||||||
|
if let input = Int($0) {
|
||||||
|
host.port = input
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
prompt: "",
|
||||||
|
keyboardType: .numberPad
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Section {
|
||||||
|
TextBox(label: "Username", text: $host.username, prompt: "")
|
||||||
|
|
||||||
|
TextBox(label: "Password", text: $host.password, prompt: "", secure: true)
|
||||||
|
|
||||||
|
let keypair = keyManager.keypairs.first(where: { $0.id == host.privateKeyID })
|
||||||
|
TextBox(label: "Private key", text: .constant(keypair?.name ?? "None"), prompt: "")
|
||||||
|
}
|
||||||
|
|
||||||
|
Section() {
|
||||||
|
let startupSnip = hostsManager.snippets.first(where: { $0.id == host.startupSnippetID })
|
||||||
|
TextBox(label: "Startup Snippet", text: .constant(startupSnip?.name ?? "None"), prompt: "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#Preview {
|
||||||
|
HostPreview(
|
||||||
|
hostsManager: HostsManager(),
|
||||||
|
keyManager: KeyManager(),
|
||||||
|
host: Host.debug
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -10,15 +10,15 @@ import SwiftUI
|
|||||||
struct HostSymbolPreview: View {
|
struct HostSymbolPreview: View {
|
||||||
@State var symbol: HostSymbol
|
@State var symbol: HostSymbol
|
||||||
@State var label: String
|
@State var label: String
|
||||||
@State var small: Bool = false
|
@State var horizontal: Bool = false
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
if small {
|
if horizontal {
|
||||||
HStack(alignment: .center, spacing: 5) {
|
HStack(alignment: .center, spacing: 5) {
|
||||||
Text(label)
|
|
||||||
symbol.image
|
symbol.image
|
||||||
.resizable().scaledToFit()
|
.resizable().scaledToFit()
|
||||||
.symbolRenderingMode(.monochrome)
|
.symbolRenderingMode(.monochrome)
|
||||||
|
Text(label)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ZStack(alignment: .center) {
|
ZStack(alignment: .center) {
|
||||||
@@ -33,6 +33,14 @@ struct HostsView: View {
|
|||||||
}
|
}
|
||||||
.id(host)
|
.id(host)
|
||||||
.animation(.default, value: host)
|
.animation(.default, value: host)
|
||||||
|
.contextMenu {
|
||||||
|
Button() {
|
||||||
|
hostsManager.removeHost(host)
|
||||||
|
} label: { Label("Delete", systemImage: "trash") }
|
||||||
|
.tint(.red)
|
||||||
|
} preview: {
|
||||||
|
HostPreview(hostsManager: hostsManager, keyManager: keyManager, host: host)
|
||||||
|
}
|
||||||
.swipeActions(edge: .trailing) {
|
.swipeActions(edge: .trailing) {
|
||||||
Button(role: .destructive) {
|
Button(role: .destructive) {
|
||||||
hostsManager.removeHost(host)
|
hostsManager.removeHost(host)
|
||||||
@@ -61,7 +69,7 @@ struct HostsView: View {
|
|||||||
#Preview {
|
#Preview {
|
||||||
HostsView(
|
HostsView(
|
||||||
handler: SSHHandler(host: Host.debug, keyManager: nil),
|
handler: SSHHandler(host: Host.debug, keyManager: nil),
|
||||||
hostsManager: HostsManager(),
|
hostsManager: HostsManager(previews: true),
|
||||||
keyManager: KeyManager()
|
keyManager: KeyManager()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user