import SwiftUI struct AddContactOrChannelScreen: View { @EnvironmentObject var wrapper: MonalXmppWrapper @Environment(\.router) var router enum Field { case account case contact } @FocusState private var focus: Field? @State private var ownerAccount: Account? @State private var contactJID: String = "" var body: some View { ZStack { // Background color Color.Material.Background.light .ignoresSafeArea() // Content VStack(spacing: 0) { // Header SharedNavigationBar( leftButton: .init( image: Image(systemName: "xmark"), action: { router.dismissScreen() } ), centerText: .init(text: L10n.Contacts.Add.title), rightButton: .init( image: Image(systemName: "plus.viewfinder"), action: { print("Scan QR-code") } ) ) // Content VStack(spacing: 16) { // Explanation text Text(L10n.Contacts.Add.explanation) .font(.body3) .foregroundColor(.Material.Shape.separator) .multilineTextAlignment(.center) .padding(.top, 16) // Account selector HStack(spacing: 0) { Text("Use account:") .font(.body2) .foregroundColor(.Material.Text.main) .frame(alignment: .leading) Spacer() } UniversalInputCollection.DropDownMenu( prompt: "Use account", elements: wrapper.accounts, selected: $ownerAccount, focus: $focus, fieldType: .account ) // Contact text input HStack(spacing: 0) { Text("Contact JID:") .font(.body2) .foregroundColor(.Material.Text.main) .frame(alignment: .leading) Spacer() } UniversalInputCollection.TextField( prompt: "Contact or channel JID", text: $contactJID, focus: $focus, fieldType: .contact, contentType: .emailAddress, keyboardType: .emailAddress, submitLabel: .done, action: { focus = .account } ) // Save button Button { Task { await save() } } label: { Text(L10n.Global.save) } .buttonStyle(PrimaryButtonStyle()) .disabled(!inputValid) .padding(.top) Spacer() } .padding(.horizontal, 32) } } .onAppear { if let exists = wrapper.accounts.first { ownerAccount = exists } } } private var inputValid: Bool { ownerAccount != nil && !contactJID.isEmpty && UniversalInputCollection.Validators.isEmail(contactJID) } private func save() async { guard let ownerAccount = ownerAccount else { return } router.showModal { LoadingScreen() } defer { router.dismissModal() } do { try await wrapper.addContact(contactJid: contactJID, forAccountID: ownerAccount.id) router.dismissScreen() } catch { router.showAlert( .alert, title: L10n.Global.Error.title, subtitle: L10n.Contacts.Add.serverError ) { Button(L10n.Global.ok, role: .cancel) {} } } } }