import Combine import Martin import SwiftUI struct LoginScreen: View { @Environment(\.router) var router @EnvironmentObject var clientsStore: ClientsStore enum Field { case userJid case password } @FocusState private var focus: Field? #if DEBUG @State private var jidStr: String = "nartest1@conversations.im" @State private var pass: String = "nartest12345" // @State private var jidStr: String = "test1@test.anal.company" // @State private var pass: String = "12345" #else @State private var jidStr: String = "" @State private var pass: String = "" #endif public var body: some View { ZStack { // background Color.Material.Background.light .ignoresSafeArea() // content VStack(spacing: 32) { // icon Image.logo .resizable() .aspectRatio(contentMode: .fit) .frame(width: 120, height: 120) // texts VStack(spacing: 10) { Text(L10n.Login.title) .font(.head1l) .foregroundColor(.Material.Text.main) .fixedSize(horizontal: true, vertical: false) Text(L10n.Login.subtitle) .font(.body2) .foregroundColor(.Material.Text.sub) .multilineTextAlignment(.center) .fixedSize(horizontal: false, vertical: true) } VStack(spacing: 16) { UniversalInputCollection.TextField( prompt: L10n.Login.Hint.jid, text: $jidStr, focus: $focus, fieldType: .userJid, contentType: .emailAddress, keyboardType: .emailAddress, submitLabel: .next, action: { focus = .password } ) UniversalInputCollection.SecureField( prompt: L10n.Login.Hint.password, text: $pass, focus: $focus, fieldType: .password, submitLabel: .go, action: { focus = nil } ) Button { Task { await tryLogin() } } label: { Text(L10n.Login.btn) } .buttonStyle(PrimaryButtonStyle()) .disabled(!loginInputValid) Button { router.dismissScreen() } label: { Text("\(Image(systemName: "chevron.left")) \(L10n.Global.back)") .foregroundColor(.Material.Elements.active) .font(.body2) } } } .padding(.horizontal, 32) } } private var loginInputValid: Bool { !jidStr.isEmpty && !pass.isEmpty && UniversalInputCollection.Validators.isEmail(jidStr) } private func tryLogin() async { router.showModal { LoadingScreen() } defer { router.dismissModal() } do { try await clientsStore.tryLogin(jidStr, pass) } catch { router.dismissModal() router.showAlert( .alert, title: L10n.Global.Error.title, subtitle: L10n.Login.error ) { Button(L10n.Global.ok, role: .cancel) {} } } } }