fix the key, hostskeys, snippet views being black sometimes

This commit is contained in:
neon443
2025-11-07 10:23:14 +00:00
parent 750bf6ee62
commit db899fbb0f
3 changed files with 145 additions and 151 deletions

View File

@@ -14,58 +14,56 @@ struct HostkeysView: View {
ZStack { ZStack {
hostsManager.selectedTheme.background.suiColor.opacity(0.7) hostsManager.selectedTheme.background.suiColor.opacity(0.7)
.ignoresSafeArea(.all) .ignoresSafeArea(.all)
NavigationStack { List {
List { if hostsManager.hosts.isEmpty {
if hostsManager.hosts.isEmpty { VStack(alignment: .leading) {
Text("Looking empty 'round here...")
.font(.title3)
.bold()
.padding(.bottom)
VStack(alignment: .leading) { VStack(alignment: .leading) {
Text("Looking empty 'round here...") Text("Connect to some hosts to collect more hostkeys!")
.font(.title3)
.bold()
.padding(.bottom) .padding(.bottom)
VStack(alignment: .leading) { Text("ShhShell remembers hostkey fingerprints for you, and will alert you if they change.")
Text("Connect to some hosts to collect more hostkeys!") .font(.subheadline)
.padding(.bottom) Text("This could be due a man in the middle attack, where a bad actor tries to impersonate your server.")
Text("ShhShell remembers hostkey fingerprints for you, and will alert you if they change.") .font(.subheadline)
.font(.subheadline) }
Text("This could be due a man in the middle attack, where a bad actor tries to impersonate your server.") }
.font(.subheadline) }
}
} ForEach($hostsManager.hosts) { $host in
} VStack(alignment: .leading) {
if !host.name.isEmpty {
ForEach($hostsManager.hosts) { $host in Text("name")
VStack(alignment: .leading) { .foregroundStyle(.gray)
if !host.name.isEmpty { .font(.caption)
Text("name") Text(host.name)
.foregroundStyle(.gray) .bold()
.font(.caption) }
Text(host.name) Text("address")
.bold() .foregroundStyle(.gray)
} .font(.caption)
Text("address") Text(host.address)
.foregroundStyle(.gray) .bold()
.font(.caption) Text(host.key ?? "nil")
Text(host.address) }
.bold() .swipeActions(edge: .trailing, allowsFullSwipe: true) {
Text(host.key ?? "nil") Button(/*role: .destructive*/) {
} host.key = nil
.swipeActions(edge: .trailing, allowsFullSwipe: true) { hostsManager.updateHost(host)
Button(/*role: .destructive*/) { } label: {
host.key = nil Label("Forget", systemImage: "trash")
hostsManager.updateHost(host)
} label: {
Label("Forget", systemImage: "trash")
}
} }
} }
} }
.scrollContentBackground(.hidden)
.navigationTitle("Hostkeys")
} }
.scrollContentBackground(.hidden)
.navigationTitle("Hostkeys")
} }
} }
} }
#Preview { #Preview {
HostkeysView(hostsManager: HostsManager()) HostkeysView(hostsManager: HostsManager())
} }

View File

@@ -17,59 +17,57 @@ struct KeyManagerView: View {
ZStack { ZStack {
hostsManager.selectedTheme.background.suiColor.opacity(0.7) hostsManager.selectedTheme.background.suiColor.opacity(0.7)
.ignoresSafeArea(.all) .ignoresSafeArea(.all)
NavigationStack { List {
List { Section() {
Section() { ForEach(keyManager.keypairs) { kp in
ForEach(keyManager.keypairs) { kp in NavigationLink {
NavigationLink { KeyDetailView(
KeyDetailView( hostsManager: hostsManager,
hostsManager: hostsManager, keyManager: keyManager,
keyManager: keyManager, keypair: kp
keypair: kp )
) } label: {
HStack {
Image(systemName: "key")
if kp.label.isEmpty {
Text(kp.id.uuidString)
} else {
Text(kp.label)
}
Spacer()
Text(kp.type.description)
.foregroundStyle(.gray)
}
}
.swipeActions(edge: .trailing) {
Button(role: .destructive) {
keyManager.deleteKey(kp)
} label: { } label: {
HStack { Label("Delete", systemImage: "trash")
Image(systemName: "key")
if kp.label.isEmpty {
Text(kp.id.uuidString)
} else {
Text(kp.label)
}
Spacer()
Text(kp.type.description)
.foregroundStyle(.gray)
}
}
.swipeActions(edge: .trailing) {
Button(role: .destructive) {
keyManager.deleteKey(kp)
} label: {
Label("Delete", systemImage: "trash")
}
} }
} }
.id(keyManager.keypairs)
} }
.id(keyManager.keypairs)
CenteredLabel(title: "Generate a key", systemName: "plus")
.onTapGesture {
let comment = UIDevice().model + " at " + Date().formatted(date: .numeric, time: .omitted)
keyManager.generateKey(type: .ed25519, comment: comment)
}
.listRowSeparator(.hidden)
CenteredLabel(title: "Import a key", systemName: "square.and.arrow.down")
.onTapGesture {
showImporter.toggle()
}
.sheet(isPresented: $showImporter) {
KeyImporterView(keyManager: keyManager)
.colorScheme(hostsManager.selectedTheme.background.luminance > 0.5 ? .light : .dark)
}
} }
.scrollContentBackground(.hidden)
.navigationTitle("Keys") CenteredLabel(title: "Generate a key", systemName: "plus")
.onTapGesture {
let comment = UIDevice().model + " at " + Date().formatted(date: .numeric, time: .omitted)
keyManager.generateKey(type: .ed25519, comment: comment)
}
.listRowSeparator(.hidden)
CenteredLabel(title: "Import a key", systemName: "square.and.arrow.down")
.onTapGesture {
showImporter.toggle()
}
.sheet(isPresented: $showImporter) {
KeyImporterView(keyManager: keyManager)
.colorScheme(hostsManager.selectedTheme.background.luminance > 0.5 ? .light : .dark)
}
} }
.scrollContentBackground(.hidden)
.navigationTitle("Keys")
} }
} }
} }

View File

@@ -11,79 +11,77 @@ struct SnippetManagerView: View {
@ObservedObject var hostsManager: HostsManager @ObservedObject var hostsManager: HostsManager
@State var showSnippetAdder: Bool = false @State var showSnippetAdder: Bool = false
var body: some View { var body: some View {
ZStack { ZStack {
hostsManager.selectedTheme.background.suiColor.opacity(0.7) hostsManager.selectedTheme.background.suiColor.opacity(0.7)
.ignoresSafeArea(.all) .ignoresSafeArea(.all)
NavigationStack { List {
List { if hostsManager.snippets.isEmpty {
if hostsManager.snippets.isEmpty { VStack(alignment: .leading) {
VStack(alignment: .leading) { Image(systemName: "questionmark.square.dashed")
Image(systemName: "questionmark.square.dashed") .resizable().scaledToFit()
.resizable().scaledToFit() .frame(width: 75)
.frame(width: 75) .foregroundStyle(hostsManager.tint)
.foregroundStyle(hostsManager.tint) .shadow(color: hostsManager.tint, radius: 2)
.shadow(color: hostsManager.tint, radius: 2) .padding(.bottom, 10)
.padding(.bottom, 10) Text("No Snippets")
Text("No Snippets") .font(.title)
.font(.title) .monospaced()
.monospaced() Text("Snippets are strings of commands that can be run at once in a terminal.")
Text("Snippets are strings of commands that can be run at once in a terminal.") .padding(.bottom)
.padding(.bottom) .foregroundStyle(.gray)
.foregroundStyle(.gray) .foregroundStyle(.foreground.opacity(0.7))
.foregroundStyle(.foreground.opacity(0.7))
}
}
ForEach(hostsManager.snippets) { snip in
VStack(alignment: .leading) {
Text(snip.name)
.bold()
.foregroundStyle(.gray)
.font(.subheadline)
Text(snip.content)
.lineLimit(3)
}
.swipeActions(edge: .trailing) {
Button(role: .destructive) {
hostsManager.deleteSnippet(snip)
} label: {
Label("Delete", systemImage: "trash")
}
.tint(.red)
Button {
hostsManager.duplicateSnippet(snip)
} label: {
Label("Duplicate", systemImage: "square.filled.on.square")
}
.tint(.blue)
Button {
UIPasteboard().string = snip.content
} label: {
Label("Copy", systemImage: "doc.on.clipboard")
}
.tint(.blue)
}
} }
} }
.scrollContentBackground(.hidden) ForEach(hostsManager.snippets) { snip in
.sheet(isPresented: $showSnippetAdder) { VStack(alignment: .leading) {
AddSnippetView(hostsManager: hostsManager) Text(snip.name)
.presentationDetents([.medium]) .bold()
} .foregroundStyle(.gray)
.toolbar { .font(.subheadline)
Button() { Text(snip.content)
showSnippetAdder.toggle() .lineLimit(3)
} label: {
Label("Add", systemImage: "plus")
} }
.swipeActions(edge: .trailing) {
Button(role: .destructive) {
hostsManager.deleteSnippet(snip)
} label: {
Label("Delete", systemImage: "trash")
}
.tint(.red)
Button {
hostsManager.duplicateSnippet(snip)
} label: {
Label("Duplicate", systemImage: "square.filled.on.square")
}
.tint(.blue)
Button {
UIPasteboard().string = snip.content
} label: {
Label("Copy", systemImage: "doc.on.clipboard")
}
.tint(.blue)
}
}
}
.scrollContentBackground(.hidden)
.sheet(isPresented: $showSnippetAdder) {
AddSnippetView(hostsManager: hostsManager)
.presentationDetents([.medium])
}
.toolbar {
Button() {
showSnippetAdder.toggle()
} label: {
Label("Add", systemImage: "plus")
} }
} }
.navigationTitle("Snippets") .navigationTitle("Snippets")
} }
} }
} }
#Preview { #Preview {
SnippetManagerView(hostsManager: HostsManager()) SnippetManagerView(hostsManager: HostsManager())
} }