import SwiftUI struct ServerListView: View { @Environment(AppState.self) private var appState @State private var serverToDelete: SavedServer? var body: some View { @Bindable var state = appState NavigationStack { Group { if appState.servers.isEmpty { ContentUnavailableView( "No Servers", systemImage: "server.rack", description: Text("Tap + to add a server.") ) } else { List { ForEach(appState.servers) { server in Button { appState.connectTo(server) } label: { ServerRowView(server: server) } .swipeActions(edge: .trailing) { Button(role: .destructive) { serverToDelete = server } label: { Label("Delete", systemImage: "trash") } Button { appState.editingServer = server } label: { Label("Edit", systemImage: "pencil") } .tint(.blue) } } } } } .navigationTitle("Servers") .toolbar { ToolbarItem(placement: .primaryAction) { Button { appState.showAddServer = true } label: { Image(systemName: "plus") } .accessibilityLabel("Add server") } } .sheet(isPresented: $state.showAddServer) { AddServerView(editing: nil) } .sheet(item: $state.editingServer) { server in AddServerView(editing: server) } .sheet(item: $state.pendingIdentity) { identity in ServerIdentityView(identity: identity) } .sheet(isPresented: $state.showPasswordPrompt) { PasswordPromptView() } .overlay { if appState.isConnecting { ConnectingOverlay() } } .confirmationDialog("Delete server?", isPresented: Binding( get: { serverToDelete != nil }, set: { if !$0 { serverToDelete = nil } } )) { if let s = serverToDelete { Button("Delete \(s.displayString)", role: .destructive) { appState.removeServer(s) serverToDelete = nil } } Button("Cancel", role: .cancel) { serverToDelete = nil } } } } } private struct ServerRowView: View { let server: SavedServer var body: some View { VStack(alignment: .leading, spacing: 2) { Text(server.displayString) .font(.body) Text(server.authMode == .guest ? "Guest" : "Account: \(server.savedUsername)") .font(.caption) .foregroundStyle(.secondary) } .accessibilityElement(children: .combine) .accessibilityLabel("\(server.displayString), \(server.authMode == .guest ? "guest" : "account \(server.savedUsername)")") } } private struct ConnectingOverlay: View { @Environment(AppState.self) private var appState var body: some View { ZStack { Color.black.opacity(0.3).ignoresSafeArea() VStack(spacing: 16) { ProgressView() Text(appState.connectStatus) .foregroundStyle(.white) Button("Cancel") { appState.cancelConnect() } .buttonStyle(.bordered) .tint(.white) } .padding(24) .background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 16)) } } }