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 {
hostsManager.selectedTheme.background.suiColor.opacity(0.7)
.ignoresSafeArea(.all)
NavigationStack {
List {
if hostsManager.hosts.isEmpty {
List {
if hostsManager.hosts.isEmpty {
VStack(alignment: .leading) {
Text("Looking empty 'round here...")
.font(.title3)
.bold()
.padding(.bottom)
VStack(alignment: .leading) {
Text("Looking empty 'round here...")
.font(.title3)
.bold()
Text("Connect to some hosts to collect more hostkeys!")
.padding(.bottom)
VStack(alignment: .leading) {
Text("Connect to some hosts to collect more hostkeys!")
.padding(.bottom)
Text("ShhShell remembers hostkey fingerprints for you, and will alert you if they change.")
.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 {
Text("name")
.foregroundStyle(.gray)
.font(.caption)
Text(host.name)
.bold()
}
Text("address")
.foregroundStyle(.gray)
.font(.caption)
Text(host.address)
.bold()
Text(host.key ?? "nil")
}
.swipeActions(edge: .trailing, allowsFullSwipe: true) {
Button(/*role: .destructive*/) {
host.key = nil
hostsManager.updateHost(host)
} label: {
Label("Forget", systemImage: "trash")
}
Text("ShhShell remembers hostkey fingerprints for you, and will alert you if they change.")
.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 {
Text("name")
.foregroundStyle(.gray)
.font(.caption)
Text(host.name)
.bold()
}
Text("address")
.foregroundStyle(.gray)
.font(.caption)
Text(host.address)
.bold()
Text(host.key ?? "nil")
}
.swipeActions(edge: .trailing, allowsFullSwipe: true) {
Button(/*role: .destructive*/) {
host.key = nil
hostsManager.updateHost(host)
} label: {
Label("Forget", systemImage: "trash")
}
}
}
.scrollContentBackground(.hidden)
.navigationTitle("Hostkeys")
}
.scrollContentBackground(.hidden)
.navigationTitle("Hostkeys")
}
}
}
#Preview {
HostkeysView(hostsManager: HostsManager())
HostkeysView(hostsManager: HostsManager())
}

View File

@@ -17,59 +17,57 @@ struct KeyManagerView: View {
ZStack {
hostsManager.selectedTheme.background.suiColor.opacity(0.7)
.ignoresSafeArea(.all)
NavigationStack {
List {
Section() {
ForEach(keyManager.keypairs) { kp in
NavigationLink {
KeyDetailView(
hostsManager: hostsManager,
keyManager: keyManager,
keypair: kp
)
List {
Section() {
ForEach(keyManager.keypairs) { kp in
NavigationLink {
KeyDetailView(
hostsManager: hostsManager,
keyManager: keyManager,
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: {
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("Delete", systemImage: "trash")
}
Label("Delete", systemImage: "trash")
}
}
.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)
}
.id(keyManager.keypairs)
}
.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
@State var showSnippetAdder: Bool = false
var body: some View {
var body: some View {
ZStack {
hostsManager.selectedTheme.background.suiColor.opacity(0.7)
.ignoresSafeArea(.all)
NavigationStack {
List {
if hostsManager.snippets.isEmpty {
VStack(alignment: .leading) {
Image(systemName: "questionmark.square.dashed")
.resizable().scaledToFit()
.frame(width: 75)
.foregroundStyle(hostsManager.tint)
.shadow(color: hostsManager.tint, radius: 2)
.padding(.bottom, 10)
Text("No Snippets")
.font(.title)
.monospaced()
Text("Snippets are strings of commands that can be run at once in a terminal.")
.padding(.bottom)
.foregroundStyle(.gray)
.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)
}
List {
if hostsManager.snippets.isEmpty {
VStack(alignment: .leading) {
Image(systemName: "questionmark.square.dashed")
.resizable().scaledToFit()
.frame(width: 75)
.foregroundStyle(hostsManager.tint)
.shadow(color: hostsManager.tint, radius: 2)
.padding(.bottom, 10)
Text("No Snippets")
.font(.title)
.monospaced()
Text("Snippets are strings of commands that can be run at once in a terminal.")
.padding(.bottom)
.foregroundStyle(.gray)
.foregroundStyle(.foreground.opacity(0.7))
}
}
.scrollContentBackground(.hidden)
.sheet(isPresented: $showSnippetAdder) {
AddSnippetView(hostsManager: hostsManager)
.presentationDetents([.medium])
}
.toolbar {
Button() {
showSnippetAdder.toggle()
} label: {
Label("Add", systemImage: "plus")
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)
.sheet(isPresented: $showSnippetAdder) {
AddSnippetView(hostsManager: hostsManager)
.presentationDetents([.medium])
}
.toolbar {
Button() {
showSnippetAdder.toggle()
} label: {
Label("Add", systemImage: "plus")
}
}
.navigationTitle("Snippets")
}
}
}
}
#Preview {
SnippetManagerView(hostsManager: HostsManager())
SnippetManagerView(hostsManager: HostsManager())
}