wip
This commit is contained in:
parent
4c42b21559
commit
49f1028d69
|
@ -11,7 +11,7 @@ import UniformTypeIdentifiers
|
|||
|
||||
struct AddContactMenu: View {
|
||||
var delegate: SheetDismisserProtocol
|
||||
static private let jidFaultyPattern = "^([^@]+@)?.+(\\..{2,})?$"
|
||||
private static let jidFaultyPattern = "^([^@]+@)?.+(\\..{2,})?$"
|
||||
|
||||
@State private var enabledAccounts: [xmpp]
|
||||
@State private var selectedAccount: Int
|
||||
|
@ -33,33 +33,33 @@ struct AddContactMenu: View {
|
|||
|
||||
@State private var isEditingJid = false
|
||||
|
||||
private let dismissWithNewContact: (MLContact) -> ()
|
||||
private let dismissWithNewContact: (MLContact) -> Void
|
||||
private let preauthToken: String?
|
||||
|
||||
init(delegate: SheetDismisserProtocol, dismissWithNewContact: @escaping (MLContact) -> (), prefillJid: String = "", preauthToken:String? = nil, prefillAccount:xmpp? = nil, omemoFingerprints: [NSNumber:Data]? = nil) {
|
||||
init(delegate: SheetDismisserProtocol, dismissWithNewContact: @escaping (MLContact) -> Void, prefillJid: String = "", preauthToken: String? = nil, prefillAccount: xmpp? = nil, omemoFingerprints: [NSNumber: Data]? = nil) {
|
||||
self.delegate = delegate
|
||||
self.dismissWithNewContact = dismissWithNewContact
|
||||
// self.toAdd = State(wrappedValue: prefillJid)
|
||||
self.toAdd = prefillJid
|
||||
toAdd = prefillJid
|
||||
self.preauthToken = preauthToken
|
||||
// only display omemo ui part if there are any fingerprints (the checks below test for nil, not for 0)
|
||||
if omemoFingerprints?.count ?? 0 > 0 {
|
||||
self.scannedFingerprints = omemoFingerprints
|
||||
scannedFingerprints = omemoFingerprints
|
||||
}
|
||||
|
||||
let enabledAccounts = MLXMPPManager.sharedInstance().connectedXMPP as! [xmpp]
|
||||
self.enabledAccounts = enabledAccounts
|
||||
self.selectedAccount = enabledAccounts.first != nil ? 0 : -1;
|
||||
selectedAccount = enabledAccounts.first != nil ? 0 : -1
|
||||
if let prefillAccount = prefillAccount {
|
||||
for index in enabledAccounts.indices {
|
||||
if enabledAccounts[index].accountID.isEqual(to: prefillAccount.accountID) {
|
||||
self.selectedAccount = index
|
||||
selectedAccount = index
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME duplicate code from WelcomeLogIn.swift, maybe move to SwiftuiHelpers
|
||||
// FIXME: duplicate code from WelcomeLogIn.swift, maybe move to SwiftuiHelpers
|
||||
private var toAddEmptyAlert: Bool {
|
||||
alertPrompt.title = Text("No Empty Values!")
|
||||
alertPrompt.message = Text("Please make sure you have entered a valid jid.")
|
||||
|
@ -81,23 +81,23 @@ struct AddContactMenu: View {
|
|||
private func successAlert(title: Text, message: Text) {
|
||||
alertPrompt.title = title
|
||||
alertPrompt.message = message
|
||||
self.success = true // < dismiss entire view on close
|
||||
success = true // < dismiss entire view on close
|
||||
showAlert = true
|
||||
}
|
||||
|
||||
private var toAddEmpty: Bool {
|
||||
return toAdd.isEmpty
|
||||
toAdd.isEmpty
|
||||
}
|
||||
|
||||
private var toAddInvalid: Bool {
|
||||
return toAdd.range(of: AddContactMenu.jidFaultyPattern, options:.regularExpression) == nil
|
||||
toAdd.range(of: AddContactMenu.jidFaultyPattern, options: .regularExpression) == nil
|
||||
}
|
||||
|
||||
func trustFingerprints(_ fingerprints: [NSNumber: Data]?, for jid: String, on account: xmpp) {
|
||||
// we don't untrust other devices not included in here, because conversations only exports its own fingerprint
|
||||
if let fingerprints = fingerprints {
|
||||
for (deviceId, fingerprint) in fingerprints {
|
||||
let address = SignalAddress.init(name:jid, deviceId:deviceId.int32Value)
|
||||
let address = SignalAddress(name: jid, deviceId: deviceId.int32Value)
|
||||
let knownDevices = Array(account.omemo.knownDevices(forAddressName: jid))
|
||||
if !knownDevices.contains(deviceId) {
|
||||
account.omemo.addIdentityManually(address, identityKey: fingerprint)
|
||||
|
@ -114,19 +114,19 @@ struct AddContactMenu: View {
|
|||
}
|
||||
|
||||
func addJid(jid: String) {
|
||||
let account = self.enabledAccounts[selectedAccount]
|
||||
let account = enabledAccounts[selectedAccount]
|
||||
let contact = MLContact.createContact(fromJid: jid, andAccountID: account.accountID)
|
||||
if contact.isInRoster {
|
||||
self.newContact = contact
|
||||
newContact = contact
|
||||
// import omemo fingerprints as manually trusted, if requested
|
||||
trustFingerprints(self.importScannedFingerprints ? self.scannedFingerprints : [:], for:jid, on:account)
|
||||
trustFingerprints(importScannedFingerprints ? scannedFingerprints : [:], for: jid, on: account)
|
||||
// only alert of already known contact if we did not import the omemo fingerprints
|
||||
if !self.importScannedFingerprints || self.scannedFingerprints?.count ?? 0 == 0 {
|
||||
if self.enabledAccounts.count > 1 {
|
||||
self.success = true
|
||||
if !importScannedFingerprints || scannedFingerprints?.count ?? 0 == 0 {
|
||||
if enabledAccounts.count > 1 {
|
||||
success = true
|
||||
successAlert(title: Text("Already present"), message: Text("This contact is already in the contact list of the selected account"))
|
||||
} else {
|
||||
self.success = true
|
||||
success = true
|
||||
successAlert(title: Text("Already present"), message: Text("This contact is already in your contact list"))
|
||||
}
|
||||
}
|
||||
|
@ -161,16 +161,14 @@ struct AddContactMenu: View {
|
|||
}
|
||||
|
||||
var body: some View {
|
||||
let account = self.enabledAccounts[selectedAccount]
|
||||
let account = enabledAccounts[selectedAccount]
|
||||
let splitJid = HelperTools.splitJid(account.connectionProperties.identity.jid)
|
||||
Form {
|
||||
if enabledAccounts.isEmpty {
|
||||
Text("Please make sure at least one account has connected before trying to add a contact or channel.")
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
else
|
||||
{
|
||||
if DataLayer.sharedInstance().allContactRequests().count > 0 {
|
||||
} else {
|
||||
if !DataLayer.sharedInstance().allContactRequests().isEmpty {
|
||||
ContactRequestsMenu()
|
||||
}
|
||||
|
||||
|
@ -194,7 +192,7 @@ struct AddContactMenu: View {
|
|||
.foregroundColor(scannedFingerprints != nil ? .secondary : .primary)
|
||||
.onChange(of: toAdd) { _ in toAdd = toAdd.replacingOccurrences(of: " ", with: "") }
|
||||
|
||||
if scannedFingerprints != nil && scannedFingerprints!.count > 0 {
|
||||
if scannedFingerprints != nil && !scannedFingerprints!.isEmpty {
|
||||
Section(header: Text("A contact was scanned through the QR code scanner")) {
|
||||
Toggle(isOn: $importScannedFingerprints) {
|
||||
Text("Import and trust OMEMO fingerprints from QR code")
|
||||
|
@ -237,7 +235,7 @@ struct AddContactMenu: View {
|
|||
}
|
||||
}
|
||||
|
||||
if DataLayer.sharedInstance().allContactRequests().count == 0 {
|
||||
if DataLayer.sharedInstance().allContactRequests().isEmpty {
|
||||
Section {
|
||||
ContactRequestsMenu()
|
||||
}
|
||||
|
@ -341,7 +339,7 @@ struct AddContactMenu: View {
|
|||
struct AddContactMenu_Previews: PreviewProvider {
|
||||
static var delegate = SheetDismisserProtocol()
|
||||
static var previews: some View {
|
||||
AddContactMenu(delegate: delegate, dismissWithNewContact: { c in
|
||||
AddContactMenu(delegate: delegate, dismissWithNewContact: { _ in
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,12 +11,12 @@ import SwiftUI
|
|||
struct ContactViewEntry: View {
|
||||
private let contact: MLContact
|
||||
@Binding private var selectedContactForContactDetails: ObservableKVOWrapper<MLContact>?
|
||||
private let dismissWithContact: (MLContact) -> ()
|
||||
private let dismissWithContact: (MLContact) -> Void
|
||||
|
||||
@State private var shouldPresentRemoveContactAlert: Bool = false
|
||||
|
||||
private var removeContactButtonText: String {
|
||||
if (!isDeletable) {
|
||||
if !isDeletable {
|
||||
return "Cannot delete notes to self"
|
||||
}
|
||||
return contact.isMuc ? "Remove Conversation" : "Remove Contact"
|
||||
|
@ -34,9 +34,9 @@ struct ContactViewEntry: View {
|
|||
!contact.isSelfChat
|
||||
}
|
||||
|
||||
init (contact: MLContact, selectedContactForContactDetails: Binding<ObservableKVOWrapper<MLContact>?>, dismissWithContact: @escaping (MLContact) -> ()) {
|
||||
init(contact: MLContact, selectedContactForContactDetails: Binding<ObservableKVOWrapper<MLContact>?>, dismissWithContact: @escaping (MLContact) -> Void) {
|
||||
self.contact = contact
|
||||
self._selectedContactForContactDetails = selectedContactForContactDetails
|
||||
_selectedContactForContactDetails = selectedContactForContactDetails
|
||||
self.dismissWithContact = dismissWithContact
|
||||
}
|
||||
|
||||
|
@ -88,12 +88,12 @@ struct ContactViewEntry: View {
|
|||
struct ContactsView: View {
|
||||
@ObservedObject private var contacts: Contacts
|
||||
private let delegate: SheetDismisserProtocol
|
||||
private let dismissWithContact: (MLContact) -> ()
|
||||
private let dismissWithContact: (MLContact) -> Void
|
||||
|
||||
@State private var searchText: String = ""
|
||||
@State private var selectedContactForContactDetails: ObservableKVOWrapper<MLContact>? = nil
|
||||
|
||||
init(contacts: Contacts, delegate: SheetDismisserProtocol, dismissWithContact: @escaping (MLContact) -> ()) {
|
||||
init(contacts: Contacts, delegate: SheetDismisserProtocol, dismissWithContact: @escaping (MLContact) -> Void) {
|
||||
self.contacts = contacts
|
||||
self.delegate = delegate
|
||||
self.dismissWithContact = dismissWithContact
|
||||
|
@ -107,7 +107,7 @@ struct ContactsView: View {
|
|||
}
|
||||
|
||||
private var contactList: [MLContact] {
|
||||
return contacts.contacts
|
||||
contacts.contacts
|
||||
.filter(ContactsView.shouldDisplayContact)
|
||||
.sorted { ContactsView.sortingCriteria($0) < ContactsView.sortingCriteria($1) }
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ struct ContactsView: View {
|
|||
}
|
||||
|
||||
private static func sortingCriteria(_ contact: MLContact) -> (String, String) {
|
||||
return (contact.contactDisplayName.lowercased(), contact.contactJid.lowercased())
|
||||
(contact.contactDisplayName.lowercased(), contact.contactJid.lowercased())
|
||||
}
|
||||
|
||||
private func searchMatchesContact(contact: MLContact, search: String) -> Bool {
|
||||
|
@ -175,20 +175,20 @@ class Contacts: ObservableObject {
|
|||
private var subscriptions: Set<AnyCancellable> = Set()
|
||||
|
||||
init() {
|
||||
self.contacts = Set(DataLayer.sharedInstance().contactList())
|
||||
self.requestCount = DataLayer.sharedInstance().allContactRequests().count
|
||||
contacts = Set(DataLayer.sharedInstance().contactList())
|
||||
requestCount = DataLayer.sharedInstance().allContactRequests().count
|
||||
subscriptions = [
|
||||
NotificationCenter.default.publisher(for: NSNotification.Name("kMonalContactRemoved"))
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink() { _ in self.refreshContacts() },
|
||||
.sink { _ in self.refreshContacts() },
|
||||
NotificationCenter.default.publisher(for: NSNotification.Name("kMonalContactRefresh"))
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink() { _ in self.refreshContacts() }
|
||||
.sink { _ in self.refreshContacts() }
|
||||
]
|
||||
}
|
||||
|
||||
private func refreshContacts() {
|
||||
self.contacts = Set(DataLayer.sharedInstance().contactList())
|
||||
self.requestCount = DataLayer.sharedInstance().allContactRequests().count
|
||||
contacts = Set(DataLayer.sharedInstance().contactList())
|
||||
requestCount = DataLayer.sharedInstance().allContactRequests().count
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,17 +123,7 @@ struct AddContactOrChannelScreen: View {
|
|||
router.dismissModal()
|
||||
}
|
||||
|
||||
do {
|
||||
try await wrapper.addContact(contactJid: contactJID, forAccountID: ownerAccount.id)
|
||||
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) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ private struct ContactsScreenRow: View {
|
|||
|
||||
var body: some View {
|
||||
SharedListRow(
|
||||
iconType: .charCircle(contact.name?.firstLetter ?? contact.contactJid.firstLetter),
|
||||
iconType: .charCircle(contact.name ?? contact.contactJid),
|
||||
text: contact.contactJid,
|
||||
controlType: .none
|
||||
)
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
enum AimErrors: Error {
|
||||
case loginError
|
||||
case addContactError
|
||||
}
|
||||
|
|
|
@ -51,6 +51,6 @@ struct Contact: Identifiable {
|
|||
init?(_ obj: MLContact) {
|
||||
ownerId = obj.accountID.intValue
|
||||
contactJid = obj.contactJid
|
||||
name = obj.nickName
|
||||
name = obj.nickName.isEmpty ? nil : obj.nickName
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,15 +41,13 @@ extension MonalXmppWrapper {
|
|||
}
|
||||
}
|
||||
|
||||
func addContact(contactJid: String, forAccountID: Int) async throws {
|
||||
_ = await Task { [weak self] in
|
||||
let result = self?.db.addContact(contactJid, forAccount: NSNumber(value: forAccountID), nickname: nil) ?? true
|
||||
if result {
|
||||
NotificationCenter.default.post(name: Notification.Name(kMonalContactRefresh), object: nil)
|
||||
} else {
|
||||
throw AimErrors.addContactError
|
||||
func addContact(contactJid: String, forAccountID: Int) async {
|
||||
await withCheckedContinuation { [weak self] cnt in
|
||||
let contact = MLContact.createContact(fromJid: contactJid, andAccountID: NSNumber(value: forAccountID))
|
||||
self?.xmpp.add(contact)
|
||||
cnt.resume()
|
||||
}
|
||||
}.result
|
||||
NotificationCenter.default.post(name: Notification.Name(kMonalContactRefresh), object: nil)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -137,6 +135,9 @@ private extension MonalXmppWrapper {
|
|||
}
|
||||
|
||||
func refreshContacts() {
|
||||
contacts = db.contactList().compactMap { Contact($0) }
|
||||
contacts = db.contactList()
|
||||
.filter { $0.isSubscribedTo || $0.hasOutgoingContactRequest || $0.isSubscribedFrom }
|
||||
.filter { !$0.isSelfChat } // removed for now
|
||||
.compactMap { Contact($0) }
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue