From 8aae1b2020680b17888ca67be16a338658607ab6 Mon Sep 17 00:00:00 2001 From: Benoit Martins Date: Wed, 8 Nov 2023 22:01:10 +0100 Subject: [PATCH] Edit native contact test --- Linphone.xcodeproj/project.pbxproj | 4 + Linphone/Contacts/ContactsManager.swift | 43 +- Linphone/Localizable.xcstrings | 3 + .../Contacts/Fragments/ContactFragment.swift | 6 +- .../ContactInnerActionsFragment.swift | 455 ++++++++++++++++++ .../Fragments/ContactInnerFragment.swift | 433 ++--------------- .../Fragments/ContactsListBottomSheet.swift | 6 +- .../Fragments/EditContactFragment.swift | 19 +- Linphone/UI/Main/ContentView.swift | 13 +- Linphone/Utils/EditContactController.swift | 2 +- 10 files changed, 551 insertions(+), 433 deletions(-) create mode 100644 Linphone/UI/Main/Contacts/Fragments/ContactInnerActionsFragment.swift diff --git a/Linphone.xcodeproj/project.pbxproj b/Linphone.xcodeproj/project.pbxproj index d04b4595f..565fc4601 100644 --- a/Linphone.xcodeproj/project.pbxproj +++ b/Linphone.xcodeproj/project.pbxproj @@ -51,6 +51,7 @@ D7C3650C2AF0084000FE6142 /* EditContactViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7C3650B2AF0084000FE6142 /* EditContactViewModel.swift */; }; D7C3650E2AF15BF200FE6142 /* PhotoPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7C3650D2AF15BF200FE6142 /* PhotoPicker.swift */; }; D7C48DF42AFA66F900D938CB /* EditContactController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7C48DF32AFA66F900D938CB /* EditContactController.swift */; }; + D7C48DF62AFCDF4700D938CB /* ContactInnerActionsFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7C48DF52AFCDF4700D938CB /* ContactInnerActionsFragment.swift */; }; D7D1698C2AE66FA500109A5C /* MagicSearchSingleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7D1698B2AE66FA500109A5C /* MagicSearchSingleton.swift */; }; D7D24D132AC1B4E800C6F35B /* NotoSans-Medium.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7D24D0D2AC1B4E800C6F35B /* NotoSans-Medium.ttf */; }; D7D24D142AC1B4E800C6F35B /* NotoSans-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D7D24D0E2AC1B4E800C6F35B /* NotoSans-Regular.ttf */; }; @@ -118,6 +119,7 @@ D7C3650B2AF0084000FE6142 /* EditContactViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditContactViewModel.swift; sourceTree = ""; }; D7C3650D2AF15BF200FE6142 /* PhotoPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoPicker.swift; sourceTree = ""; }; D7C48DF32AFA66F900D938CB /* EditContactController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditContactController.swift; sourceTree = ""; }; + D7C48DF52AFCDF4700D938CB /* ContactInnerActionsFragment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactInnerActionsFragment.swift; sourceTree = ""; }; D7D1698B2AE66FA500109A5C /* MagicSearchSingleton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MagicSearchSingleton.swift; sourceTree = ""; }; D7D24D0D2AC1B4E800C6F35B /* NotoSans-Medium.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "NotoSans-Medium.ttf"; sourceTree = ""; }; D7D24D0E2AC1B4E800C6F35B /* NotoSans-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "NotoSans-Regular.ttf"; sourceTree = ""; }; @@ -342,6 +344,7 @@ D7B5066C2AEFA9B900CEB4E9 /* ContactInnerFragment.swift */, D7C365072AEFAB7F00FE6142 /* ContactListBottomSheet.swift */, D7C365092AF001C300FE6142 /* EditContactFragment.swift */, + D7C48DF52AFCDF4700D938CB /* ContactInnerActionsFragment.swift */, ); path = Fragments; sourceTree = ""; @@ -588,6 +591,7 @@ D7E6D0552AEBFCCE00A57AAF /* ContactsInnerFragment.swift in Sources */, D72343362AD037AF009AA24E /* ToastView.swift in Sources */, D7FB55112AD447FD00A5AB15 /* RegisterFragment.swift in Sources */, + D7C48DF62AFCDF4700D938CB /* ContactInnerActionsFragment.swift in Sources */, D72343322ACEFF58009AA24E /* QRScannerController.swift in Sources */, D72343342ACEFFC3009AA24E /* QRScanner.swift in Sources */, D72343302ACEFEF8009AA24E /* QrCodeScannerFragment.swift in Sources */, diff --git a/Linphone/Contacts/ContactsManager.swift b/Linphone/Contacts/ContactsManager.swift index 981bd7c6f..29506bbd5 100644 --- a/Linphone/Contacts/ContactsManager.swift +++ b/Linphone/Contacts/ContactsManager.swift @@ -95,6 +95,7 @@ final class ContactsManager: ObservableObject { } let store = CNContactStore() + store.requestAccess(for: .contacts) { (granted, error) in if let error = error { print("failed to request access", error) @@ -105,7 +106,7 @@ final class ContactsManager: ObservableObject { CNContactFamilyNameKey, CNContactGivenNameKey, CNContactNicknameKey, CNContactPostalAddressesKey, CNContactIdentifierKey, CNInstantMessageAddressUsernameKey, CNContactInstantMessageAddressesKey, - CNContactImageDataKey, CNContactThumbnailImageDataKey, CNContactOrganizationNameKey] + CNContactOrganizationNameKey, CNContactImageDataAvailableKey, CNContactImageDataKey, CNContactThumbnailImageDataKey] let request = CNContactFetchRequest(keysToFetch: keys as [CNKeyDescriptor]) do { try store.enumerateContacts(with: request, usingBlock: { (contact, _) in @@ -289,46 +290,6 @@ final class ContactsManager: ObservableObject { } } - func getCNContact(friend: Friend, completion: @escaping (CNContact?) -> Void) { - DispatchQueue.global().async { - let store = CNContactStore() - store.requestAccess(for: .contacts) { (granted, error) in - if let error = error { - print("failed to request access", error) - return - } - if granted { - let keys = [CNContactEmailAddressesKey, CNContactPhoneNumbersKey, - CNContactFamilyNameKey, CNContactGivenNameKey, CNContactNicknameKey, - CNContactPostalAddressesKey, CNContactIdentifierKey, - CNInstantMessageAddressUsernameKey, CNContactInstantMessageAddressesKey, - CNContactImageDataKey, CNContactThumbnailImageDataKey, CNContactOrganizationNameKey] - let request = CNContactFetchRequest(keysToFetch: keys as [CNKeyDescriptor]) - do { - try store.enumerateContacts(with: request, usingBlock: { (contact, _) in - if contact.identifier == friend.nativeUri { - var contactFetched = contact - if !contactFetched.areKeysAvailable([CNContactViewController.descriptorForRequiredKeys()]) { - do { - contactFetched = try store.unifiedContact(withIdentifier: contact.identifier, keysToFetch: [CNContactViewController.descriptorForRequiredKeys()]) - completion(contactFetched) - } - catch { - completion(nil) - } - } - } - }) - } catch let error { - print("Failed to enumerate contact", error) - } - } else { - print("access denied") - } - } - } - } - func getFriend(contact: Contact) -> Friend? { if friendList != nil { let friend = friendList!.friends.first(where: {$0.nativeUri == contact.identifier}) diff --git a/Linphone/Localizable.xcstrings b/Linphone/Localizable.xcstrings index 2742080e2..0062a8ce1 100644 --- a/Linphone/Localizable.xcstrings +++ b/Linphone/Localizable.xcstrings @@ -3,6 +3,9 @@ "strings" : { "" : { + }, + " " : { + }, " et " : { diff --git a/Linphone/UI/Main/Contacts/Fragments/ContactFragment.swift b/Linphone/UI/Main/Contacts/Fragments/ContactFragment.swift index 02d537c6f..aa8a09228 100644 --- a/Linphone/UI/Main/Contacts/Fragments/ContactFragment.swift +++ b/Linphone/UI/Main/Contacts/Fragments/ContactFragment.swift @@ -18,6 +18,7 @@ */ import SwiftUI +import Contacts struct ContactFragment: View { @@ -37,7 +38,8 @@ struct ContactFragment: View { ContactInnerFragment( contactViewModel: contactViewModel, editContactViewModel: editContactViewModel, - isShowDeletePopup: $isShowDeletePopup, + cnContact: CNContact(), + isShowDeletePopup: $isShowDeletePopup, showingSheet: $showingSheet, isShowDismissPopup: $isShowDismissPopup ) @@ -49,6 +51,7 @@ struct ContactFragment: View { ContactInnerFragment( contactViewModel: contactViewModel, editContactViewModel: editContactViewModel, + cnContact: CNContact(), isShowDeletePopup: $isShowDeletePopup, showingSheet: $showingSheet, isShowDismissPopup: $isShowDismissPopup @@ -61,6 +64,7 @@ struct ContactFragment: View { ContactInnerFragment( contactViewModel: contactViewModel, editContactViewModel: editContactViewModel, + cnContact: CNContact(), isShowDeletePopup: $isShowDeletePopup, showingSheet: $showingSheet, isShowDismissPopup: $isShowDismissPopup diff --git a/Linphone/UI/Main/Contacts/Fragments/ContactInnerActionsFragment.swift b/Linphone/UI/Main/Contacts/Fragments/ContactInnerActionsFragment.swift new file mode 100644 index 000000000..23eb79e93 --- /dev/null +++ b/Linphone/UI/Main/Contacts/Fragments/ContactInnerActionsFragment.swift @@ -0,0 +1,455 @@ +// +// ContactInnerActionsFragment.swift +// Linphone +// +// Created by BenoƮt Martins on 09/11/2023. +// + +import SwiftUI + +struct ContactInnerActionsFragment: View { + + @ObservedObject var magicSearch = MagicSearchSingleton.shared + @ObservedObject var contactViewModel: ContactViewModel + @ObservedObject var editContactViewModel: EditContactViewModel + + @State private var informationIsOpen = true + + @Binding var showingSheet: Bool + @Binding var isShowDeletePopup: Bool + @Binding var isShowDismissPopup: Bool + + var actionEditButton: () -> Void + + var body: some View { + HStack(alignment: .center) { + Text("Information") + .default_text_style_800(styleSize: 16) + + Spacer() + + Image(informationIsOpen ? "caret-up" : "caret-down") + .renderingMode(.template) + .resizable() + .foregroundStyle(Color.grayMain2c600) + .frame(width: 25, height: 25, alignment: .leading) + } + .padding(.top, 30) + .padding(.bottom, 10) + .padding(.horizontal, 16) + .background(Color.gray100) + .onTapGesture { + withAnimation { + informationIsOpen.toggle() + } + } + + if informationIsOpen { + VStack(spacing: 0) { + if contactViewModel.indexDisplayedFriend != nil && magicSearch.lastSearch[contactViewModel.indexDisplayedFriend!].friend != nil { + ForEach(0..