From 5b5a5d88fae858fd1f7a9e741eb17ddffb10c28f Mon Sep 17 00:00:00 2001 From: Benoit Martins Date: Fri, 28 Jun 2024 15:30:12 +0200 Subject: [PATCH] Fix contact views --- .../ContactInnerActionsFragment.swift | 273 +++++++----------- .../Fragments/ContactInnerFragment.swift | 38 +-- .../Contacts/Model/ContactAvatarModel.swift | 12 + 3 files changed, 137 insertions(+), 186 deletions(-) diff --git a/Linphone/UI/Main/Contacts/Fragments/ContactInnerActionsFragment.swift b/Linphone/UI/Main/Contacts/Fragments/ContactInnerActionsFragment.swift index 7a3d96ce9..01e0ea646 100644 --- a/Linphone/UI/Main/Contacts/Fragments/ContactInnerActionsFragment.swift +++ b/Linphone/UI/Main/Contacts/Fragments/ContactInnerActionsFragment.swift @@ -18,6 +18,7 @@ */ import SwiftUI +import linphonesw struct ContactInnerActionsFragment: View { @@ -26,6 +27,7 @@ struct ContactInnerActionsFragment: View { @ObservedObject var contactViewModel: ContactViewModel @ObservedObject var editContactViewModel: EditContactViewModel + @ObservedObject var contactAvatarModel: ContactAvatarModel @State private var informationIsOpen = true @@ -62,126 +64,125 @@ struct ContactInnerActionsFragment: View { if informationIsOpen { VStack(spacing: 0) { - if contactViewModel.indexDisplayedFriend != nil - && contactsManager.lastSearch.count > contactViewModel.indexDisplayedFriend! - && contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend != nil { - ForEach(0.. contactViewModel.indexDisplayedFriend! - && contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend != nil - && ((contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.organization != nil - && !contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.organization!.isEmpty) - || (contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.jobTitle != nil - && !contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.jobTitle!.isEmpty)) { + if contactAvatarModel.friend != nil && (contactAvatarModel.friend!.organization != nil + && !contactAvatarModel.friend!.organization!.isEmpty) + || (contactAvatarModel.friend!.jobTitle != nil + && !contactAvatarModel.friend!.jobTitle!.isEmpty) { VStack { - if contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.organization != nil - && !contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.organization!.isEmpty { - Text("**Company :** \(contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.organization!)") + if contactAvatarModel.friend!.organization != nil + && !contactAvatarModel.friend!.organization!.isEmpty { + Text("**Company :** \(contactAvatarModel.friend!.organization!)") .default_text_style(styleSize: 14) .padding(.vertical, 15) .padding(.horizontal, 20) .frame(maxWidth: .infinity, alignment: .leading) } - if contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.jobTitle != nil - && !contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.jobTitle!.isEmpty { - Text("**Job :** \(contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.jobTitle!)") + if contactAvatarModel.friend!.jobTitle != nil + && !contactAvatarModel.friend!.jobTitle!.isEmpty { + Text("**Job :** \(contactAvatarModel.friend!.jobTitle!)") .default_text_style(styleSize: 14) .padding(.top, - contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.organization != nil - && !contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.organization!.isEmpty + contactAvatarModel.friend!.organization != nil + && !contactAvatarModel.friend!.organization!.isEmpty ? 0 : 15 ) .padding(.bottom, 15) @@ -212,11 +213,7 @@ struct ContactInnerActionsFragment: View { .background(Color.gray100) VStack(spacing: 0) { - if contactViewModel.indexDisplayedFriend != nil - && contactsManager.lastSearch.count > contactViewModel.indexDisplayedFriend! - && contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend != nil - && contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.nativeUri != nil - && !contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.nativeUri!.isEmpty { + if !contactAvatarModel.nativeUri.isEmpty { Button { actionEditButton() } label: { @@ -264,7 +261,7 @@ struct ContactInnerActionsFragment: View { } .simultaneousGesture( TapGesture().onEnded { - editContactViewModel.selectedEditFriend = contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend + editContactViewModel.selectedEditFriend = contactAvatarModel.friend! editContactViewModel.resetValues() } ) @@ -276,30 +273,21 @@ struct ContactInnerActionsFragment: View { .padding(.horizontal) Button { - if contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend != nil { + if contactAvatarModel.friend != nil { contactViewModel.objectWillChange.send() - contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.edit() - contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.starred.toggle() - contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.done() + contactAvatarModel.friend!.edit() + contactAvatarModel.friend!.starred.toggle() + contactAvatarModel.friend!.done() } } label: { HStack { - Image(contactViewModel.indexDisplayedFriend != nil - && contactViewModel.indexDisplayedFriend! < contactsManager.lastSearch.count - && contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend != nil - && contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.starred == true ? "heart-fill" : "heart") + Image(contactAvatarModel.friend != nil && contactAvatarModel.friend!.starred == true ? "heart-fill" : "heart") .renderingMode(.template) .resizable() - .foregroundStyle(contactViewModel.indexDisplayedFriend != nil - && contactViewModel.indexDisplayedFriend! < contactsManager.lastSearch.count - && contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend != nil - && contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.starred == true ? Color.redDanger500 : Color.grayMain2c500) + .foregroundStyle(contactAvatarModel.friend != nil && contactAvatarModel.friend!.starred == true ? Color.redDanger500 : Color.grayMain2c500) .frame(width: 25, height: 25) .padding(.all, 10) - Text(contactViewModel.indexDisplayedFriend != nil - && contactViewModel.indexDisplayedFriend! < contactsManager.lastSearch.count - && contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend != nil - && contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.starred == true + Text(contactAvatarModel.friend != nil && contactAvatarModel.friend!.starred == true ? "Remove from favourites" : "Add to favourites") .default_text_style(styleSize: 14) @@ -344,62 +332,8 @@ struct ContactInnerActionsFragment: View { } .padding(.horizontal) - /* - Button { - } label: { - HStack { - Image("bell-simple-slash") - .renderingMode(.template) - .resizable() - .foregroundStyle(Color.grayMain2c600) - .frame(width: 25, height: 25) - .padding(.all, 10) - - Text("Mute") - .default_text_style(styleSize: 14) - .frame(maxWidth: .infinity, alignment: .leading) - .lineLimit(1) - .fixedSize(horizontal: false, vertical: true) - Spacer() - } - .padding(.vertical, 15) - .padding(.horizontal, 20) - } - - VStack { - Divider() - } - .padding(.horizontal) - - Button { - } label: { - HStack { - Image("x-circle") - .renderingMode(.template) - .resizable() - .foregroundStyle(Color.grayMain2c600) - .frame(width: 25, height: 25) - .padding(.all, 10) - - Text("Block") - .default_text_style(styleSize: 14) - .frame(maxWidth: .infinity, alignment: .leading) - .lineLimit(1) - .fixedSize(horizontal: false, vertical: true) - Spacer() - } - .padding(.vertical, 15) - .padding(.horizontal, 20) - } - - VStack { - Divider() - } - .padding(.horizontal) - */ - Button { - if contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend != nil { + if contactAvatarModel != nil { isShowDeletePopup.toggle() } } label: { @@ -435,6 +369,7 @@ struct ContactInnerActionsFragment: View { ContactInnerActionsFragment( contactViewModel: ContactViewModel(), editContactViewModel: EditContactViewModel(), + contactAvatarModel: ContactAvatarModel(friend: nil, name: "", address: "", withPresence: false), showingSheet: .constant(false), showShareSheet: .constant(false), isShowDeletePopup: .constant(false), diff --git a/Linphone/UI/Main/Contacts/Fragments/ContactInnerFragment.swift b/Linphone/UI/Main/Contacts/Fragments/ContactInnerFragment.swift index 87457c6c2..0f47f37df 100644 --- a/Linphone/UI/Main/Contacts/Fragments/ContactInnerFragment.swift +++ b/Linphone/UI/Main/Contacts/Fragments/ContactInnerFragment.swift @@ -20,6 +20,7 @@ import SwiftUI import Contacts import ContactsUI +import linphonesw struct ContactInnerFragment: View { @@ -69,9 +70,7 @@ struct ContactInnerFragment: View { Spacer() if contactViewModel.indexDisplayedFriend != nil && contactViewModel.indexDisplayedFriend! < contactsManager.lastSearch.count - && contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend != nil - && contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.nativeUri != nil - && !contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.nativeUri!.isEmpty { + && !contactAvatarModel.nativeUri.isEmpty { Button(action: { editNativeContact() }, label: { @@ -99,7 +98,7 @@ struct ContactInnerFragment: View { } .simultaneousGesture( TapGesture().onEnded { - editContactViewModel.selectedEditFriend = contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend + editContactViewModel.selectedEditFriend = contactAvatarModel.friend editContactViewModel.resetValues() } ) @@ -115,24 +114,19 @@ struct ContactInnerFragment: View { VStack(spacing: 0) { VStack(spacing: 0) { VStack(spacing: 0) { - if contactViewModel.indexDisplayedFriend != nil && contactViewModel.indexDisplayedFriend! < contactsManager.lastSearch.count - && contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend != nil - && contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.photo != nil - && !contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.photo!.isEmpty { + if contactViewModel.indexDisplayedFriend != nil && contactViewModel.indexDisplayedFriend! < contactsManager.lastSearch.count { Avatar(contactAvatarModel: contactAvatarModel, avatarSize: 100) } else if contactViewModel.indexDisplayedFriend != nil && contactViewModel.indexDisplayedFriend! < contactsManager.lastSearch.count - && contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend != nil { + && contactAvatarModel != nil { Image("profil-picture-default") .resizable() .frame(width: 100, height: 100) .clipShape(Circle()) } if contactViewModel.indexDisplayedFriend != nil - && contactViewModel.indexDisplayedFriend! < contactsManager.lastSearch.count - && contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend != nil - && contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend?.name != nil { - Text((contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend?.name)!) + && contactViewModel.indexDisplayedFriend! < contactsManager.lastSearch.count { + Text(contactAvatarModel.name) .foregroundStyle(Color.grayMain2c700) .multilineTextAlignment(.center) .default_text_style(styleSize: 14) @@ -158,7 +152,12 @@ struct ContactInnerFragment: View { Spacer() Button(action: { - telecomManager.doCallOrJoinConf(address: contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.address!) + do { + let address = try Factory.Instance.createAddress(addr: contactAvatarModel.address) + telecomManager.doCallOrJoinConf(address: address) + } catch { + Log.error("[ContactInnerFragment] unable to create address for a new outgoing call : \(contactAvatarModel.address) \(error) ") + } }, label: { VStack { HStack(alignment: .center) { @@ -208,7 +207,12 @@ struct ContactInnerFragment: View { Spacer() Button(action: { - telecomManager.doCallOrJoinConf(address: contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.address!, isVideo: true) + do { + let address = try Factory.Instance.createAddress(addr: contactAvatarModel.address) + telecomManager.doCallOrJoinConf(address: address, isVideo: true) + } catch { + Log.error("[ContactInnerFragment] unable to create address for a new outgoing call : \(contactAvatarModel.address) \(error) ") + } }, label: { VStack { HStack(alignment: .center) { @@ -236,7 +240,7 @@ struct ContactInnerFragment: View { ContactInnerActionsFragment( contactViewModel: contactViewModel, editContactViewModel: editContactViewModel, - showingSheet: $showingSheet, + contactAvatarModel: contactAvatarModel, showingSheet: $showingSheet, showShareSheet: $showShareSheet, isShowDeletePopup: $isShowDeletePopup, isShowDismissPopup: $isShowDismissPopup, @@ -271,7 +275,7 @@ struct ContactInnerFragment: View { let store = CNContactStore() let descriptor = CNContactViewController.descriptorForRequiredKeys() cnContact = try store.unifiedContact( - withIdentifier: contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.nativeUri!, + withIdentifier: contactAvatarModel.nativeUri, keysToFetch: [descriptor] ) diff --git a/Linphone/UI/Main/Contacts/Model/ContactAvatarModel.swift b/Linphone/UI/Main/Contacts/Model/ContactAvatarModel.swift index 8caf5b8eb..1ce1df3f4 100644 --- a/Linphone/UI/Main/Contacts/Model/ContactAvatarModel.swift +++ b/Linphone/UI/Main/Contacts/Model/ContactAvatarModel.swift @@ -29,6 +29,10 @@ class ContactAvatarModel: ObservableObject { let address: String + @Published var addresses: [String] + + let nativeUri: String + let withPresence: Bool? @Published var lastPresenceInfo: String @@ -41,6 +45,14 @@ class ContactAvatarModel: ObservableObject { self.friend = friend self.name = name self.address = address + var addressesTmp: [String] = [] + if friend != nil { + friend!.addresses.forEach { address in + addressesTmp.append(address.asStringUriOnly()) + } + } + self.addresses = addressesTmp + self.nativeUri = friend?.nativeUri ?? "" self.withPresence = withPresence if friend != nil && withPresence == true {