2024-06-19 15:15:27 +00:00
|
|
|
import SwiftUI
|
|
|
|
|
|
|
|
struct AddContactOrChannelScreen: View {
|
2024-09-03 15:13:58 +00:00
|
|
|
@Environment(\.router) var router
|
|
|
|
@EnvironmentObject var clientsStore: ClientsStore
|
2024-06-19 15:15:27 +00:00
|
|
|
|
|
|
|
enum Field {
|
|
|
|
case account
|
|
|
|
case contact
|
|
|
|
}
|
|
|
|
|
|
|
|
@FocusState private var focus: Field?
|
|
|
|
|
2024-09-03 15:13:58 +00:00
|
|
|
@State private var ownerCredentials: Credentials?
|
2024-06-19 15:15:27 +00:00
|
|
|
@State private var contactJID: String = ""
|
|
|
|
|
|
|
|
var body: some View {
|
|
|
|
ZStack {
|
|
|
|
// Background color
|
2024-07-04 08:21:12 +00:00
|
|
|
Color.Material.Background.light
|
2024-06-19 15:15:27 +00:00
|
|
|
.ignoresSafeArea()
|
|
|
|
|
|
|
|
// Content
|
|
|
|
VStack(spacing: 0) {
|
|
|
|
// Header
|
2024-08-07 09:19:53 +00:00
|
|
|
SharedNavigationBar(
|
|
|
|
leftButton: .init(
|
2024-08-07 11:45:04 +00:00
|
|
|
image: Image(systemName: "xmark"),
|
2024-08-07 09:19:53 +00:00
|
|
|
action: {
|
2024-09-03 15:13:58 +00:00
|
|
|
router.dismissScreen()
|
2024-08-07 09:19:53 +00:00
|
|
|
}
|
|
|
|
),
|
|
|
|
centerText: .init(text: L10n.Contacts.Add.title),
|
|
|
|
rightButton: .init(
|
|
|
|
image: Image(systemName: "plus.viewfinder"),
|
|
|
|
action: {
|
|
|
|
print("Scan QR-code")
|
|
|
|
}
|
|
|
|
)
|
|
|
|
)
|
2024-06-19 15:15:27 +00:00
|
|
|
|
2024-09-03 15:13:58 +00:00
|
|
|
// Content
|
2024-06-19 15:15:27 +00:00
|
|
|
VStack(spacing: 16) {
|
|
|
|
// Explanation text
|
|
|
|
Text(L10n.Contacts.Add.explanation)
|
|
|
|
.font(.body3)
|
2024-07-04 08:21:12 +00:00
|
|
|
.foregroundColor(.Material.Shape.separator)
|
2024-06-19 15:15:27 +00:00
|
|
|
.multilineTextAlignment(.center)
|
|
|
|
.padding(.top, 16)
|
|
|
|
|
|
|
|
// Account selector
|
|
|
|
HStack(spacing: 0) {
|
|
|
|
Text("Use account:")
|
|
|
|
.font(.body2)
|
2024-07-04 08:21:12 +00:00
|
|
|
.foregroundColor(.Material.Text.main)
|
2024-06-19 15:15:27 +00:00
|
|
|
.frame(alignment: .leading)
|
|
|
|
Spacer()
|
|
|
|
}
|
|
|
|
UniversalInputCollection.DropDownMenu(
|
|
|
|
prompt: "Use account",
|
2024-09-03 15:13:58 +00:00
|
|
|
elements: activeClientsCredentials,
|
|
|
|
selected: $ownerCredentials,
|
2024-06-19 15:15:27 +00:00
|
|
|
focus: $focus,
|
|
|
|
fieldType: .account
|
|
|
|
)
|
|
|
|
|
|
|
|
// Contact text input
|
|
|
|
HStack(spacing: 0) {
|
|
|
|
Text("Contact JID:")
|
|
|
|
.font(.body2)
|
2024-07-04 08:21:12 +00:00
|
|
|
.foregroundColor(.Material.Text.main)
|
2024-06-19 15:15:27 +00:00
|
|
|
.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 {
|
2024-09-03 15:13:58 +00:00
|
|
|
Task {
|
|
|
|
await save()
|
|
|
|
}
|
2024-06-19 15:15:27 +00:00
|
|
|
} label: {
|
|
|
|
Text(L10n.Global.save)
|
|
|
|
}
|
|
|
|
.buttonStyle(PrimaryButtonStyle())
|
|
|
|
.disabled(!inputValid)
|
|
|
|
.padding(.top)
|
|
|
|
Spacer()
|
|
|
|
}
|
|
|
|
.padding(.horizontal, 32)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.onAppear {
|
2024-09-03 15:13:58 +00:00
|
|
|
if let exists = activeClientsCredentials.first {
|
|
|
|
ownerCredentials = exists
|
2024-06-19 15:15:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-09-03 15:13:58 +00:00
|
|
|
private var activeClientsCredentials: [Credentials] {
|
|
|
|
clientsStore.clients
|
|
|
|
.filter { $0.state != .disabled }
|
|
|
|
.map { $0.credentials }
|
|
|
|
}
|
|
|
|
|
2024-06-19 15:15:27 +00:00
|
|
|
private var inputValid: Bool {
|
2024-09-03 15:13:58 +00:00
|
|
|
ownerCredentials != nil && !contactJID.isEmpty && UniversalInputCollection.Validators.isEmail(contactJID)
|
2024-06-19 15:15:27 +00:00
|
|
|
}
|
|
|
|
|
2024-09-03 15:13:58 +00:00
|
|
|
private func save() async {
|
|
|
|
guard let ownerCredentials = ownerCredentials else { return }
|
|
|
|
|
|
|
|
router.showModal {
|
|
|
|
LoadingScreen()
|
|
|
|
}
|
|
|
|
|
|
|
|
defer {
|
|
|
|
router.dismissModal()
|
|
|
|
}
|
|
|
|
|
|
|
|
do {
|
|
|
|
try await clientsStore.addRoster(ownerCredentials, contactJID: contactJID, name: nil, groups: [])
|
|
|
|
router.dismissScreen()
|
|
|
|
} catch {
|
|
|
|
router.showAlert(
|
|
|
|
.alert,
|
|
|
|
title: L10n.Global.Error.title,
|
|
|
|
subtitle: L10n.Contacts.Add.serverError
|
|
|
|
) {
|
|
|
|
Button(L10n.Global.ok, role: .cancel) {}
|
|
|
|
}
|
2024-06-19 15:15:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|