From 7dca3300e19f4e8815e1fc5a25293af4540f2e6e Mon Sep 17 00:00:00 2001 From: Benoit Martins Date: Wed, 29 May 2024 16:41:35 +0200 Subject: [PATCH] Fix avatar crash --- Linphone/Contacts/ContactsManager.swift | 35 ++- Linphone/TelecomManager/TelecomManager.swift | 244 +++++++++--------- Linphone/UI/Call/CallView.swift | 112 +------- .../UI/Call/Fragments/CallsListFragment.swift | 57 +--- Linphone/UI/Call/Model/ParticipantModel.swift | 20 +- .../UI/Call/ViewModel/CallViewModel.swift | 160 +++++++----- .../MeetingWaitingRoomViewModel.swift | 119 ++++----- .../Contacts/Model/ContactAvatarModel.swift | 34 ++- .../Model/ConversationModel.swift | 155 +++++------ .../ViewModel/ConversationViewModel.swift | 8 +- .../ConversationsListViewModel.swift | 38 +-- .../UI/Main/History/Model/HistoryModel.swift | 42 +-- .../ViewModel/ScheduleMeetingViewModel.swift | 10 +- .../Viewmodel/AddParticipantsViewModel.swift | 4 +- Linphone/Utils/Avatar.swift | 2 +- 15 files changed, 499 insertions(+), 541 deletions(-) diff --git a/Linphone/Contacts/ContactsManager.swift b/Linphone/Contacts/ContactsManager.swift index c81f8c0dd..eba36a0be 100644 --- a/Linphone/Contacts/ContactsManager.swift +++ b/Linphone/Contacts/ContactsManager.swift @@ -302,21 +302,28 @@ final class ContactsManager: ObservableObject { } } - func getFriendWithAddress(address: Address) -> Friend? { - let clonedAddress = address.clone() - clonedAddress!.clean() - let sipUri = clonedAddress!.asStringUriOnly() - - if friendList != nil { - var friend: Friend? - friend = self.friendList!.friends.first(where: {$0.addresses.contains(where: {$0.asStringUriOnly() == sipUri})}) - if friend == nil { - friend = self.linphoneFriendList!.friends.first(where: {$0.addresses.contains(where: {$0.asStringUriOnly() == sipUri})}) + + func getFriendWithAddress(address: Address?, completion: @escaping (Friend?) -> Void) { + self.coreContext.doOnCoreQueue { core in + if address != nil { + let clonedAddress = address!.clone() + clonedAddress!.clean() + let sipUri = clonedAddress!.asStringUriOnly() + + if self.friendList != nil { + var friend: Friend? + friend = self.friendList!.friends.first(where: {$0.addresses.contains(where: {$0.asStringUriOnly() == sipUri})}) + if friend == nil { + friend = self.linphoneFriendList!.friends.first(where: {$0.addresses.contains(where: {$0.asStringUriOnly() == sipUri})}) + } + + completion(friend) + } else { + completion(nil) + } + } else { + completion(nil) } - - return friend - } else { - return nil } } } diff --git a/Linphone/TelecomManager/TelecomManager.swift b/Linphone/TelecomManager/TelecomManager.swift index f31aaf261..f28b4cf6a 100644 --- a/Linphone/TelecomManager/TelecomManager.swift +++ b/Linphone/TelecomManager/TelecomManager.swift @@ -340,20 +340,25 @@ class TelecomManager: ObservableObject { providerDelegate.reportIncomingCall(call: call, uuid: uuid, handle: handle, hasVideo: hasVideo, displayName: displayName) } - func incomingDisplayName(call: Call) -> String { - if call.remoteAddress != nil { - let friend = ContactsManager.shared.getFriendWithAddress(address: call.remoteAddress!) - if friend != nil && friend!.address != nil && friend!.address!.displayName != nil { - return friend!.address!.displayName! - } else { - if call.remoteAddress!.displayName != nil { - return call.remoteAddress!.displayName! - } else if call.remoteAddress!.username != nil { - return call.remoteAddress!.username! + + func incomingDisplayName(call: Call, completion: @escaping (String) -> Void) { + CoreContext.shared.doOnCoreQueue { core in + if call.remoteAddress != nil { + ContactsManager.shared.getFriendWithAddress(address: call.remoteAddress!) { friendResult in + let friend = friendResult + if friend != nil && friend!.address != nil && friend!.address!.displayName != nil { + completion(friend!.address!.displayName!) + } else { + if call.remoteAddress!.displayName != nil { + completion(call.remoteAddress!.displayName!) + } else if call.remoteAddress!.username != nil { + completion(call.remoteAddress!.username!) + } + } } } + completion("IncomingDisplayName") } - return "IncomingDisplayName" } static func callKitEnabled(core: Core) -> Bool { @@ -464,14 +469,16 @@ class TelecomManager: ObservableObject { if isRecordingByRemoteTmp && ToastViewModel.shared.toastMessage.isEmpty { var displayName = "" - let friend = ContactsManager.shared.getFriendWithAddress(address: call.remoteAddress!) - if friend != nil && friend!.address != nil && friend!.address!.displayName != nil { - displayName = friend!.address!.displayName! - } else { - if call.remoteAddress!.displayName != nil { - displayName = call.remoteAddress!.displayName! - } else if call.remoteAddress!.username != nil { - displayName = call.remoteAddress!.username! + ContactsManager.shared.getFriendWithAddress(address: call.remoteAddress!) { friendResult in + let friend = friendResult + if friend != nil && friend!.address != nil && friend!.address!.displayName != nil { + displayName = friend!.address!.displayName! + } else { + if call.remoteAddress!.displayName != nil { + displayName = call.remoteAddress!.displayName! + } else if call.remoteAddress!.username != nil { + displayName = call.remoteAddress!.username! + } } } @@ -526,67 +533,69 @@ class TelecomManager: ObservableObject { switch cstate { case .IncomingReceived: let addr = call.remoteAddress - let displayName = incomingDisplayName(call: call) -#if targetEnvironment(simulator) - DispatchQueue.main.async { - self.outgoingCallStarted = false - self.callStarted = false - if self.callInProgress == false { - withAnimation { - self.callInProgress = true - self.callDisplayed = true + incomingDisplayName(call: call) { displayNameResult in + let displayName = displayNameResult + #if targetEnvironment(simulator) + DispatchQueue.main.async { + self.outgoingCallStarted = false + self.callStarted = false + if self.callInProgress == false { + withAnimation { + self.callInProgress = true + self.callDisplayed = true + } } } + #endif + if call.replacedCall != nil { + self.endCallKitReplacedCall = false + + let uuid = self.providerDelegate.uuids["\(TelecomManager.uuidReplacedCall ?? "")"] + let callInfo = self.providerDelegate.callInfos[uuid!] + callInfo!.callId = self.referedToCall ?? "" + if callInfo != nil && uuid != nil && addr != nil { + self.providerDelegate.callInfos.updateValue(callInfo!, forKey: uuid!) + self.providerDelegate.uuids.removeValue(forKey: callId) + self.providerDelegate.uuids.updateValue(uuid!, forKey: callInfo!.callId) + self.providerDelegate.updateCall(uuid: uuid!, handle: addr!.asStringUriOnly(), hasVideo: self.remoteConfVideo, displayName: displayName) + } + } else if TelecomManager.callKitEnabled(core: core) { + /* + let isConference = isConferenceCall(call: call) + let isEarlyConference = isConference && CallsViewModel.shared.currentCallData.value??.isConferenceCall.value != true // Conference info not be received yet. + if (isEarlyConference) { + CallsViewModel.shared.currentCallData.readCurrentAndObserve { _ in + let uuid = providerDelegate.uuids["\(callId)"] + if (uuid != nil) { + displayName = "\(VoipTexts.conference_incoming_title): \(CallsViewModel.shared.currentCallData.value??.remoteConferenceSubject.value ?? "") (\(CallsViewModel.shared.currentCallData.value??.conferenceParticipantsCountLabel.value ?? ""))" + providerDelegate.updateCall(uuid: uuid!, handle: addr!.asStringUriOnly(), hasVideo: video, displayName: displayName) + } + } + } + */ + let uuid = self.providerDelegate.uuids["\(callId)"] + if call.replacedCall == nil { + TelecomManager.uuidReplacedCall = callId + } + + if uuid != nil { + // Tha app is now registered, updated the call already existed. + self.providerDelegate.updateCall(uuid: uuid!, handle: addr!.asStringUriOnly(), hasVideo: self.remoteConfVideo, displayName: displayName) + } else { + self.displayIncomingCall(call: call, handle: addr!.asStringUriOnly(), hasVideo: self.remoteConfVideo, callId: callId, displayName: displayName) + } + } /* else if UIApplication.shared.applicationState != .active { + // not support callkit , use notif + let content = UNMutableNotificationContent() + content.title = NSLocalizedString("Incoming call", comment: "") + content.body = displayName + content.sound = UNNotificationSound.init(named: UNNotificationSoundName.init("notes_of_the_optimistic.caf")) + content.categoryIdentifier = "call_cat" + content.userInfo = ["CallId": callId] + let req = UNNotificationRequest.init(identifier: "call_request", content: content, trigger: nil) + UNUserNotificationCenter.current().add(req, withCompletionHandler: nil) + } */ } -#endif - if call.replacedCall != nil { - endCallKitReplacedCall = false - - let uuid = providerDelegate.uuids["\(TelecomManager.uuidReplacedCall ?? "")"] - let callInfo = providerDelegate.callInfos[uuid!] - callInfo!.callId = referedToCall ?? "" - if callInfo != nil && uuid != nil && addr != nil { - providerDelegate.callInfos.updateValue(callInfo!, forKey: uuid!) - providerDelegate.uuids.removeValue(forKey: callId) - providerDelegate.uuids.updateValue(uuid!, forKey: callInfo!.callId) - providerDelegate.updateCall(uuid: uuid!, handle: addr!.asStringUriOnly(), hasVideo: remoteConfVideo, displayName: displayName) - } - } else if TelecomManager.callKitEnabled(core: core) { - /* - let isConference = isConferenceCall(call: call) - let isEarlyConference = isConference && CallsViewModel.shared.currentCallData.value??.isConferenceCall.value != true // Conference info not be received yet. - if (isEarlyConference) { - CallsViewModel.shared.currentCallData.readCurrentAndObserve { _ in - let uuid = providerDelegate.uuids["\(callId)"] - if (uuid != nil) { - displayName = "\(VoipTexts.conference_incoming_title): \(CallsViewModel.shared.currentCallData.value??.remoteConferenceSubject.value ?? "") (\(CallsViewModel.shared.currentCallData.value??.conferenceParticipantsCountLabel.value ?? ""))" - providerDelegate.updateCall(uuid: uuid!, handle: addr!.asStringUriOnly(), hasVideo: video, displayName: displayName) - } - } - } - */ - let uuid = providerDelegate.uuids["\(callId)"] - if call.replacedCall == nil { - TelecomManager.uuidReplacedCall = callId - } - - if uuid != nil { - // Tha app is now registered, updated the call already existed. - providerDelegate.updateCall(uuid: uuid!, handle: addr!.asStringUriOnly(), hasVideo: remoteConfVideo, displayName: displayName) - } else { - displayIncomingCall(call: call, handle: addr!.asStringUriOnly(), hasVideo: remoteConfVideo, callId: callId, displayName: displayName) - } - } /* else if UIApplication.shared.applicationState != .active { - // not support callkit , use notif - let content = UNMutableNotificationContent() - content.title = NSLocalizedString("Incoming call", comment: "") - content.body = displayName - content.sound = UNNotificationSound.init(named: UNNotificationSoundName.init("notes_of_the_optimistic.caf")) - content.categoryIdentifier = "call_cat" - content.userInfo = ["CallId": callId] - let req = UNNotificationRequest.init(identifier: "call_request", content: content, trigger: nil) - UNUserNotificationCenter.current().add(req, withCompletionHandler: nil) - } */ case .StreamsRunning: if TelecomManager.callKitEnabled(core: core) { @@ -660,52 +669,53 @@ class TelecomManager: ObservableObject { } //if core.callsNb == 0 { - DispatchQueue.main.async { - if core.callsNb == 0 { - do { - try core.setVideodevice(newValue: "AV Capture: com.apple.avfoundation.avcapturedevice.built-in_video:1") - } catch _ { - - } - withAnimation { - self.outgoingCallStarted = false - self.callInProgress = false - self.callDisplayed = false - self.callStarted = false - self.callConnected = false - } - } else { - if core.calls.last != nil { - self.setHeld(call: core.calls.last!, hold: false) - - DispatchQueue.main.asyncAfter(deadline: .now() + 1) { - self.remainingCall = true - DispatchQueue.main.asyncAfter(deadline: .now() + 1) { - self.remainingCall = false - } - } - } - } - + self.incomingDisplayName(call: call) { displayNameResult in var displayName = "Unknown" if call.dir == .Incoming { - displayName = self.incomingDisplayName(call: call) + displayName = displayNameResult } else { // if let addr = call.remoteAddress, let contactName = FastAddressBook.displayName(for: addr.getCobject) { displayName = "TODOContactName" } - - if UIApplication.shared.applicationState != .active && (callLog == nil || callLog?.status == .Missed || callLog?.status == .Aborted || callLog?.status == .EarlyAborted) { - // Configure the notification's payload. - let content = UNMutableNotificationContent() - content.title = NSString.localizedUserNotificationString(forKey: NSLocalizedString("Missed call", comment: ""), arguments: nil) - content.body = NSString.localizedUserNotificationString(forKey: displayName, arguments: nil) + DispatchQueue.main.async { + if core.callsNb == 0 { + do { + try core.setVideodevice(newValue: "AV Capture: com.apple.avfoundation.avcapturedevice.built-in_video:1") + } catch _ { + + } + withAnimation { + self.outgoingCallStarted = false + self.callInProgress = false + self.callDisplayed = false + self.callStarted = false + self.callConnected = false + } + } else { + if core.calls.last != nil { + self.setHeld(call: core.calls.last!, hold: false) + + DispatchQueue.main.asyncAfter(deadline: .now() + 1) { + self.remainingCall = true + DispatchQueue.main.asyncAfter(deadline: .now() + 1) { + self.remainingCall = false + } + } + } + } - // Deliver the notification. - let request = UNNotificationRequest(identifier: "call_request", content: content, trigger: nil) // Schedule the notification. - let center = UNUserNotificationCenter.current() - center.add(request) { (error: Error?) in - if error != nil { - Log.info("Error while adding notification request : \(error!.localizedDescription)") + if UIApplication.shared.applicationState != .active && (callLog == nil || callLog?.status == .Missed || callLog?.status == .Aborted || callLog?.status == .EarlyAborted) { + // Configure the notification's payload. + let content = UNMutableNotificationContent() + content.title = NSString.localizedUserNotificationString(forKey: NSLocalizedString("Missed call", comment: ""), arguments: nil) + content.body = NSString.localizedUserNotificationString(forKey: displayName, arguments: nil) + + // Deliver the notification. + let request = UNNotificationRequest(identifier: "call_request", content: content, trigger: nil) // Schedule the notification. + let center = UNUserNotificationCenter.current() + center.add(request) { (error: Error?) in + if error != nil { + Log.info("Error while adding notification request : \(error!.localizedDescription)") + } } } } diff --git a/Linphone/UI/Call/CallView.swift b/Linphone/UI/Call/CallView.swift index 5d89945f1..82cdad0fe 100644 --- a/Linphone/UI/Call/CallView.swift +++ b/Linphone/UI/Call/CallView.swift @@ -368,49 +368,8 @@ struct CallView: View { .frame(width: 206, height: 206) } - if callViewModel.remoteAddress != nil { - let addressFriend = contactsManager.getFriendWithAddress(address: callViewModel.remoteAddress!) - - let contactAvatarModel = addressFriend != nil - ? ContactsManager.shared.avatarListModel.first(where: { - ($0.friend!.consolidatedPresence == .Online || $0.friend!.consolidatedPresence == .Busy) - && $0.friend!.name == addressFriend!.name - && $0.friend!.address!.asStringUriOnly() == addressFriend!.address!.asStringUriOnly() - }) - : ContactAvatarModel(friend: nil, name: "", address: "", withPresence: false) - - if addressFriend != nil && addressFriend!.photo != nil && !addressFriend!.photo!.isEmpty { - if contactAvatarModel != nil { - Avatar(contactAvatarModel: contactAvatarModel!, avatarSize: 200, hidePresence: true) - } - } else { - if callViewModel.remoteAddress!.displayName != nil { - Image(uiImage: contactsManager.textToImage( - firstName: callViewModel.remoteAddress!.displayName!, - lastName: callViewModel.remoteAddress!.displayName!.components(separatedBy: " ").count > 1 - ? callViewModel.remoteAddress!.displayName!.components(separatedBy: " ")[1] - : "")) - .resizable() - .frame(width: 200, height: 200) - .clipShape(Circle()) - - } else { - Image(uiImage: contactsManager.textToImage( - firstName: callViewModel.remoteAddress!.username ?? "Username Error", - lastName: callViewModel.remoteAddress!.username!.components(separatedBy: " ").count > 1 - ? callViewModel.remoteAddress!.username!.components(separatedBy: " ")[1] - : "")) - .resizable() - .frame(width: 200, height: 200) - .clipShape(Circle()) - } - - } - } else { - Image("profil-picture-default") - .resizable() - .frame(width: 200, height: 200) - .clipShape(Circle()) + if callViewModel.avatarModel != nil { + Avatar(contactAvatarModel: callViewModel.avatarModel!, avatarSize: 200, hidePresence: true) } if callViewModel.isRemoteDeviceTrusted { @@ -722,66 +681,13 @@ struct CallView: View { VStack { Spacer() HStack { - ZStack { - if callViewModel.activeSpeakerParticipant?.address != nil { - let addressFriend = contactsManager.getFriendWithAddress(address: callViewModel.activeSpeakerParticipant!.address) - - let contactAvatarModel = addressFriend != nil - ? ContactsManager.shared.avatarListModel.first(where: { - ($0.friend!.consolidatedPresence == .Online || $0.friend!.consolidatedPresence == .Busy) - && $0.friend!.name == addressFriend!.name - && $0.friend!.address!.asStringUriOnly() == addressFriend!.address!.asStringUriOnly() - }) - : ContactAvatarModel(friend: nil, name: "", address: "", withPresence: false) - - if addressFriend != nil && addressFriend!.photo != nil && !addressFriend!.photo!.isEmpty { - if contactAvatarModel != nil { - Avatar(contactAvatarModel: contactAvatarModel!, avatarSize: 200, hidePresence: true) - .onAppear { - DispatchQueue.main.asyncAfter(deadline: .now() + 1) { - displayVideo = true - } - } - } - } else { - if callViewModel.activeSpeakerParticipant!.address.displayName != nil { - Image(uiImage: contactsManager.textToImage( - firstName: callViewModel.activeSpeakerParticipant!.address.displayName!, - lastName: callViewModel.activeSpeakerParticipant!.address.displayName!.components(separatedBy: " ").count > 1 - ? callViewModel.activeSpeakerParticipant!.address.displayName!.components(separatedBy: " ")[1] - : "")) - .resizable() - .frame(width: 200, height: 200) - .clipShape(Circle()) - .onAppear { - DispatchQueue.main.asyncAfter(deadline: .now() + 1) { - displayVideo = true - } - } - - } else { - Image(uiImage: contactsManager.textToImage( - firstName: callViewModel.activeSpeakerParticipant!.address.username ?? "Username Error", - lastName: callViewModel.activeSpeakerParticipant!.address.username!.components(separatedBy: " ").count > 1 - ? callViewModel.activeSpeakerParticipant!.address.username!.components(separatedBy: " ")[1] - : "")) - .resizable() - .frame(width: 200, height: 200) - .clipShape(Circle()) - .onAppear { - DispatchQueue.main.asyncAfter(deadline: .now() + 1) { - displayVideo = true - } - } - } - - } - } else { - Image("profil-picture-default") - .resizable() - .frame(width: 200, height: 200) - .clipShape(Circle()) - } + if callViewModel.activeSpeakerParticipant != nil { + Avatar(contactAvatarModel: callViewModel.activeSpeakerParticipant!.avatarModel, avatarSize: 200, hidePresence: true) + .onAppear { + DispatchQueue.main.asyncAfter(deadline: .now() + 1) { + displayVideo = true + } + } } } diff --git a/Linphone/UI/Call/Fragments/CallsListFragment.swift b/Linphone/UI/Call/Fragments/CallsListFragment.swift index d80560e0c..171f11696 100644 --- a/Linphone/UI/Call/Fragments/CallsListFragment.swift +++ b/Linphone/UI/Call/Fragments/CallsListFragment.swift @@ -218,57 +218,28 @@ struct CallsListFragment: View { HStack { HStack { if callViewModel.calls[index].callLog != nil && callViewModel.calls[index].callLog!.remoteAddress != nil { - let addressFriend = contactsManager.getFriendWithAddress(address: callViewModel.calls[index].callLog!.remoteAddress!) - - let contactAvatarModel = addressFriend != nil - ? ContactsManager.shared.avatarListModel.first(where: { - ($0.friend!.consolidatedPresence == .Online || $0.friend!.consolidatedPresence == .Busy) - && $0.friend!.name == addressFriend!.name - && $0.friend!.address!.asStringUriOnly() == addressFriend!.address!.asStringUriOnly() - }) - : ContactAvatarModel(friend: nil, name: "", address: "", withPresence: false) - - if addressFriend != nil && addressFriend!.photo != nil && !addressFriend!.photo!.isEmpty { - if contactAvatarModel != nil { - Avatar(contactAvatarModel: contactAvatarModel!, avatarSize: 50) - } else { - Image("profil-picture-default") - .resizable() - .frame(width: 50, height: 50) - .clipShape(Circle()) - } + if callViewModel.callsContactAvatarModel[index] != nil && callViewModel.calls[index].callLog?.conferenceInfo == nil { + Avatar(contactAvatarModel: callViewModel.callsContactAvatarModel[index]!, avatarSize: 50) } else { - if callViewModel.calls[index].callLog!.remoteAddress!.displayName != nil { - Image(uiImage: contactsManager.textToImage( - firstName: callViewModel.calls[index].callLog!.remoteAddress!.displayName!, - lastName: callViewModel.calls[index].callLog!.remoteAddress!.displayName!.components(separatedBy: " ").count > 1 - ? callViewModel.calls[index].callLog!.remoteAddress!.displayName!.components(separatedBy: " ")[1] - : "")) - .resizable() - .frame(width: 50, height: 50) - .clipShape(Circle()) - - } else { - Image(uiImage: contactsManager.textToImage( - firstName: callViewModel.calls[index].callLog!.remoteAddress!.username ?? "Username Error", - lastName: callViewModel.calls[index].callLog!.remoteAddress!.username!.components(separatedBy: " ").count > 1 - ? callViewModel.calls[index].callLog!.remoteAddress!.username!.components(separatedBy: " ")[1] - : "")) - .resizable() - .frame(width: 50, height: 50) - .clipShape(Circle()) + VStack { + Image("users-three-square") + .renderingMode(.template) + .resizable() + .frame(width: 28, height: 28) + .foregroundStyle(Color.grayMain2c600) } + .frame(width: 50, height: 50) + .background(Color.grayMain2c200) + .clipShape(Circle()) } - if addressFriend != nil { - Text(addressFriend!.name!) + if callViewModel.calls[index].callLog?.conferenceInfo == nil { + Text(callViewModel.callsContactAvatarModel[index]!.name) .default_text_style(styleSize: 16) .frame(maxWidth: .infinity, alignment: .leading) .lineLimit(1) } else { - Text(callViewModel.calls[index].callLog!.remoteAddress!.displayName != nil - ? callViewModel.calls[index].callLog!.remoteAddress!.displayName! - : callViewModel.calls[index].callLog!.remoteAddress!.username!) + Text(callViewModel.calls[index].callLog!.conferenceInfo!.subject ?? "Conference Name error") .default_text_style(styleSize: 16) .frame(maxWidth: .infinity, alignment: .leading) .lineLimit(1) diff --git a/Linphone/UI/Call/Model/ParticipantModel.swift b/Linphone/UI/Call/Model/ParticipantModel.swift index 0a1ec61d4..921fe079e 100644 --- a/Linphone/UI/Call/Model/ParticipantModel.swift +++ b/Linphone/UI/Call/Model/ParticipantModel.swift @@ -39,18 +39,26 @@ class ParticipantModel: ObservableObject { self.sipUri = address.asStringUriOnly() - if let addressFriend = ContactsManager.shared.getFriendWithAddress(address: self.address) { - self.name = addressFriend.name! - } else { - self.name = address.displayName != nil ? address.displayName! : address.username! - } + self.name = "" - self.avatarModel = ContactAvatarModel.getAvatarModelFromAddress(address: self.address) + self.avatarModel = ContactAvatarModel(friend: nil, name: "", address: address.asStringUriOnly(), withPresence: false) self.isJoining = isJoining self.onPause = onPause self.isMuted = isMuted self.isAdmin = isAdmin self.isSpeaking = isSpeaking + + ContactsManager.shared.getFriendWithAddress(address: self.address) { friendResult in + if let addressFriend = friendResult { + self.name = addressFriend.name! + } else { + self.name = address.displayName != nil ? address.displayName! : address.username! + } + } + + ContactAvatarModel.getAvatarModelFromAddress(address: self.address) { avatarResult in + self.avatarModel = avatarResult + } } } diff --git a/Linphone/UI/Call/ViewModel/CallViewModel.swift b/Linphone/UI/Call/ViewModel/CallViewModel.swift index 605868fdc..65834b7f6 100644 --- a/Linphone/UI/Call/ViewModel/CallViewModel.swift +++ b/Linphone/UI/Call/ViewModel/CallViewModel.swift @@ -62,6 +62,7 @@ class CallViewModel: ObservableObject { private var mConferenceSuscriptions = Set() @Published var calls: [Call] = [] + @Published var callsContactAvatarModel: [ContactAvatarModel?] = [] let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect() @@ -137,14 +138,25 @@ class CallViewModel: ObservableObject { if self.currentCall?.conference != nil { displayNameTmp = self.currentCall?.conference?.subject ?? "" } else if self.currentCall?.remoteAddress != nil { - let friend = ContactsManager.shared.getFriendWithAddress(address: self.currentCall!.remoteAddress!) - if friend != nil && friend!.address != nil && friend!.address!.displayName != nil { - displayNameTmp = friend!.address!.displayName! - } else { - if self.currentCall!.remoteAddress!.displayName != nil { - displayNameTmp = self.currentCall!.remoteAddress!.displayName! - } else if self.currentCall!.remoteAddress!.username != nil { - displayNameTmp = self.currentCall!.remoteAddress!.username! + ContactsManager.shared.getFriendWithAddress(address: self.currentCall!.remoteAddress) { friendResult in + let friend = friendResult + if friend != nil && friend!.address != nil && friend!.address!.displayName != nil { + displayNameTmp = friend!.address!.displayName! + } else { + if self.currentCall!.remoteAddress!.displayName != nil { + displayNameTmp = self.currentCall!.remoteAddress!.displayName! + } else if self.currentCall!.remoteAddress!.username != nil { + displayNameTmp = self.currentCall!.remoteAddress!.username! + } + } + DispatchQueue.main.async { + self.displayName = displayNameTmp + } + } + + ContactAvatarModel.getAvatarModelFromAddress(address: self.currentCall!.remoteAddress!) { avatarResult in + DispatchQueue.main.async { + self.avatarModel = avatarResult } } } @@ -171,7 +183,6 @@ class CallViewModel: ObservableObject { self.remoteAddress = remoteAddressTmp self.displayName = displayNameTmp - //self.avatarModel = ??? self.micMutted = micMuttedTmp self.isRecording = isRecordingTmp self.isPaused = isPausedTmp @@ -224,9 +235,17 @@ class CallViewModel: ObservableObject { } func getCallsList() { + self.callsContactAvatarModel.removeAll() + self.calls.removeAll() coreContext.doOnCoreQueue { core in - DispatchQueue.main.async { - self.calls = core.calls + let callsTmp = core.calls + callsTmp.forEach { call in + ContactAvatarModel.getAvatarModelFromAddress(address: call.callLog!.remoteAddress!) { avatarResult in + DispatchQueue.main.async { + self.callsContactAvatarModel.append(avatarResult) + self.calls.append(call) + } + } } } } @@ -272,14 +291,16 @@ class CallViewModel: ObservableObject { var activeSpeakerNameTmp = "" if activeSpeakerParticipantTmp != nil { - let friend = ContactsManager.shared.getFriendWithAddress(address: activeSpeakerParticipantTmp!.address) - if friend != nil && friend!.address != nil && friend!.address!.displayName != nil { - activeSpeakerNameTmp = friend!.address!.displayName! - } else { - if activeSpeakerParticipantTmp!.address.displayName != nil { - activeSpeakerNameTmp = activeSpeakerParticipantTmp!.address.displayName! - } else if activeSpeakerParticipantTmp!.address.username != nil { - activeSpeakerNameTmp = activeSpeakerParticipantTmp!.address.username! + ContactsManager.shared.getFriendWithAddress(address: activeSpeakerParticipantTmp?.address) { friendResult in + let friend = friendResult + if friend != nil && friend!.address != nil && friend!.address!.displayName != nil { + activeSpeakerNameTmp = friend!.address!.displayName! + } else { + if activeSpeakerParticipantTmp!.address.displayName != nil { + activeSpeakerNameTmp = activeSpeakerParticipantTmp!.address.displayName! + } else if activeSpeakerParticipantTmp!.address.username != nil { + activeSpeakerNameTmp = activeSpeakerParticipantTmp!.address.username! + } } } } @@ -346,46 +367,48 @@ class CallViewModel: ObservableObject { isMuted: cbValue.participantDevice.isMuted ) - var activeSpeakerNameTmp = "" - let friend = ContactsManager.shared.getFriendWithAddress(address: activeSpeakerParticipantTmp.address) - if friend != nil && friend!.address != nil && friend!.address!.displayName != nil { - activeSpeakerNameTmp = friend!.address!.displayName! - } else { - if activeSpeakerParticipantTmp.address.displayName != nil { - activeSpeakerNameTmp = activeSpeakerParticipantTmp.address.displayName! - } else if activeSpeakerParticipantTmp.address.username != nil { - activeSpeakerNameTmp = activeSpeakerParticipantTmp.address.username! - } - } - - var participantListTmp: [ParticipantModel] = [] - if (activeSpeakerParticipantBis != nil && !activeSpeakerParticipantBis!.address.equal(address2: activeSpeakerParticipantTmp.address)) - || ( activeSpeakerParticipantBis == nil) { - - cbValue.conference.participantDeviceList.forEach({ participantDevice in - if participantDevice.address != nil && !cbValue.conference.isMe(uri: participantDevice.address!.clone()!) { - if !cbValue.conference.isMe(uri: participantDevice.address!.clone()!) { - let isAdmin = cbValue.conference.participantList.first(where: {$0.address!.equal(address2: participantDevice.address!.clone()!)})?.isAdmin - participantListTmp.append( - ParticipantModel( - address: participantDevice.address!, - isJoining: participantDevice.state == .Joining || participantDevice.state == .Alerting, - onPause: participantDevice.state == .OnHold, - isMuted: participantDevice.isMuted, - isAdmin: isAdmin ?? false - ) - ) - } + ContactsManager.shared.getFriendWithAddress(address: activeSpeakerParticipantTmp.address) { friendResult in + var activeSpeakerNameTmp = "" + let friend = friendResult + if friend != nil && friend!.address != nil && friend!.address!.displayName != nil { + activeSpeakerNameTmp = friend!.address!.displayName! + } else { + if activeSpeakerParticipantTmp.address.displayName != nil { + activeSpeakerNameTmp = activeSpeakerParticipantTmp.address.displayName! + } else if activeSpeakerParticipantTmp.address.username != nil { + activeSpeakerNameTmp = activeSpeakerParticipantTmp.address.username! } - }) - } - - DispatchQueue.main.async { - self.activeSpeakerParticipant = activeSpeakerParticipantTmp - self.activeSpeakerName = activeSpeakerNameTmp + } + + var participantListTmp: [ParticipantModel] = [] if (activeSpeakerParticipantBis != nil && !activeSpeakerParticipantBis!.address.equal(address2: activeSpeakerParticipantTmp.address)) - || ( activeSpeakerParticipantBis == nil) { - self.participantList = participantListTmp + || ( activeSpeakerParticipantBis == nil) { + + cbValue.conference.participantDeviceList.forEach({ participantDevice in + if participantDevice.address != nil && !cbValue.conference.isMe(uri: participantDevice.address!.clone()!) { + if !cbValue.conference.isMe(uri: participantDevice.address!.clone()!) { + let isAdmin = cbValue.conference.participantList.first(where: {$0.address!.equal(address2: participantDevice.address!.clone()!)})?.isAdmin + participantListTmp.append( + ParticipantModel( + address: participantDevice.address!, + isJoining: participantDevice.state == .Joining || participantDevice.state == .Alerting, + onPause: participantDevice.state == .OnHold, + isMuted: participantDevice.isMuted, + isAdmin: isAdmin ?? false + ) + ) + } + } + }) + } + + DispatchQueue.main.async { + self.activeSpeakerParticipant = activeSpeakerParticipantTmp + self.activeSpeakerName = activeSpeakerNameTmp + if (activeSpeakerParticipantBis != nil && !activeSpeakerParticipantBis!.address.equal(address2: activeSpeakerParticipantTmp.address)) + || ( activeSpeakerParticipantBis == nil) { + self.participantList = participantListTmp + } } } } @@ -441,14 +464,21 @@ class CallViewModel: ObservableObject { } if activeSpeakerParticipantTmp != nil { - let friend = ContactsManager.shared.getFriendWithAddress(address: activeSpeakerParticipantTmp!.address) - if friend != nil && friend!.address != nil && friend!.address!.displayName != nil { - activeSpeakerNameTmp = friend!.address!.displayName! - } else { - if activeSpeakerParticipantTmp!.address.displayName != nil { - activeSpeakerNameTmp = activeSpeakerParticipantTmp!.address.displayName! - } else if activeSpeakerParticipantTmp!.address.username != nil { - activeSpeakerNameTmp = activeSpeakerParticipantTmp!.address.username! + ContactsManager.shared.getFriendWithAddress(address: activeSpeakerParticipantTmp?.address) { friendResult in + let friend = friendResult + if friend != nil && friend!.address != nil && friend!.address!.displayName != nil { + activeSpeakerNameTmp = friend!.address!.displayName! + } else { + if activeSpeakerParticipantTmp!.address.displayName != nil { + activeSpeakerNameTmp = activeSpeakerParticipantTmp!.address.displayName! + } else if activeSpeakerParticipantTmp!.address.username != nil { + activeSpeakerNameTmp = activeSpeakerParticipantTmp!.address.username! + } + } + DispatchQueue.main.async { + if self.activeSpeakerParticipant == nil { + self.activeSpeakerName = activeSpeakerNameTmp + } } } } diff --git a/Linphone/UI/Call/ViewModel/MeetingWaitingRoomViewModel.swift b/Linphone/UI/Call/ViewModel/MeetingWaitingRoomViewModel.swift index 681096d73..ec0eaf252 100644 --- a/Linphone/UI/Call/ViewModel/MeetingWaitingRoomViewModel.swift +++ b/Linphone/UI/Call/ViewModel/MeetingWaitingRoomViewModel.swift @@ -64,68 +64,69 @@ class MeetingWaitingRoomViewModel: ObservableObject { let confNameTmp = conf?.subject ?? "Conference" var userNameTmp = "" - let friend = core.defaultAccount != nil && core.defaultAccount!.contactAddress != nil - ? ContactsManager.shared.getFriendWithAddress(address: core.defaultAccount!.contactAddress!) - : nil - - let addressTmp = friend?.address?.asStringUriOnly() ?? "" - - if friend != nil && friend!.address != nil && friend!.address!.displayName != nil { - userNameTmp = friend!.address!.displayName! - } else { - if core.defaultAccount!.contactAddress!.displayName != nil { - userNameTmp = core.defaultAccount!.contactAddress!.displayName! - } else if core.defaultAccount!.contactAddress!.username != nil { - userNameTmp = core.defaultAccount!.contactAddress!.username! - } - } - - let avatarModelTmp = friend != nil - ? ContactsManager.shared.avatarListModel.first(where: { - $0.friend!.name == friend!.name - && $0.friend!.address!.asStringUriOnly() == core.defaultAccount!.contactAddress!.asStringUriOnly() - }) ?? ContactAvatarModel(friend: nil, name: userNameTmp, address: addressTmp, withPresence: false) - : ContactAvatarModel(friend: nil, name: userNameTmp, address: addressTmp, withPresence: false) - - if core.videoEnabled && !core.videoPreviewEnabled { - DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { - core.videoPreviewEnabled = true - self.videoDisplayed = true - } - } - - core.micEnabled = true - - let micMuttedTmp = !core.micEnabled - - let timeInterval = TimeInterval(conf!.dateTime) - let date = Date(timeIntervalSince1970: timeInterval) - let dateFormatter = DateFormatter() - dateFormatter.dateStyle = .full - dateFormatter.timeStyle = .none - let dateTmp = dateFormatter.string(from: date) - - let timeFormatter = DateFormatter() - timeFormatter.dateFormat = Locale.current.identifier == "fr_FR" ? "HH:mm" : "h:mm a" - let timeTmp = timeFormatter.string(from: date) - - let timeBisInterval = TimeInterval(conf!.dateTime + (Int(conf!.duration) * 60)) - let timeBis = Date(timeIntervalSince1970: timeBisInterval) - let timeBisTmp = timeFormatter.string(from: timeBis) - - let meetingDateTmp = "\(dateTmp) | \(timeTmp) - \(timeBisTmp)" - - DispatchQueue.main.async { - if self.telecomManager.meetingWaitingRoomName.isEmpty || self.telecomManager.meetingWaitingRoomName != confNameTmp { - self.telecomManager.meetingWaitingRoomName = confNameTmp + ContactsManager.shared.getFriendWithAddress(address: core.defaultAccount?.contactAddress) { friendResult in + let friend = core.defaultAccount != nil && core.defaultAccount!.contactAddress != nil + ? friendResult + : nil + + let addressTmp = friend?.address?.asStringUriOnly() ?? "" + + if friend != nil && friend!.address != nil && friend!.address!.displayName != nil { + userNameTmp = friend!.address!.displayName! + } else { + if core.defaultAccount!.contactAddress!.displayName != nil { + userNameTmp = core.defaultAccount!.contactAddress!.displayName! + } else if core.defaultAccount!.contactAddress!.username != nil { + userNameTmp = core.defaultAccount!.contactAddress!.username! + } } - self.userName = userNameTmp - self.avatarModel = avatarModelTmp - self.micMutted = micMuttedTmp - self.meetingDate = meetingDateTmp + let avatarModelTmp = friend != nil + ? ContactsManager.shared.avatarListModel.first(where: { + $0.friend!.name == friend!.name + && $0.friend!.address!.asStringUriOnly() == core.defaultAccount!.contactAddress!.asStringUriOnly() + }) ?? ContactAvatarModel(friend: nil, name: userNameTmp, address: addressTmp, withPresence: false) + : ContactAvatarModel(friend: nil, name: userNameTmp, address: addressTmp, withPresence: false) + + if core.videoEnabled && !core.videoPreviewEnabled { + DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { + core.videoPreviewEnabled = true + self.videoDisplayed = true + } + } + + core.micEnabled = true + + let micMuttedTmp = !core.micEnabled + + let timeInterval = TimeInterval(conf!.dateTime) + let date = Date(timeIntervalSince1970: timeInterval) + let dateFormatter = DateFormatter() + dateFormatter.dateStyle = .full + dateFormatter.timeStyle = .none + let dateTmp = dateFormatter.string(from: date) + + let timeFormatter = DateFormatter() + timeFormatter.dateFormat = Locale.current.identifier == "fr_FR" ? "HH:mm" : "h:mm a" + let timeTmp = timeFormatter.string(from: date) + + let timeBisInterval = TimeInterval(conf!.dateTime + (Int(conf!.duration) * 60)) + let timeBis = Date(timeIntervalSince1970: timeBisInterval) + let timeBisTmp = timeFormatter.string(from: timeBis) + + let meetingDateTmp = "\(dateTmp) | \(timeTmp) - \(timeBisTmp)" + + DispatchQueue.main.async { + if self.telecomManager.meetingWaitingRoomName.isEmpty || self.telecomManager.meetingWaitingRoomName != confNameTmp { + self.telecomManager.meetingWaitingRoomName = confNameTmp + } + + self.userName = userNameTmp + self.avatarModel = avatarModelTmp + self.micMutted = micMuttedTmp + self.meetingDate = meetingDateTmp + } } - } } } diff --git a/Linphone/UI/Main/Contacts/Model/ContactAvatarModel.swift b/Linphone/UI/Main/Contacts/Model/ContactAvatarModel.swift index e7b1d297b..9236d41df 100644 --- a/Linphone/UI/Main/Contacts/Model/ContactAvatarModel.swift +++ b/Linphone/UI/Main/Contacts/Model/ContactAvatarModel.swift @@ -117,20 +117,28 @@ class ContactAvatarModel: ObservableObject { } } - static func getAvatarModelFromAddress(address: Address) -> ContactAvatarModel { - if let addressFriend = ContactsManager.shared.getFriendWithAddress(address: address) { - var avatarModel = ContactsManager.shared.avatarListModel.first(where: { - $0.friend!.name == addressFriend.name - && $0.friend!.address!.asStringUriOnly() == address.asStringUriOnly() - }) - - if avatarModel == nil { - avatarModel = ContactAvatarModel(friend: nil, name: addressFriend.name!, address: address.asStringUriOnly(), withPresence: false) + + static func getAvatarModelFromAddress(address: Address, completion: @escaping (ContactAvatarModel) -> Void) { + ContactsManager.shared.getFriendWithAddress(address: address) { resultFriend in + if let addressFriend = resultFriend { + if addressFriend.address != nil { + var avatarModel = ContactsManager.shared.avatarListModel.first(where: { + $0.friend!.name == addressFriend.name + && $0.friend!.address!.asStringUriOnly() == addressFriend.address!.asStringUriOnly() + }) + + if avatarModel == nil { + avatarModel = ContactAvatarModel(friend: nil, name: addressFriend.name!, address: addressFriend.address!.asStringUriOnly(), withPresence: false) + } + completion(avatarModel!) + } else { + let name = address.displayName != nil ? address.displayName! : address.username! + completion(ContactAvatarModel(friend: nil, name: name, address: address.asStringUriOnly(), withPresence: false)) + } + } else { + let name = address.displayName != nil ? address.displayName! : address.username! + completion(ContactAvatarModel(friend: nil, name: name, address: address.asStringUriOnly(), withPresence: false)) } - return avatarModel! - } else { - let name = address.displayName != nil ? address.displayName! : address.username! - return ContactAvatarModel(friend: nil, name: name, address: address.asStringUriOnly(), withPresence: false) } } } diff --git a/Linphone/UI/Main/Conversations/Model/ConversationModel.swift b/Linphone/UI/Main/Conversations/Model/ConversationModel.swift index 24544bb50..439e22fa9 100644 --- a/Linphone/UI/Main/Conversations/Model/ConversationModel.swift +++ b/Linphone/UI/Main/Conversations/Model/ConversationModel.swift @@ -137,40 +137,42 @@ class ConversationModel: ObservableObject { coreContext.doOnCoreQueue { _ in let lastMessage = self.chatRoom.lastMessageInHistory if lastMessage != nil { - var fromAddressFriend = lastMessage!.fromAddress != nil - ? self.contactsManager.getFriendWithAddress(address: lastMessage!.fromAddress!)?.name ?? nil - : nil - - if !lastMessage!.isOutgoing && lastMessage!.chatRoom != nil && !lastMessage!.chatRoom!.hasCapability(mask: ChatRoom.Capabilities.OneToOne.rawValue) { - if fromAddressFriend == nil { - if lastMessage!.fromAddress!.displayName != nil { - fromAddressFriend = lastMessage!.fromAddress!.displayName! + ": " - } else if lastMessage!.fromAddress!.username != nil { - fromAddressFriend = lastMessage!.fromAddress!.username! + ": " + self.contactsManager.getFriendWithAddress(address: lastMessage!.fromAddress) { friendResult in + var fromAddressFriend = lastMessage!.fromAddress != nil + ? friendResult?.name ?? nil + : nil + + if !lastMessage!.isOutgoing && lastMessage!.chatRoom != nil && !lastMessage!.chatRoom!.hasCapability(mask: ChatRoom.Capabilities.OneToOne.rawValue) { + if fromAddressFriend == nil { + if lastMessage!.fromAddress!.displayName != nil { + fromAddressFriend = lastMessage!.fromAddress!.displayName! + ": " + } else if lastMessage!.fromAddress!.username != nil { + fromAddressFriend = lastMessage!.fromAddress!.username! + ": " + } else { + fromAddressFriend = "" + } } else { - fromAddressFriend = "" + fromAddressFriend! += ": " } + } else { - fromAddressFriend! += ": " + fromAddressFriend = nil } - } else { - fromAddressFriend = nil - } - - let lastMessageTextTmp = (fromAddressFriend ?? "") - + (lastMessage!.contents.first(where: {$0.isText == true})?.utf8Text ?? (lastMessage!.contents.first(where: {$0.isFile == true || $0.isFileTransfer == true})?.name ?? "")) - - let lastMessageIsOutgoingTmp = lastMessage?.isOutgoing ?? false - - let lastMessageStateTmp = lastMessage?.state.rawValue ?? 0 - - DispatchQueue.main.async { - self.lastMessageText = lastMessageTextTmp + let lastMessageTextTmp = (fromAddressFriend ?? "") + + (lastMessage!.contents.first(where: {$0.isText == true})?.utf8Text ?? (lastMessage!.contents.first(where: {$0.isFile == true || $0.isFileTransfer == true})?.name ?? "")) - self.lastMessageIsOutgoing = lastMessageIsOutgoingTmp + let lastMessageIsOutgoingTmp = lastMessage?.isOutgoing ?? false - self.lastMessageState = lastMessageStateTmp + let lastMessageStateTmp = lastMessage?.state.rawValue ?? 0 + + DispatchQueue.main.async { + self.lastMessageText = lastMessageTextTmp + + self.lastMessageIsOutgoing = lastMessageIsOutgoingTmp + + self.lastMessageState = lastMessageStateTmp + } } } } @@ -178,49 +180,50 @@ class ConversationModel: ObservableObject { func getChatRoomSubject() { coreContext.doOnCoreQueue { _ in - - let addressFriend = - (self.chatRoom.participants.first != nil && self.chatRoom.participants.first!.address != nil) - ? self.contactsManager.getFriendWithAddress(address: self.chatRoom.participants.first!.address!) - : nil - - if self.isGroup { - self.subject = self.chatRoom.subject! - } else if addressFriend != nil { - self.subject = addressFriend!.name! - } else { - if self.chatRoom.participants.first != nil - && self.chatRoom.participants.first!.address != nil { - - self.subject = self.chatRoom.participants.first!.address!.displayName != nil - ? self.chatRoom.participants.first!.address!.displayName! - : self.chatRoom.participants.first!.address!.username! - + self.contactsManager.getFriendWithAddress(address: self.chatRoom.participants.first?.address) { friendResult in + let addressFriend = + (self.chatRoom.participants.first != nil && self.chatRoom.participants.first!.address != nil) + ? friendResult + : nil + + if self.isGroup { + self.subject = self.chatRoom.subject! + } else if addressFriend != nil { + self.subject = addressFriend!.name! + } else { + if self.chatRoom.participants.first != nil + && self.chatRoom.participants.first!.address != nil { + + self.subject = self.chatRoom.participants.first!.address!.displayName != nil + ? self.chatRoom.participants.first!.address!.displayName! + : self.chatRoom.participants.first!.address!.username! + + } + } + + let addressTmp = addressFriend?.address?.asStringUriOnly() ?? "" + + let avatarModelTmp = addressFriend != nil && !self.isGroup + ? ContactsManager.shared.avatarListModel.first(where: { + $0.friend!.name == addressFriend!.name + && $0.friend!.address!.asStringUriOnly() == addressFriend!.address!.asStringUriOnly() + }) + ?? ContactAvatarModel( + friend: nil, + name: self.subject, + address: addressTmp, + withPresence: false + ) + : ContactAvatarModel( + friend: nil, + name: self.subject, + address: addressTmp, + withPresence: false + ) + + DispatchQueue.main.async { + self.avatarModel = avatarModelTmp } - } - - let addressTmp = addressFriend?.address?.asStringUriOnly() ?? "" - - let avatarModelTmp = addressFriend != nil && !self.isGroup - ? ContactsManager.shared.avatarListModel.first(where: { - $0.friend!.name == addressFriend!.name - && $0.friend!.address!.asStringUriOnly() == addressFriend!.address!.asStringUriOnly() - }) - ?? ContactAvatarModel( - friend: nil, - name: self.subject, - address: addressTmp, - withPresence: false - ) - : ContactAvatarModel( - friend: nil, - name: self.subject, - address: addressTmp, - withPresence: false - ) - - DispatchQueue.main.async { - self.avatarModel = avatarModelTmp } } } @@ -235,12 +238,14 @@ class ConversationModel: ObservableObject { coreContext.doOnCoreQueue { _ in if !self.isGroup { if self.chatRoom.participants.first != nil && self.chatRoom.participants.first!.address != nil { - let avatarModelTmp = ContactAvatarModel.getAvatarModelFromAddress(address: self.chatRoom.participants.first!.address!) - let subjectTmp = avatarModelTmp.name - - DispatchQueue.main.async { - self.avatarModel = avatarModelTmp - self.subject = subjectTmp + ContactAvatarModel.getAvatarModelFromAddress(address: self.chatRoom.participants.first!.address!) { avatarResult in + let avatarModelTmp = avatarResult + let subjectTmp = avatarModelTmp.name + + DispatchQueue.main.async { + self.avatarModel = avatarModelTmp + self.subject = subjectTmp + } } } } diff --git a/Linphone/UI/Main/Conversations/ViewModel/ConversationViewModel.swift b/Linphone/UI/Main/Conversations/ViewModel/ConversationViewModel.swift index add138ae3..98b228650 100644 --- a/Linphone/UI/Main/Conversations/ViewModel/ConversationViewModel.swift +++ b/Linphone/UI/Main/Conversations/ViewModel/ConversationViewModel.swift @@ -98,9 +98,11 @@ class ConversationViewModel: ObservableObject { if self.displayedConversation != nil { self.displayedConversation!.chatRoom.participants.forEach { participant in if participant.address != nil { - let avatarModelTmp = ContactAvatarModel.getAvatarModelFromAddress(address: participant.address!) - DispatchQueue.main.async { - self.participantConversationModel.append(avatarModelTmp) + ContactAvatarModel.getAvatarModelFromAddress(address: participant.address!) { avatarResult in + let avatarModelTmp = avatarResult + DispatchQueue.main.async { + self.participantConversationModel.append(avatarModelTmp) + } } } } diff --git a/Linphone/UI/Main/Conversations/ViewModel/ConversationsListViewModel.swift b/Linphone/UI/Main/Conversations/ViewModel/ConversationsListViewModel.swift index c21a2d749..838dfa326 100644 --- a/Linphone/UI/Main/Conversations/ViewModel/ConversationsListViewModel.swift +++ b/Linphone/UI/Main/Conversations/ViewModel/ConversationsListViewModel.swift @@ -148,29 +148,33 @@ class ConversationsListViewModel: ObservableObject { } } - func getContentTextMessage(message: ChatMessage) -> String { - var fromAddressFriend = message.fromAddress != nil - ? contactsManager.getFriendWithAddress(address: message.fromAddress!)?.name ?? nil - : nil - - if !message.isOutgoing && message.chatRoom != nil && !message.chatRoom!.hasCapability(mask: ChatRoom.Capabilities.OneToOne.rawValue) { - if fromAddressFriend == nil { - if message.fromAddress!.displayName != nil { - fromAddressFriend = message.fromAddress!.displayName! + ": " - } else if message.fromAddress!.username != nil { - fromAddressFriend = message.fromAddress!.username! + ": " + func getContentTextMessage(message: ChatMessage, completion: @escaping (String) -> Void) { + contactsManager.getFriendWithAddress(address: message.fromAddress) { friendResult in + var fromAddressFriend = message.fromAddress != nil + ? friendResult?.name ?? nil + : nil + + if !message.isOutgoing && message.chatRoom != nil && !message.chatRoom!.hasCapability(mask: ChatRoom.Capabilities.OneToOne.rawValue) { + if fromAddressFriend == nil { + if message.fromAddress!.displayName != nil { + fromAddressFriend = message.fromAddress!.displayName! + ": " + } else if message.fromAddress!.username != nil { + fromAddressFriend = message.fromAddress!.username! + ": " + } else { + fromAddressFriend = "" + } } else { - fromAddressFriend = "" + fromAddressFriend! += ": " } + } else { - fromAddressFriend! += ": " + fromAddressFriend = nil } - } else { - fromAddressFriend = nil + completion( + (fromAddressFriend ?? "") + (message.contents.first(where: {$0.isText == true})?.utf8Text ?? (message.contents.first(where: {$0.isFile == true || $0.isFileTransfer == true})?.name ?? "")) + ) } - - return (fromAddressFriend ?? "") + (message.contents.first(where: {$0.isText == true})?.utf8Text ?? (message.contents.first(where: {$0.isFile == true || $0.isFileTransfer == true})?.name ?? "")) } func getCallTime(startDate: time_t) -> String { diff --git a/Linphone/UI/Main/History/Model/HistoryModel.swift b/Linphone/UI/Main/History/Model/HistoryModel.swift index cc356f2f3..57e353197 100644 --- a/Linphone/UI/Main/History/Model/HistoryModel.swift +++ b/Linphone/UI/Main/History/Model/HistoryModel.swift @@ -71,27 +71,29 @@ class HistoryModel: ObservableObject { func refreshAvatarModel() { coreContext.doOnCoreQueue { _ in - let addressFriendTmp = ContactsManager.shared.getFriendWithAddress(address: self.callLog.dir == .Outgoing ? self.callLog.toAddress! : self.callLog.fromAddress!) - if addressFriendTmp != nil { - self.addressFriend = addressFriendTmp - - let addressNameTmp = self.addressName - - let avatarModelTmp = addressFriendTmp != nil - ? ContactsManager.shared.avatarListModel.first(where: { - $0.friend!.name == addressFriendTmp!.name - && $0.friend!.address!.asStringUriOnly() == addressFriendTmp!.address!.asStringUriOnly() - }) ?? ContactAvatarModel(friend: nil, name: self.addressName, address: self.address, withPresence: false) - : ContactAvatarModel(friend: nil, name: self.addressName, address: self.address, withPresence: false) - - DispatchQueue.main.async { + ContactsManager.shared.getFriendWithAddress(address: self.callLog.dir == .Outgoing ? self.callLog.toAddress! : self.callLog.fromAddress!) { friendResult in + let addressFriendTmp = friendResult + if addressFriendTmp != nil { self.addressFriend = addressFriendTmp - self.addressName = addressFriendTmp!.name ?? addressNameTmp - self.avatarModel = avatarModelTmp - } - } else { - DispatchQueue.main.async { - self.avatarModel = ContactAvatarModel(friend: nil, name: self.addressName, address: self.address, withPresence: false) + + let addressNameTmp = self.addressName + + let avatarModelTmp = addressFriendTmp != nil + ? ContactsManager.shared.avatarListModel.first(where: { + $0.friend!.name == addressFriendTmp!.name + && $0.friend!.address!.asStringUriOnly() == addressFriendTmp!.address!.asStringUriOnly() + }) ?? ContactAvatarModel(friend: nil, name: self.addressName, address: self.address, withPresence: false) + : ContactAvatarModel(friend: nil, name: self.addressName, address: self.address, withPresence: false) + + DispatchQueue.main.async { + self.addressFriend = addressFriendTmp + self.addressName = addressFriendTmp!.name ?? addressNameTmp + self.avatarModel = avatarModelTmp + } + } else { + DispatchQueue.main.async { + self.avatarModel = ContactAvatarModel(friend: nil, name: self.addressName, address: self.address, withPresence: false) + } } } } diff --git a/Linphone/UI/Main/Meetings/ViewModel/ScheduleMeetingViewModel.swift b/Linphone/UI/Main/Meetings/ViewModel/ScheduleMeetingViewModel.swift index 86c9d6e4e..0a43e13fc 100644 --- a/Linphone/UI/Main/Meetings/ViewModel/ScheduleMeetingViewModel.swift +++ b/Linphone/UI/Main/Meetings/ViewModel/ScheduleMeetingViewModel.swift @@ -257,9 +257,11 @@ class ScheduleMeetingViewModel: ObservableObject { var list: [SelectedAddressModel] = [] for partInfo in conferenceInfo.participantInfos { if let addr = partInfo.address { - let avatarModel = ContactAvatarModel.getAvatarModelFromAddress(address: addr) - list.append(SelectedAddressModel(addr: addr, avModel: avatarModel)) - Log.info("\(ScheduleMeetingViewModel.TAG) Loaded participant \(addr.asStringUriOnly())") + ContactAvatarModel.getAvatarModelFromAddress(address: addr) { avatarResult in + let avatarModel = avatarResult + self.participants.append(SelectedAddressModel(addr: addr, avModel: avatarModel)) + Log.info("\(ScheduleMeetingViewModel.TAG) Loaded participant \(addr.asStringUriOnly())") + } } } Log.info("\(ScheduleMeetingViewModel.TAG) \(list.count) participants loaded from found conference info") @@ -271,7 +273,7 @@ class ScheduleMeetingViewModel: ObservableObject { self.computeDateLabels() self.computeTimeLabels() self.updateTimezone() - self.participants = list + //self.participants = list } } else { diff --git a/Linphone/UI/Main/Viewmodel/AddParticipantsViewModel.swift b/Linphone/UI/Main/Viewmodel/AddParticipantsViewModel.swift index d8140d3a7..616692b07 100644 --- a/Linphone/UI/Main/Viewmodel/AddParticipantsViewModel.swift +++ b/Linphone/UI/Main/Viewmodel/AddParticipantsViewModel.swift @@ -31,7 +31,9 @@ class AddParticipantsViewModel: ObservableObject { participantsToAdd.remove(at: idx) } else { Log.info("[\(AddParticipantsViewModel.TAG)] Adding participant \(addr.asStringUriOnly()) to selection") - participantsToAdd.append(SelectedAddressModel(addr: addr, avModel: ContactAvatarModel.getAvatarModelFromAddress(address: addr))) + ContactAvatarModel.getAvatarModelFromAddress(address: addr) { avatarResult in + self.participantsToAdd.append(SelectedAddressModel(addr: addr, avModel: avatarResult)) + } } } diff --git a/Linphone/Utils/Avatar.swift b/Linphone/Utils/Avatar.swift index deb0c4724..bb7a6d028 100644 --- a/Linphone/Utils/Avatar.swift +++ b/Linphone/Utils/Avatar.swift @@ -37,7 +37,7 @@ struct Avatar: View { } var body: some View { - if contactAvatarModel.friend != nil { + if contactAvatarModel.friend != nil && contactAvatarModel.friend!.photo != nil { AsyncImage(url: ContactsManager.shared.getImagePath(friendPhotoPath: contactAvatarModel.friend!.photo!)) { image in switch image { case .empty: