142 lines
7.3 KiB
Swift
142 lines
7.3 KiB
Swift
|
//
|
||
|
// AddContactMenu.swift
|
||
|
// Monal
|
||
|
//
|
||
|
// Created by Jan on 27.10.22.
|
||
|
// Copyright © 2022 monal-im.org. All rights reserved.
|
||
|
//
|
||
|
|
||
|
import OrderedCollections
|
||
|
|
||
|
struct CreateGroupMenu: View {
|
||
|
private var appDelegate: MonalAppDelegate
|
||
|
private var delegate: SheetDismisserProtocol
|
||
|
@State private var enabledAccounts: [xmpp]
|
||
|
@State private var selectedAccount: xmpp?
|
||
|
@State private var groupName: String = ""
|
||
|
@State private var showAlert = false
|
||
|
// note: dismissLabel is not accessed but defined at the .alert() section
|
||
|
@State private var alertPrompt = AlertPrompt(dismissLabel: Text("Close"))
|
||
|
@State private var selectedContacts: OrderedSet<ObservableKVOWrapper<MLContact>> = []
|
||
|
@State private var isEditingGroupName = false
|
||
|
@StateObject private var overlay = LoadingOverlayState()
|
||
|
|
||
|
init(delegate: SheetDismisserProtocol) {
|
||
|
self.appDelegate = UIApplication.shared.delegate as! MonalAppDelegate
|
||
|
self.delegate = delegate
|
||
|
|
||
|
let enabledAccounts = MLXMPPManager.sharedInstance().connectedXMPP as! [xmpp]
|
||
|
self.enabledAccounts = enabledAccounts
|
||
|
_selectedAccount = State(wrappedValue: enabledAccounts.first)
|
||
|
}
|
||
|
|
||
|
private func errorAlert(title: Text, message: Text = Text("")) {
|
||
|
alertPrompt.title = title
|
||
|
alertPrompt.message = message
|
||
|
showAlert = true
|
||
|
}
|
||
|
|
||
|
// When a Form is placed inside a Popover, and the horizontal size class is regular, the spacing chosen by SwiftUI is incorrect.
|
||
|
// In particular, the spacing between the top of the first element and the navigation bar is too small, meaning the two overlap.
|
||
|
// This only happens when the view is inside a popover, and the horizontal size class is regular.
|
||
|
// Therefore, it is inconvenient to apply some manual spacing, as this we would have to work out in which situations it should be applied.
|
||
|
// Placing a Text view inside the header causes SwiftUI to add consistent spacing in all situations.
|
||
|
var popoverFormSpacingWorkaround: some View {
|
||
|
Text("")
|
||
|
}
|
||
|
|
||
|
var body: some View {
|
||
|
Form {
|
||
|
if enabledAccounts.isEmpty {
|
||
|
Text("Please make sure at least one account has connected before trying to create new group.")
|
||
|
.foregroundColor(.secondary)
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Section(header: popoverFormSpacingWorkaround) {
|
||
|
if enabledAccounts.count > 1 {
|
||
|
Picker(selection: $selectedAccount, label: Text("Use account")) {
|
||
|
ForEach(Array(self.enabledAccounts.enumerated()), id: \.element) { idx, account in
|
||
|
Text(account.connectionProperties.identity.jid).tag(account as xmpp?)
|
||
|
}
|
||
|
}
|
||
|
.pickerStyle(.menu)
|
||
|
}
|
||
|
|
||
|
TextField(NSLocalizedString("Group Name (optional)", comment: "placeholder when creating new group"), text: $groupName, onEditingChanged: { isEditingGroupName = $0 })
|
||
|
.autocorrectionDisabled()
|
||
|
.autocapitalization(.none)
|
||
|
.addClearButton(isEditing: isEditingGroupName, text:$groupName)
|
||
|
|
||
|
Button(action: {
|
||
|
guard let generatedJid = self.selectedAccount!.mucProcessor.generateMucJid() else {
|
||
|
errorAlert(title: Text("Error creating group!"), message: Text("Your server does not provide a MUC component."))
|
||
|
return
|
||
|
}
|
||
|
showLoadingOverlay(overlay, headline: NSLocalizedString("Creating Group", comment: ""))
|
||
|
guard let roomJid = self.selectedAccount!.mucProcessor.createGroup(generatedJid) else {
|
||
|
//room already existing in our local bookmarks --> just open it
|
||
|
//this should never happen since we randomly generated a jid above
|
||
|
hideLoadingOverlay(overlay)
|
||
|
let groupContact = MLContact.createContact(fromJid: generatedJid, andAccountID: self.selectedAccount!.accountID)
|
||
|
self.delegate.dismissWithoutAnimation()
|
||
|
if let activeChats = self.appDelegate.activeChats {
|
||
|
activeChats.presentChat(with:groupContact)
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
self.selectedAccount!.mucProcessor.addUIHandler({_data in let data = _data as! NSDictionary
|
||
|
let success : Bool = data["success"] as! Bool;
|
||
|
if success {
|
||
|
DataLayer.sharedInstance().setFullName(self.groupName, forContact:roomJid, andAccount:self.selectedAccount!.accountID)
|
||
|
self.selectedAccount!.mucProcessor.changeName(ofMuc: roomJid, to: self.groupName)
|
||
|
for user in self.selectedContacts {
|
||
|
self.selectedAccount!.mucProcessor.setAffiliation(kMucAffiliationMember, ofUser: user.contactJid, inMuc: roomJid)
|
||
|
self.selectedAccount!.mucProcessor.inviteUser(user.contactJid, inMuc: roomJid)
|
||
|
}
|
||
|
let groupContact = MLContact.createContact(fromJid: roomJid, andAccountID: self.selectedAccount!.accountID)
|
||
|
hideLoadingOverlay(overlay)
|
||
|
self.delegate.dismissWithoutAnimation()
|
||
|
if let activeChats = self.appDelegate.activeChats {
|
||
|
activeChats.presentChat(with:groupContact)
|
||
|
}
|
||
|
} else {
|
||
|
hideLoadingOverlay(overlay)
|
||
|
errorAlert(title: Text("Error creating group!"), message: Text(data["errorMessage"] as! String))
|
||
|
}
|
||
|
}, forMuc: roomJid)
|
||
|
}, label: {
|
||
|
Text("Create new group")
|
||
|
})
|
||
|
}
|
||
|
|
||
|
Section(header: Text("Selected Group Members")) {
|
||
|
NavigationLink(destination: LazyClosureView(ContactPicker(self.selectedAccount!, binding: $selectedContacts))) {
|
||
|
Text("Change Group Members")
|
||
|
}
|
||
|
ForEach(self.selectedContacts, id: \.obj.contactJid) { contact in
|
||
|
ContactEntry(contact: contact)
|
||
|
}
|
||
|
.onDelete(perform: { indexSet in
|
||
|
self.selectedContacts.remove(at: indexSet.first!)
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
.alert(isPresented: $showAlert) {
|
||
|
Alert(title: alertPrompt.title, message: alertPrompt.message, dismissButton:.default(Text("Close"), action: {
|
||
|
showAlert = false
|
||
|
}))
|
||
|
}
|
||
|
.addLoadingOverlay(overlay)
|
||
|
.navigationBarTitle(Text("Create new group"), displayMode: .inline)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
struct CreateGroupMenu_Previews: PreviewProvider {
|
||
|
static var delegate = SheetDismisserProtocol()
|
||
|
static var previews: some View {
|
||
|
CreateGroupMenu(delegate: delegate)
|
||
|
}
|
||
|
}
|