forked from mirrors/linphone-iphone
Fix avatar refresh after image download
This commit is contained in:
parent
088f3a7506
commit
1b879a5c61
10 changed files with 126 additions and 132 deletions
|
|
@ -100,6 +100,7 @@ final class ContactsManager: ObservableObject {
|
|||
CNContactOrganizationNameKey, CNContactImageDataAvailableKey, CNContactImageDataKey, CNContactThumbnailImageDataKey]
|
||||
let request = CNContactFetchRequest(keysToFetch: keys as [CNKeyDescriptor])
|
||||
do {
|
||||
var contactCounter = 0
|
||||
try store.enumerateContacts(with: request, usingBlock: { (contact, _) in
|
||||
DispatchQueue.main.sync {
|
||||
let newContact = Contact(
|
||||
|
|
@ -109,7 +110,7 @@ final class ContactsManager: ObservableObject {
|
|||
organizationName: contact.organizationName,
|
||||
jobTitle: "",
|
||||
displayName: contact.nickname,
|
||||
sipAddresses: contact.instantMessageAddresses.map { $0.value.service == "SIP" ? $0.value.username : "" },
|
||||
sipAddresses: contact.instantMessageAddresses.map { $0.value.service.lowercased() == "SIP".lowercased() ? $0.value.username : "" },
|
||||
phoneNumbers: contact.phoneNumbers.map { PhoneNumber(numLabel: $0.label ?? "", num: $0.value.stringValue)},
|
||||
imageData: ""
|
||||
)
|
||||
|
|
@ -125,8 +126,21 @@ final class ContactsManager: ObservableObject {
|
|||
: contact.givenName, lastName: contact.familyName),
|
||||
name: contact.givenName + contact.familyName,
|
||||
prefix: ((imageThumbnail == nil) ? "-default" : ""),
|
||||
contact: newContact, linphoneFriend: false, existingFriend: nil)
|
||||
contact: newContact, linphoneFriend: false, existingFriend: nil) {
|
||||
if (self.friendList?.friends.count ?? 0) + (self.linphoneFriendList?.friends.count ?? 0) == contactCounter {
|
||||
self.linphoneFriendList?.updateSubscriptions()
|
||||
self.friendList?.updateSubscriptions()
|
||||
|
||||
MagicSearchSingleton.shared.searchForContacts(sourceFlags: MagicSearch.Source.Friends.rawValue | MagicSearch.Source.LdapServers.rawValue)
|
||||
|
||||
self.friendListSuscription = self.friendList?.publisher?.onPresenceReceived?.postOnMainQueue { (cbValue: (friendList: FriendList, friends: [Friend])) in
|
||||
MagicSearchSingleton.shared.searchForContacts(sourceFlags: MagicSearch.Source.Friends.rawValue | MagicSearch.Source.LdapServers.rawValue)
|
||||
self.friendListSuscription = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
contactCounter += 1
|
||||
})
|
||||
|
||||
} catch let error {
|
||||
|
|
@ -137,16 +151,6 @@ final class ContactsManager: ObservableObject {
|
|||
print("\(#function) - access denied")
|
||||
}
|
||||
}
|
||||
|
||||
self.linphoneFriendList?.updateSubscriptions()
|
||||
self.friendList?.updateSubscriptions()
|
||||
|
||||
self.friendListSuscription = self.friendList?.publisher?.onPresenceReceived?.postOnMainQueue { (cbValue: (friendList: FriendList, friends: [Friend])) in
|
||||
MagicSearchSingleton.shared.searchForContacts(sourceFlags: MagicSearch.Source.Friends.rawValue | MagicSearch.Source.LdapServers.rawValue)
|
||||
self.friendListSuscription = nil
|
||||
}
|
||||
|
||||
MagicSearchSingleton.shared.searchForContacts(sourceFlags: MagicSearch.Source.Friends.rawValue | MagicSearch.Source.LdapServers.rawValue)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -178,7 +182,7 @@ final class ContactsManager: ObservableObject {
|
|||
return IBImgViewUserProfile
|
||||
}
|
||||
|
||||
func saveImage(image: UIImage, name: String, prefix: String, contact: Contact, linphoneFriend: Bool, existingFriend: Friend?) {
|
||||
func saveImage(image: UIImage, name: String, prefix: String, contact: Contact, linphoneFriend: Bool, existingFriend: Friend?, completion: @escaping () -> Void) {
|
||||
guard let data = image.jpegData(compressionQuality: 1) ?? image.pngData() else {
|
||||
return
|
||||
}
|
||||
|
|
@ -192,6 +196,7 @@ final class ContactsManager: ObservableObject {
|
|||
_ = self.friendList?.addLocalFriend(linphoneFriend: resultFriend!)
|
||||
}
|
||||
}
|
||||
completion()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -168,6 +168,7 @@ final class CoreContext: ObservableObject {
|
|||
if cbVal.state == .Ok {
|
||||
self.loggingInProgress = false
|
||||
self.loggedIn = true
|
||||
ContactsManager.shared.fetchContacts()
|
||||
} else if cbVal.state == .Progress {
|
||||
self.loggingInProgress = true
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -143,7 +143,6 @@ struct LinphoneApp: App {
|
|||
if newPhase == .active {
|
||||
Log.info("Entering foreground")
|
||||
coreContext.onEnterForeground()
|
||||
ContactsManager.shared.fetchContacts()
|
||||
} else if newPhase == .inactive {
|
||||
} else if newPhase == .background {
|
||||
Log.info("Entering background")
|
||||
|
|
|
|||
|
|
@ -443,8 +443,9 @@ class TelecomManager: ObservableObject {
|
|||
} else {
|
||||
DispatchQueue.main.async {
|
||||
self.remoteConfVideo = false
|
||||
let remoteConfVideoTmp = call.currentParams!.videoEnabled && call.currentParams!.videoDirection == .SendRecv || call.currentParams!.videoDirection == .RecvOnly
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||
self.remoteConfVideo = call.currentParams!.videoEnabled && call.currentParams!.videoDirection == .SendRecv || call.currentParams!.videoDirection == .RecvOnly
|
||||
self.remoteConfVideo = remoteConfVideoTmp
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -526,29 +526,29 @@ struct EditContactFragment: View {
|
|||
name: editContactViewModel.firstName
|
||||
+ editContactViewModel.lastName,
|
||||
prefix: ((selectedImage == nil) ? "-default" : ""),
|
||||
contact: newContact, linphoneFriend: true, existingFriend: editContactViewModel.selectedEditFriend)
|
||||
contact: newContact, linphoneFriend: true, existingFriend: editContactViewModel.selectedEditFriend) {
|
||||
MagicSearchSingleton.shared.searchForContacts(sourceFlags: MagicSearch.Source.Friends.rawValue | MagicSearch.Source.LdapServers.rawValue)
|
||||
|
||||
if editContactViewModel.selectedEditFriend != nil && editContactViewModel.selectedEditFriend!.name != editContactViewModel.firstName + " " + editContactViewModel.lastName {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||
let result = ContactsManager.shared.lastSearch.firstIndex(where: {
|
||||
$0.friend!.name == newContact.firstName + " " + newContact.lastName
|
||||
})
|
||||
contactViewModel.indexDisplayedFriend = result
|
||||
}
|
||||
}
|
||||
|
||||
delayColorDismiss()
|
||||
if editContactViewModel.selectedEditFriend == nil {
|
||||
withAnimation {
|
||||
isShowEditContactFragment.toggle()
|
||||
}
|
||||
} else {
|
||||
dismiss()
|
||||
}
|
||||
editContactViewModel.resetValues()
|
||||
}
|
||||
}
|
||||
|
||||
MagicSearchSingleton.shared.searchForContacts(sourceFlags: MagicSearch.Source.Friends.rawValue | MagicSearch.Source.LdapServers.rawValue)
|
||||
|
||||
if editContactViewModel.selectedEditFriend != nil && editContactViewModel.selectedEditFriend!.name != editContactViewModel.firstName + " " + editContactViewModel.lastName {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||
let result = ContactsManager.shared.lastSearch.firstIndex(where: {
|
||||
$0.friend!.name == newContact.firstName + " " + newContact.lastName
|
||||
})
|
||||
contactViewModel.indexDisplayedFriend = result
|
||||
}
|
||||
}
|
||||
|
||||
delayColorDismiss()
|
||||
if editContactViewModel.selectedEditFriend == nil {
|
||||
withAnimation {
|
||||
isShowEditContactFragment.toggle()
|
||||
}
|
||||
} else {
|
||||
dismiss()
|
||||
}
|
||||
editContactViewModel.resetValues()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -117,7 +117,6 @@ class ContactAvatarModel: ObservableObject {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static func getAvatarModelFromAddress(address: Address, completion: @escaping (ContactAvatarModel) -> Void) {
|
||||
ContactsManager.shared.getFriendWithAddressInCoreQueue(address: address) { resultFriend in
|
||||
if let addressFriend = resultFriend {
|
||||
|
|
|
|||
|
|
@ -34,21 +34,21 @@ struct ConversationsListFragment: View {
|
|||
List {
|
||||
ForEach(0..<conversationsListViewModel.conversationsList.count, id: \.self) { index in
|
||||
HStack {
|
||||
Avatar(contactAvatarModel: conversationsListViewModel.conversationsList[index].avatarModel, avatarSize: 50)
|
||||
Avatar(contactAvatarModel: conversationsListViewModel.conversationsList[index].avatarModel, avatarSize: 50)
|
||||
|
||||
VStack(spacing: 0) {
|
||||
Spacer()
|
||||
|
||||
VStack(spacing: 0) {
|
||||
Spacer()
|
||||
Text(conversationsListViewModel.conversationsList[index].subject)
|
||||
.foregroundStyle(Color.grayMain2c800)
|
||||
.if(conversationsListViewModel.conversationsList[index].unreadMessagesCount > 0) { view in
|
||||
view.default_text_style_700(styleSize: 14)
|
||||
}
|
||||
.default_text_style(styleSize: 14)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.lineLimit(1)
|
||||
|
||||
Text(conversationsListViewModel.conversationsList[index].subject)
|
||||
.foregroundStyle(Color.grayMain2c800)
|
||||
.if(conversationsListViewModel.conversationsList[index].unreadMessagesCount > 0) { view in
|
||||
view.default_text_style_700(styleSize: 14)
|
||||
}
|
||||
.default_text_style(styleSize: 14)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.lineLimit(1)
|
||||
|
||||
Text(conversationsListViewModel.conversationsList[index].lastMessageText)
|
||||
Text(conversationsListViewModel.conversationsList[index].lastMessageText)
|
||||
.foregroundStyle(Color.grayMain2c400)
|
||||
.if(conversationsListViewModel.conversationsList[index].unreadMessagesCount > 0) { view in
|
||||
view.default_text_style_700(styleSize: 14)
|
||||
|
|
@ -56,79 +56,79 @@ struct ConversationsListFragment: View {
|
|||
.default_text_style(styleSize: 14)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.lineLimit(1)
|
||||
|
||||
Spacer()
|
||||
}
|
||||
|
||||
Spacer()
|
||||
|
||||
VStack(alignment: .trailing, spacing: 0) {
|
||||
Spacer()
|
||||
|
||||
HStack {
|
||||
if !conversationsListViewModel.conversationsList[index].encryptionEnabled {
|
||||
Image("warning-circle")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(Color.redDanger500)
|
||||
.frame(width: 18, height: 18, alignment: .trailing)
|
||||
}
|
||||
|
||||
Spacer()
|
||||
Text(conversationsListViewModel.getCallTime(startDate: conversationsListViewModel.conversationsList[index].lastUpdateTime))
|
||||
.foregroundStyle(Color.grayMain2c400)
|
||||
.default_text_style(styleSize: 14)
|
||||
.lineLimit(1)
|
||||
}
|
||||
|
||||
Spacer()
|
||||
|
||||
VStack(alignment: .trailing, spacing: 0) {
|
||||
Spacer()
|
||||
HStack {
|
||||
if conversationsListViewModel.conversationsList[index].isMuted == false
|
||||
&& !(!conversationsListViewModel.conversationsList[index].lastMessageText.isEmpty
|
||||
&& conversationsListViewModel.conversationsList[index].lastMessageIsOutgoing == true)
|
||||
&& conversationsListViewModel.conversationsList[index].unreadMessagesCount == 0 {
|
||||
Text("")
|
||||
.frame(width: 18, height: 18, alignment: .trailing)
|
||||
}
|
||||
|
||||
HStack {
|
||||
if !conversationsListViewModel.conversationsList[index].encryptionEnabled {
|
||||
Image("warning-circle")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(Color.redDanger500)
|
||||
.frame(width: 18, height: 18, alignment: .trailing)
|
||||
}
|
||||
|
||||
Text(conversationsListViewModel.getCallTime(startDate: conversationsListViewModel.conversationsList[index].lastUpdateTime))
|
||||
.foregroundStyle(Color.grayMain2c400)
|
||||
.default_text_style(styleSize: 14)
|
||||
if conversationsListViewModel.conversationsList[index].isMuted {
|
||||
Image("bell-slash")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(Color.orangeMain500)
|
||||
.frame(width: 18, height: 18, alignment: .trailing)
|
||||
}
|
||||
|
||||
if !conversationsListViewModel.conversationsList[index].lastMessageText.isEmpty
|
||||
&& conversationsListViewModel.conversationsList[index].lastMessageIsOutgoing == true {
|
||||
let imageName = LinphoneUtils.getChatIconState(chatState: conversationsListViewModel.conversationsList[index].lastMessageState)
|
||||
Image(imageName)
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(Color.orangeMain500)
|
||||
.frame(width: 18, height: 18, alignment: .trailing)
|
||||
}
|
||||
|
||||
if conversationsListViewModel.conversationsList[index].unreadMessagesCount > 0 {
|
||||
HStack {
|
||||
Text(
|
||||
conversationsListViewModel.conversationsList[index].unreadMessagesCount < 99
|
||||
? String(conversationsListViewModel.conversationsList[index].unreadMessagesCount)
|
||||
: "99+"
|
||||
)
|
||||
.foregroundStyle(.white)
|
||||
.default_text_style(styleSize: 10)
|
||||
.lineLimit(1)
|
||||
}
|
||||
.frame(width: 18, height: 18)
|
||||
.background(Color.redDanger500)
|
||||
.cornerRadius(50)
|
||||
}
|
||||
|
||||
Spacer()
|
||||
|
||||
HStack {
|
||||
if conversationsListViewModel.conversationsList[index].isMuted == false
|
||||
&& !(!conversationsListViewModel.conversationsList[index].lastMessageText.isEmpty
|
||||
&& conversationsListViewModel.conversationsList[index].lastMessageIsOutgoing == true)
|
||||
&& conversationsListViewModel.conversationsList[index].unreadMessagesCount == 0 {
|
||||
Text("")
|
||||
.frame(width: 18, height: 18, alignment: .trailing)
|
||||
}
|
||||
|
||||
if conversationsListViewModel.conversationsList[index].isMuted {
|
||||
Image("bell-slash")
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(Color.orangeMain500)
|
||||
.frame(width: 18, height: 18, alignment: .trailing)
|
||||
}
|
||||
|
||||
if !conversationsListViewModel.conversationsList[index].lastMessageText.isEmpty
|
||||
&& conversationsListViewModel.conversationsList[index].lastMessageIsOutgoing == true {
|
||||
let imageName = LinphoneUtils.getChatIconState(chatState: conversationsListViewModel.conversationsList[index].lastMessageState)
|
||||
Image(imageName)
|
||||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.foregroundStyle(Color.orangeMain500)
|
||||
.frame(width: 18, height: 18, alignment: .trailing)
|
||||
}
|
||||
|
||||
if conversationsListViewModel.conversationsList[index].unreadMessagesCount > 0 {
|
||||
HStack {
|
||||
Text(
|
||||
conversationsListViewModel.conversationsList[index].unreadMessagesCount < 99
|
||||
? String(conversationsListViewModel.conversationsList[index].unreadMessagesCount)
|
||||
: "99+"
|
||||
)
|
||||
.foregroundStyle(.white)
|
||||
.default_text_style(styleSize: 10)
|
||||
.lineLimit(1)
|
||||
}
|
||||
.frame(width: 18, height: 18)
|
||||
.background(Color.redDanger500)
|
||||
.cornerRadius(50)
|
||||
}
|
||||
}
|
||||
|
||||
Spacer()
|
||||
}
|
||||
.padding(.trailing, 10)
|
||||
|
||||
Spacer()
|
||||
}
|
||||
.padding(.trailing, 10)
|
||||
}
|
||||
.frame(height: 50)
|
||||
.buttonStyle(.borderless)
|
||||
|
|
|
|||
|
|
@ -39,19 +39,14 @@ class ConversationModel: ObservableObject {
|
|||
@Published var subject: String
|
||||
@Published var isComposing: Bool
|
||||
@Published var lastUpdateTime: time_t
|
||||
//@Published var composingLabel: String
|
||||
@Published var isMuted: Bool
|
||||
@Published var isEphemeral: Bool
|
||||
@Published var encryptionEnabled: Bool
|
||||
@Published var lastMessageText: String
|
||||
@Published var lastMessageIsOutgoing: Bool
|
||||
@Published var lastMessageState: Int
|
||||
//@Published var dateTime: String
|
||||
@Published var unreadMessagesCount: Int
|
||||
@Published var avatarModel: ContactAvatarModel
|
||||
//@Published var isBeingDeleted: Bool
|
||||
|
||||
//private let lastMessage: ChatMessage? = nil
|
||||
|
||||
init(chatRoom: ChatRoom) {
|
||||
self.chatRoom = chatRoom
|
||||
|
|
@ -72,8 +67,6 @@ class ConversationModel: ObservableObject {
|
|||
|
||||
self.isComposing = chatRoom.isRemoteComposing
|
||||
|
||||
//self.composingLabel = chatRoom.compo
|
||||
|
||||
self.isMuted = chatRoom.muted
|
||||
|
||||
self.isEphemeral = chatRoom.ephemeralEnabled
|
||||
|
|
@ -86,15 +79,9 @@ class ConversationModel: ObservableObject {
|
|||
|
||||
self.lastMessageState = 0
|
||||
|
||||
//self.dateTime = chatRoom.date
|
||||
|
||||
self.unreadMessagesCount = 0
|
||||
|
||||
self.avatarModel = ContactAvatarModel(friend: nil, name: "", address: "", withPresence: false)
|
||||
|
||||
//self.isBeingDeleted = MutableLiveData<Boolean>()
|
||||
|
||||
//self.lastMessage: ChatMessage? = null
|
||||
self.avatarModel = ContactAvatarModel(friend: nil, name: chatRoom.subject ?? "", address: chatRoom.peerAddress?.asStringUriOnly() ?? "", withPresence: false)
|
||||
|
||||
getContentTextMessage()
|
||||
getChatRoomSubject()
|
||||
|
|
|
|||
|
|
@ -205,5 +205,7 @@ class ConversationsListViewModel: ObservableObject {
|
|||
conversationsList.forEach { conversationModel in
|
||||
conversationModel.refreshAvatarModel()
|
||||
}
|
||||
|
||||
reorderChatRooms()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,9 +54,9 @@ struct EditContactView: UIViewControllerRepresentable {
|
|||
prefix: ((imageThumbnail == nil) ? "-default" : ""),
|
||||
contact: newContact,
|
||||
linphoneFriend: false,
|
||||
existingFriend: ContactsManager.shared.getFriendWithContact(contact: newContact))
|
||||
|
||||
MagicSearchSingleton.shared.searchForContacts(sourceFlags: MagicSearch.Source.Friends.rawValue | MagicSearch.Source.LdapServers.rawValue)
|
||||
existingFriend: ContactsManager.shared.getFriendWithContact(contact: newContact)) {
|
||||
MagicSearchSingleton.shared.searchForContacts(sourceFlags: MagicSearch.Source.Friends.rawValue | MagicSearch.Source.LdapServers.rawValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
viewController.dismiss(animated: true, completion: {})
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue