From 0d210dea6d68d5c3ce2cd74b05d58a1210fc4586 Mon Sep 17 00:00:00 2001 From: Benoit Martins Date: Fri, 19 Apr 2024 15:36:12 +0200 Subject: [PATCH] Fix display of confs in story fragments --- .../users-three-square.imageset/Contents.json | 21 + .../users-three-square.svg | 8 + .../Fragments/HistoryContactFragment.swift | 1039 +++++++++-------- .../Fragments/HistoryListFragment.swift | 241 ++-- .../ViewModel/HistoryListViewModel.swift | 37 +- .../History/ViewModel/HistoryViewModel.swift | 14 + 6 files changed, 761 insertions(+), 599 deletions(-) create mode 100644 Linphone/Assets.xcassets/users-three-square.imageset/Contents.json create mode 100644 Linphone/Assets.xcassets/users-three-square.imageset/users-three-square.svg diff --git a/Linphone/Assets.xcassets/users-three-square.imageset/Contents.json b/Linphone/Assets.xcassets/users-three-square.imageset/Contents.json new file mode 100644 index 000000000..210e20d8d --- /dev/null +++ b/Linphone/Assets.xcassets/users-three-square.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "users-three-square.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Linphone/Assets.xcassets/users-three-square.imageset/users-three-square.svg b/Linphone/Assets.xcassets/users-three-square.imageset/users-three-square.svg new file mode 100644 index 000000000..86d942745 --- /dev/null +++ b/Linphone/Assets.xcassets/users-three-square.imageset/users-three-square.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Linphone/UI/Main/History/Fragments/HistoryContactFragment.swift b/Linphone/UI/Main/History/Fragments/HistoryContactFragment.swift index 71062797b..ed3a6b0fb 100644 --- a/Linphone/UI/Main/History/Fragments/HistoryContactFragment.swift +++ b/Linphone/UI/Main/History/Fragments/HistoryContactFragment.swift @@ -17,11 +17,12 @@ * along with this program. If not, see . */ -// swiftlint:disable line_length - import SwiftUI import UniformTypeIdentifiers +import linphonesw +// swiftlint:disable line_length +// swiftlint:disable type_body_length struct HistoryContactFragment: View { @State private var orientation = UIDevice.current.orientation @@ -44,518 +45,594 @@ struct HistoryContactFragment: View { var body: some View { NavigationView { - VStack(spacing: 1) { - Rectangle() - .foregroundColor(Color.orangeMain500) - .edgesIgnoringSafeArea(.top) - .frame(height: 0) - - HStack { - if !(orientation == .landscapeLeft || orientation == .landscapeRight - || UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height) { - Image("caret-left") - .renderingMode(.template) - .resizable() - .foregroundStyle(Color.orangeMain500) - .frame(width: 25, height: 25, alignment: .leading) - .padding(.all, 10) - .padding(.top, 2) - .padding(.leading, -10) - .onTapGesture { - withAnimation { - historyViewModel.displayedCall = nil - } - } - } + if historyViewModel.displayedCall != nil { + VStack(spacing: 1) { + Rectangle() + .foregroundColor(Color.orangeMain500) + .edgesIgnoringSafeArea(.top) + .frame(height: 0) - Text("Call history") - .default_text_style_orange_800(styleSize: 20) - - Spacer() - - Menu { - let fromAddressFriend = historyViewModel.displayedCall != nil ? contactsManager.getFriendWithAddress(address: historyViewModel.displayedCall!.fromAddress!) : nil - let toAddressFriend = historyViewModel.displayedCall != nil ? contactsManager.getFriendWithAddress(address: historyViewModel.displayedCall!.toAddress!) : nil - let addressFriend = historyViewModel.displayedCall != nil ? (historyViewModel.displayedCall!.dir == .Incoming ? fromAddressFriend : toAddressFriend) : nil - - Button { - isMenuOpen = false - - if contactsManager.getFriendWithAddress( - address: historyViewModel.displayedCall != nil && historyViewModel.displayedCall!.dir == .Outgoing - ? historyViewModel.displayedCall!.toAddress! - : historyViewModel.displayedCall!.fromAddress! - ) != nil { - let addressCall = historyViewModel.displayedCall != nil && historyViewModel.displayedCall!.dir == .Outgoing - ? historyViewModel.displayedCall!.toAddress! - : historyViewModel.displayedCall!.fromAddress! - - let friendIndex = contactsManager.lastSearch.firstIndex( - where: {$0.friend!.addresses.contains(where: {$0.asStringUriOnly() == addressCall.asStringUriOnly()})}) - if friendIndex != nil { - + HStack { + if !(orientation == .landscapeLeft || orientation == .landscapeRight + || UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height) { + Image("caret-left") + .renderingMode(.template) + .resizable() + .foregroundStyle(Color.orangeMain500) + .frame(width: 25, height: 25, alignment: .leading) + .padding(.all, 10) + .padding(.top, 2) + .padding(.leading, -10) + .onTapGesture { withAnimation { historyViewModel.displayedCall = nil - indexPage = 0 - - contactViewModel.indexDisplayedFriend = friendIndex } } - } else { - let addressCall = historyViewModel.displayedCall != nil && historyViewModel.displayedCall!.dir == .Outgoing - ? historyViewModel.displayedCall!.toAddress! - : historyViewModel.displayedCall!.fromAddress! - - withAnimation { - historyViewModel.displayedCall = nil - indexPage = 0 + } + + Text("Call history") + .default_text_style_orange_800(styleSize: 20) + + Spacer() + + Menu { + let fromAddressFriend = historyViewModel.displayedCall != nil ? contactsManager.getFriendWithAddress(address: historyViewModel.displayedCall!.fromAddress!) : nil + let toAddressFriend = historyViewModel.displayedCall != nil ? contactsManager.getFriendWithAddress(address: historyViewModel.displayedCall!.toAddress!) : nil + let addressFriend = historyViewModel.displayedCall != nil ? (historyViewModel.displayedCall!.dir == .Incoming ? fromAddressFriend : toAddressFriend) : nil + + if historyViewModel.displayedCallIsConference.isEmpty { + Button { + isMenuOpen = false - isShowEditContactFragment.toggle() - editContactViewModel.sipAddresses.removeAll() - editContactViewModel.sipAddresses.append(String(addressCall.asStringUriOnly().dropFirst(4))) - editContactViewModel.sipAddresses.append("") + if contactsManager.getFriendWithAddress( + address: historyViewModel.displayedCall != nil && historyViewModel.displayedCall!.dir == .Outgoing + ? historyViewModel.displayedCall!.toAddress! + : historyViewModel.displayedCall!.fromAddress! + ) != nil { + let addressCall = historyViewModel.displayedCall != nil && historyViewModel.displayedCall!.dir == .Outgoing + ? historyViewModel.displayedCall!.toAddress! + : historyViewModel.displayedCall!.fromAddress! + + let friendIndex = contactsManager.lastSearch.firstIndex( + where: {$0.friend!.addresses.contains(where: {$0.asStringUriOnly() == addressCall.asStringUriOnly()})}) + if friendIndex != nil { + + withAnimation { + historyViewModel.displayedCall = nil + indexPage = 0 + + contactViewModel.indexDisplayedFriend = friendIndex + } + } + } else { + let addressCall = historyViewModel.displayedCall != nil && historyViewModel.displayedCall!.dir == .Outgoing + ? historyViewModel.displayedCall!.toAddress! + : historyViewModel.displayedCall!.fromAddress! + + withAnimation { + historyViewModel.displayedCall = nil + indexPage = 0 + + isShowEditContactFragment.toggle() + editContactViewModel.sipAddresses.removeAll() + editContactViewModel.sipAddresses.append(String(addressCall.asStringUriOnly().dropFirst(4))) + editContactViewModel.sipAddresses.append("") + } + } + + } label: { + HStack { + Text(addressFriend != nil ? "See contact" : "Add to contacts") + Spacer() + Image(addressFriend != nil ? "user-circle" : "plus-circle") + .resizable() + .frame(width: 25, height: 25, alignment: .leading) + .padding(.all, 10) + } } } - - } label: { - HStack { - Text(addressFriend != nil ? "See contact" : "Add to contacts") - Spacer() - Image(addressFriend != nil ? "user-circle" : "plus-circle") + + Button { + isMenuOpen = false + + if historyViewModel.displayedCall != nil && historyViewModel.displayedCall!.dir == .Outgoing { + UIPasteboard.general.setValue( + historyViewModel.displayedCall!.toAddress!.asStringUriOnly().dropFirst(4), + forPasteboardType: UTType.plainText.identifier + ) + } else { + UIPasteboard.general.setValue( + historyViewModel.displayedCall!.fromAddress!.asStringUriOnly().dropFirst(4), + forPasteboardType: UTType.plainText.identifier + ) + } + + ToastViewModel.shared.toastMessage = "Success_copied_into_clipboard" + ToastViewModel.shared.displayToast.toggle() + + } label: { + HStack { + Text("Copy SIP address") + Spacer() + Image("copy") + .resizable() + .frame(width: 25, height: 25, alignment: .leading) + .padding(.all, 10) + } + } + + Button(role: .destructive) { + isMenuOpen = false + + if historyViewModel.displayedCall != nil && historyViewModel.displayedCall!.dir == .Outgoing { + historyListViewModel.callLogsAddressToDelete = historyViewModel.displayedCall!.toAddress!.asStringUriOnly() + } else { + historyListViewModel.callLogsAddressToDelete = historyViewModel.displayedCall!.fromAddress!.asStringUriOnly() + } + + isShowDeleteAllHistoryPopup.toggle() + + } label: { + HStack { + Text("Delete history") + Spacer() + Image("trash-simple-red") + .resizable() + .frame(width: 25, height: 25, alignment: .leading) + .padding(.all, 10) + } + } + } label: { + Image("dots-three-vertical") + .renderingMode(.template) .resizable() + .foregroundStyle(Color.orangeMain500) .frame(width: 25, height: 25, alignment: .leading) .padding(.all, 10) } + .padding(.leading) + .onTapGesture { + isMenuOpen = true + } } + .frame(maxWidth: .infinity) + .frame(height: 50) + .padding(.horizontal) + .padding(.bottom, 4) + .background(.white) - Button { - isMenuOpen = false - - if historyViewModel.displayedCall != nil && historyViewModel.displayedCall!.dir == .Outgoing { - UIPasteboard.general.setValue( - historyViewModel.displayedCall!.toAddress!.asStringUriOnly().dropFirst(4), - forPasteboardType: UTType.plainText.identifier - ) - } else { - UIPasteboard.general.setValue( - historyViewModel.displayedCall!.fromAddress!.asStringUriOnly().dropFirst(4), - forPasteboardType: UTType.plainText.identifier - ) - } - - ToastViewModel.shared.toastMessage = "Success_copied_into_clipboard" - ToastViewModel.shared.displayToast.toggle() - - } label: { - HStack { - Text("Copy SIP address") - Spacer() - Image("copy") - .resizable() - .frame(width: 25, height: 25, alignment: .leading) - .padding(.all, 10) - } - } - - Button(role: .destructive) { - isMenuOpen = false - - if historyViewModel.displayedCall != nil && historyViewModel.displayedCall!.dir == .Outgoing { - historyListViewModel.callLogsAddressToDelete = historyViewModel.displayedCall!.toAddress!.asStringUriOnly() - } else { - historyListViewModel.callLogsAddressToDelete = historyViewModel.displayedCall!.fromAddress!.asStringUriOnly() - } - - isShowDeleteAllHistoryPopup.toggle() - - } label: { - HStack { - Text("Delete history") - Spacer() - Image("trash-simple-red") - .resizable() - .frame(width: 25, height: 25, alignment: .leading) - .padding(.all, 10) - } - } - } label: { - Image("dots-three-vertical") - .renderingMode(.template) - .resizable() - .foregroundStyle(Color.orangeMain500) - .frame(width: 25, height: 25, alignment: .leading) - .padding(.all, 10) - } - .padding(.leading) - .onTapGesture { - isMenuOpen = true - } - } - .frame(maxWidth: .infinity) - .frame(height: 50) - .padding(.horizontal) - .padding(.bottom, 4) - .background(.white) - - ScrollView { - VStack(spacing: 0) { - VStack(spacing: 0) { - if #unavailable(iOS 16.0) { - Rectangle() - .foregroundColor(Color.gray100) - .frame(height: 7) - } + ScrollView { VStack(spacing: 0) { - let fromAddressFriend = historyViewModel.displayedCall != nil ? contactsManager.getFriendWithAddress(address: historyViewModel.displayedCall!.fromAddress!) : nil - let toAddressFriend = historyViewModel.displayedCall != nil ? contactsManager.getFriendWithAddress(address: historyViewModel.displayedCall!.toAddress!) : nil - let addressFriend = historyViewModel.displayedCall != nil ? (historyViewModel.displayedCall!.dir == .Incoming ? fromAddressFriend : toAddressFriend) : nil - - if historyViewModel.displayedCall != nil - && addressFriend != nil - && addressFriend!.photo != nil - && !addressFriend!.photo!.isEmpty { - Avatar(contactAvatarModel: contactAvatarModel, avatarSize: 100) - } else if historyViewModel.displayedCall != nil { - if historyViewModel.displayedCall!.dir == .Outgoing && historyViewModel.displayedCall!.toAddress != nil { - if historyViewModel.displayedCall!.toAddress!.displayName != nil { - Image(uiImage: contactsManager.textToImage( - firstName: historyViewModel.displayedCall!.toAddress!.displayName!, - lastName: historyViewModel.displayedCall!.toAddress!.displayName!.components(separatedBy: " ").count > 1 - ? historyViewModel.displayedCall!.toAddress!.displayName!.components(separatedBy: " ")[1] - : "")) - .resizable() - .frame(width: 100, height: 100) - .clipShape(Circle()) - - Text(historyViewModel.displayedCall!.toAddress!.displayName!) - .foregroundStyle(Color.grayMain2c700) - .multilineTextAlignment(.center) - .default_text_style(styleSize: 14) - .frame(maxWidth: .infinity) - .padding(.top, 10) - - Text(historyViewModel.displayedCall!.toAddress!.asStringUriOnly()) - .foregroundStyle(Color.grayMain2c700) - .multilineTextAlignment(.center) - .default_text_style(styleSize: 14) - .frame(maxWidth: .infinity) - .padding(.top, 5) - - Text("") - .multilineTextAlignment(.center) - .default_text_style_300(styleSize: 12) - .frame(maxWidth: .infinity) - .frame(height: 20) - } else { - Image(uiImage: contactsManager.textToImage( - firstName: historyViewModel.displayedCall!.toAddress!.username ?? "Username Error", - lastName: historyViewModel.displayedCall!.toAddress!.username!.components(separatedBy: " ").count > 1 - ? historyViewModel.displayedCall!.toAddress!.username!.components(separatedBy: " ")[1] - : "")) - .resizable() - .frame(width: 100, height: 100) - .clipShape(Circle()) - - Text(historyViewModel.displayedCall!.toAddress!.username ?? "Username Error") - .foregroundStyle(Color.grayMain2c700) - .multilineTextAlignment(.center) - .default_text_style(styleSize: 14) - .frame(maxWidth: .infinity) - .padding(.top, 10) - - Text(historyViewModel.displayedCall!.toAddress!.asStringUriOnly()) - .foregroundStyle(Color.grayMain2c700) - .multilineTextAlignment(.center) - .default_text_style(styleSize: 14) - .frame(maxWidth: .infinity) - .padding(.top, 5) - - Text("") - .multilineTextAlignment(.center) - .default_text_style_300(styleSize: 12) - .frame(maxWidth: .infinity) - .frame(height: 20) - } - - } else if historyViewModel.displayedCall!.fromAddress != nil { - if historyViewModel.displayedCall!.fromAddress!.displayName != nil { - Image(uiImage: contactsManager.textToImage( - firstName: historyViewModel.displayedCall!.fromAddress!.displayName!, - lastName: historyViewModel.displayedCall!.fromAddress!.displayName!.components(separatedBy: " ").count > 1 - ? historyViewModel.displayedCall!.fromAddress!.displayName!.components(separatedBy: " ")[1] - : "")) - .resizable() - .frame(width: 100, height: 100) - .clipShape(Circle()) - - Text(historyViewModel.displayedCall!.fromAddress!.displayName!) - .foregroundStyle(Color.grayMain2c700) - .multilineTextAlignment(.center) - .default_text_style(styleSize: 14) - .frame(maxWidth: .infinity) - .padding(.top, 10) - - Text(historyViewModel.displayedCall!.fromAddress!.asStringUriOnly()) - .foregroundStyle(Color.grayMain2c700) - .multilineTextAlignment(.center) - .default_text_style(styleSize: 14) - .frame(maxWidth: .infinity) - .padding(.top, 5) - - Text("") - .multilineTextAlignment(.center) - .default_text_style_300(styleSize: 12) - .frame(maxWidth: .infinity) - .frame(height: 20) - } else { - Image(uiImage: contactsManager.textToImage( - firstName: historyViewModel.displayedCall!.fromAddress!.username ?? "Username Error", - lastName: historyViewModel.displayedCall!.fromAddress!.username!.components(separatedBy: " ").count > 1 - ? historyViewModel.displayedCall!.fromAddress!.username!.components(separatedBy: " ")[1] - : "")) - .resizable() - .frame(width: 100, height: 100) - .clipShape(Circle()) - - Text(historyViewModel.displayedCall!.fromAddress!.username ?? "Username Error") - .foregroundStyle(Color.grayMain2c700) - .multilineTextAlignment(.center) - .default_text_style(styleSize: 14) - .frame(maxWidth: .infinity) - .padding(.top, 10) - - Text(historyViewModel.displayedCall!.fromAddress!.asStringUriOnly()) - .foregroundStyle(Color.grayMain2c700) - .multilineTextAlignment(.center) - .default_text_style(styleSize: 14) - .frame(maxWidth: .infinity) - .padding(.top, 5) - - Text("") - .multilineTextAlignment(.center) - .default_text_style_300(styleSize: 12) - .frame(maxWidth: .infinity) - .frame(height: 20) - } + VStack(spacing: 0) { + if #unavailable(iOS 16.0) { + Rectangle() + .foregroundColor(Color.gray100) + .frame(height: 7) } - } - if historyViewModel.displayedCall != nil - && addressFriend != nil - && addressFriend!.name != nil { - Text((addressFriend!.name)!) - .foregroundStyle(Color.grayMain2c700) - .multilineTextAlignment(.center) - .default_text_style(styleSize: 14) - .frame(maxWidth: .infinity) - .padding(.top, 10) - - if historyViewModel.displayedCall!.dir == .Outgoing && historyViewModel.displayedCall!.toAddress != nil { - Text(historyViewModel.displayedCall!.toAddress!.asStringUriOnly()) - .foregroundStyle(Color.grayMain2c700) - .multilineTextAlignment(.center) - .default_text_style(styleSize: 14) - .frame(maxWidth: .infinity) - .padding(.top, 5) - } else if historyViewModel.displayedCall!.fromAddress != nil { - Text(historyViewModel.displayedCall!.fromAddress!.asStringUriOnly()) - .foregroundStyle(Color.grayMain2c700) - .multilineTextAlignment(.center) - .default_text_style(styleSize: 14) - .frame(maxWidth: .infinity) - .padding(.top, 5) - } - - Text(contactAvatarModel.lastPresenceInfo) - .foregroundStyle(contactAvatarModel.lastPresenceInfo == "Online" - ? Color.greenSuccess500 - : Color.orangeWarning600) - .multilineTextAlignment(.center) - .default_text_style_300(styleSize: 12) - .frame(maxWidth: .infinity) - .frame(height: 20) - .padding(.top, 5) - } - } - .frame(minHeight: 150) - .frame(maxWidth: .infinity) - .padding(.top, 10) - .padding(.bottom, 2) - .background(Color.gray100) - - HStack { - Spacer() - - Button(action: { - if historyViewModel.displayedCall!.dir == .Outgoing && historyViewModel.displayedCall!.toAddress != nil { - telecomManager.doCallWithCore( - addr: historyViewModel.displayedCall!.toAddress!, isVideo: false, isConference: false - ) - } else if historyViewModel.displayedCall!.dir == .Incoming && historyViewModel.displayedCall!.fromAddress != nil { - telecomManager.doCallWithCore( - addr: historyViewModel.displayedCall!.fromAddress!, isVideo: false, isConference: false - ) - } - }, label: { - VStack { - HStack(alignment: .center) { - Image("phone") - .renderingMode(.template) - .resizable() - .foregroundStyle(Color.grayMain2c600) - .frame(width: 25, height: 25) - } - .padding(16) - .background(Color.grayMain2c200) - .cornerRadius(40) - - Text("Appel") - .default_text_style(styleSize: 14) - .frame(minWidth: 80) - } - }) - - Spacer() - - Button(action: { - - }, label: { - VStack { - HStack(alignment: .center) { - Image("chat-teardrop-text") - .renderingMode(.template) - .resizable() - //.foregroundStyle(Color.grayMain2c600) - .foregroundStyle(Color.grayMain2c300) - .frame(width: 25, height: 25) - .onTapGesture { - withAnimation { + VStack(spacing: 0) { + if historyViewModel.displayedCallIsConference.isEmpty { + let fromAddressFriend = historyViewModel.displayedCall != nil ? contactsManager.getFriendWithAddress(address: historyViewModel.displayedCall!.fromAddress!) : nil + let toAddressFriend = historyViewModel.displayedCall != nil ? contactsManager.getFriendWithAddress(address: historyViewModel.displayedCall!.toAddress!) : nil + let addressFriend = historyViewModel.displayedCall != nil ? (historyViewModel.displayedCall!.dir == .Incoming ? fromAddressFriend : toAddressFriend) : nil + + if historyViewModel.displayedCall != nil + && addressFriend != nil + && addressFriend!.photo != nil + && !addressFriend!.photo!.isEmpty { + Avatar(contactAvatarModel: contactAvatarModel, avatarSize: 100) + } else if historyViewModel.displayedCall != nil { + if historyViewModel.displayedCall!.dir == .Outgoing && historyViewModel.displayedCall!.toAddress != nil { + if historyViewModel.displayedCall!.toAddress!.displayName != nil { + Image(uiImage: contactsManager.textToImage( + firstName: historyViewModel.displayedCall!.toAddress!.displayName!, + lastName: historyViewModel.displayedCall!.toAddress!.displayName!.components(separatedBy: " ").count > 1 + ? historyViewModel.displayedCall!.toAddress!.displayName!.components(separatedBy: " ")[1] + : "")) + .resizable() + .frame(width: 100, height: 100) + .clipShape(Circle()) + Text(historyViewModel.displayedCall!.toAddress!.displayName!) + .foregroundStyle(Color.grayMain2c700) + .multilineTextAlignment(.center) + .default_text_style(styleSize: 14) + .frame(maxWidth: .infinity) + .padding(.top, 10) + + Text(historyViewModel.displayedCall!.toAddress!.asStringUriOnly()) + .foregroundStyle(Color.grayMain2c700) + .multilineTextAlignment(.center) + .default_text_style(styleSize: 14) + .frame(maxWidth: .infinity) + .padding(.top, 5) + + Text("") + .multilineTextAlignment(.center) + .default_text_style_300(styleSize: 12) + .frame(maxWidth: .infinity) + .frame(height: 20) + } else { + Image(uiImage: contactsManager.textToImage( + firstName: historyViewModel.displayedCall!.toAddress!.username ?? "Username Error", + lastName: historyViewModel.displayedCall!.toAddress!.username!.components(separatedBy: " ").count > 1 + ? historyViewModel.displayedCall!.toAddress!.username!.components(separatedBy: " ")[1] + : "")) + .resizable() + .frame(width: 100, height: 100) + .clipShape(Circle()) + + Text(historyViewModel.displayedCall!.toAddress!.username ?? "Username Error") + .foregroundStyle(Color.grayMain2c700) + .multilineTextAlignment(.center) + .default_text_style(styleSize: 14) + .frame(maxWidth: .infinity) + .padding(.top, 10) + + Text(historyViewModel.displayedCall!.toAddress!.asStringUriOnly()) + .foregroundStyle(Color.grayMain2c700) + .multilineTextAlignment(.center) + .default_text_style(styleSize: 14) + .frame(maxWidth: .infinity) + .padding(.top, 5) + + Text("") + .multilineTextAlignment(.center) + .default_text_style_300(styleSize: 12) + .frame(maxWidth: .infinity) + .frame(height: 20) + } + + } else if historyViewModel.displayedCall!.fromAddress != nil { + if historyViewModel.displayedCall!.fromAddress!.displayName != nil { + Image(uiImage: contactsManager.textToImage( + firstName: historyViewModel.displayedCall!.fromAddress!.displayName!, + lastName: historyViewModel.displayedCall!.fromAddress!.displayName!.components(separatedBy: " ").count > 1 + ? historyViewModel.displayedCall!.fromAddress!.displayName!.components(separatedBy: " ")[1] + : "")) + .resizable() + .frame(width: 100, height: 100) + .clipShape(Circle()) + + Text(historyViewModel.displayedCall!.fromAddress!.displayName!) + .foregroundStyle(Color.grayMain2c700) + .multilineTextAlignment(.center) + .default_text_style(styleSize: 14) + .frame(maxWidth: .infinity) + .padding(.top, 10) + + Text(historyViewModel.displayedCall!.fromAddress!.asStringUriOnly()) + .foregroundStyle(Color.grayMain2c700) + .multilineTextAlignment(.center) + .default_text_style(styleSize: 14) + .frame(maxWidth: .infinity) + .padding(.top, 5) + + Text("") + .multilineTextAlignment(.center) + .default_text_style_300(styleSize: 12) + .frame(maxWidth: .infinity) + .frame(height: 20) + } else { + Image(uiImage: contactsManager.textToImage( + firstName: historyViewModel.displayedCall!.fromAddress!.username ?? "Username Error", + lastName: historyViewModel.displayedCall!.fromAddress!.username!.components(separatedBy: " ").count > 1 + ? historyViewModel.displayedCall!.fromAddress!.username!.components(separatedBy: " ")[1] + : "")) + .resizable() + .frame(width: 100, height: 100) + .clipShape(Circle()) + + Text(historyViewModel.displayedCall!.fromAddress!.username ?? "Username Error") + .foregroundStyle(Color.grayMain2c700) + .multilineTextAlignment(.center) + .default_text_style(styleSize: 14) + .frame(maxWidth: .infinity) + .padding(.top, 10) + + Text(historyViewModel.displayedCall!.fromAddress!.asStringUriOnly()) + .foregroundStyle(Color.grayMain2c700) + .multilineTextAlignment(.center) + .default_text_style(styleSize: 14) + .frame(maxWidth: .infinity) + .padding(.top, 5) + + Text("") + .multilineTextAlignment(.center) + .default_text_style_300(styleSize: 12) + .frame(maxWidth: .infinity) + .frame(height: 20) } } + } + + if historyViewModel.displayedCall != nil + && addressFriend != nil + && addressFriend!.name != nil { + Text((addressFriend!.name)!) + .foregroundStyle(Color.grayMain2c700) + .multilineTextAlignment(.center) + .default_text_style(styleSize: 14) + .frame(maxWidth: .infinity) + .padding(.top, 10) + + if historyViewModel.displayedCall!.dir == .Outgoing && historyViewModel.displayedCall!.toAddress != nil { + Text(historyViewModel.displayedCall!.toAddress!.asStringUriOnly()) + .foregroundStyle(Color.grayMain2c700) + .multilineTextAlignment(.center) + .default_text_style(styleSize: 14) + .frame(maxWidth: .infinity) + .padding(.top, 5) + } else if historyViewModel.displayedCall!.fromAddress != nil { + Text(historyViewModel.displayedCall!.fromAddress!.asStringUriOnly()) + .foregroundStyle(Color.grayMain2c700) + .multilineTextAlignment(.center) + .default_text_style(styleSize: 14) + .frame(maxWidth: .infinity) + .padding(.top, 5) + } + + Text(contactAvatarModel.lastPresenceInfo) + .foregroundStyle(contactAvatarModel.lastPresenceInfo == "Online" + ? Color.greenSuccess500 + : Color.orangeWarning600) + .multilineTextAlignment(.center) + .default_text_style_300(styleSize: 12) + .frame(maxWidth: .infinity) + .frame(height: 20) + .padding(.top, 5) + } + } else { + VStack { + Image("users-three-square") + .renderingMode(.template) + .resizable() + .frame(width: 60, height: 60) + .foregroundStyle(Color.grayMain2c600) + } + .frame(width: 100, height: 100) + .background(Color.grayMain2c200) + .clipShape(Circle()) + + Text(historyViewModel.displayedCallIsConference ?? "") + .foregroundStyle(Color.grayMain2c700) + .multilineTextAlignment(.center) + .default_text_style(styleSize: 14) + .frame(maxWidth: .infinity) + .padding(.top, 10) } - .padding(16) - .background(Color.grayMain2c200) - .cornerRadius(40) - - Text("Message") - .default_text_style(styleSize: 14) - .frame(minWidth: 80) } - }) - - Spacer() - - Button(action: { - if historyViewModel.displayedCall!.dir == .Outgoing && historyViewModel.displayedCall!.toAddress != nil { - telecomManager.doCallWithCore( - addr: historyViewModel.displayedCall!.toAddress!, isVideo: true, isConference: false - ) - } else if historyViewModel.displayedCall!.dir == .Incoming && historyViewModel.displayedCall!.fromAddress != nil { - telecomManager.doCallWithCore( - addr: historyViewModel.displayedCall!.fromAddress!, isVideo: true, isConference: false - ) - } - }, label: { - VStack { - HStack(alignment: .center) { - Image("video-camera") - .renderingMode(.template) - .resizable() - .foregroundStyle(Color.grayMain2c600) - .frame(width: 25, height: 25) - } - .padding(16) - .background(Color.grayMain2c200) - .cornerRadius(40) - - Text("Video Call") - .default_text_style(styleSize: 14) - .frame(minWidth: 80) - } - }) - - Spacer() - } - .padding(.top, 20) - .padding(.bottom, 10) - .frame(maxWidth: .infinity) - .background(Color.gray100) - - VStack(spacing: 0) { - - let addressFriend = historyViewModel.displayedCall != nil - ? (historyViewModel.displayedCall!.dir == .Incoming ? historyViewModel.displayedCall!.fromAddress!.asStringUriOnly() - : historyViewModel.displayedCall!.toAddress!.asStringUriOnly()) : nil - - let callLogsFilter = historyListViewModel.callLogs.filter({ $0.dir == .Incoming - ? $0.fromAddress!.asStringUriOnly() == addressFriend - : $0.toAddress!.asStringUriOnly() == addressFriend }) - - ForEach(0.. 1 - ? historyListViewModel.callLogs[index].toAddress!.displayName!.components(separatedBy: " ")[1] - : "")) - .resizable() - .frame(width: 45, height: 45) - .clipShape(Circle()) - - } else { - Image(uiImage: contactsManager.textToImage( - firstName: historyListViewModel.callLogs[index].toAddress!.username ?? "Username Error", - lastName: historyListViewModel.callLogs[index].toAddress!.username!.components(separatedBy: " ").count > 1 - ? historyListViewModel.callLogs[index].toAddress!.username!.components(separatedBy: " ")[1] - : "")) - .resizable() - .frame(width: 45, height: 45) - .clipShape(Circle()) - } - - } else if historyListViewModel.callLogs[index].fromAddress != nil { - if historyListViewModel.callLogs[index].fromAddress!.displayName != nil { - Image(uiImage: contactsManager.textToImage( - firstName: historyListViewModel.callLogs[index].fromAddress!.displayName!, - lastName: historyListViewModel.callLogs[index].fromAddress!.displayName!.components(separatedBy: " ").count > 1 - ? historyListViewModel.callLogs[index].fromAddress!.displayName!.components(separatedBy: " ")[1] - : "")) - .resizable() - .frame(width: 45, height: 45) - .clipShape(Circle()) - } else { - Image(uiImage: contactsManager.textToImage( - firstName: historyListViewModel.callLogs[index].fromAddress!.username ?? "Username Error", - lastName: historyListViewModel.callLogs[index].fromAddress!.username!.components(separatedBy: " ").count > 1 - ? historyListViewModel.callLogs[index].fromAddress!.username!.components(separatedBy: " ")[1] - : "")) - .resizable() - .frame(width: 45, height: 45) - .clipShape(Circle()) - } - } else { - Image("profil-picture-default") - .resizable() - .frame(width: 45, height: 45) - .clipShape(Circle()) - } - } - - VStack(spacing: 0) { - Spacer() - + if historyListViewModel.callLogsIsConference[index].isEmpty { let fromAddressFriend = contactsManager.getFriendWithAddress(address: historyListViewModel.callLogs[index].fromAddress!) let toAddressFriend = contactsManager.getFriendWithAddress(address: historyListViewModel.callLogs[index].toAddress!) let addressFriend = historyListViewModel.callLogs[index].dir == .Incoming ? fromAddressFriend : toAddressFriend - if addressFriend != nil { - Text(addressFriend!.name!) - .default_text_style(styleSize: 14) - .frame(maxWidth: .infinity, alignment: .leading) - .lineLimit(1) + 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: "", 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: 45, height: 45) + .clipShape(Circle()) + } } else { if historyListViewModel.callLogs[index].dir == .Outgoing && historyListViewModel.callLogs[index].toAddress != nil { - Text(historyListViewModel.callLogs[index].toAddress!.displayName != nil - ? historyListViewModel.callLogs[index].toAddress!.displayName! - : historyListViewModel.callLogs[index].toAddress!.username!) + if historyListViewModel.callLogs[index].toAddress!.displayName != nil { + Image(uiImage: contactsManager.textToImage( + firstName: historyListViewModel.callLogs[index].toAddress!.displayName!, + lastName: historyListViewModel.callLogs[index].toAddress!.displayName!.components(separatedBy: " ").count > 1 + ? historyListViewModel.callLogs[index].toAddress!.displayName!.components(separatedBy: " ")[1] + : "")) + .resizable() + .frame(width: 45, height: 45) + .clipShape(Circle()) + + } else { + Image(uiImage: contactsManager.textToImage( + firstName: historyListViewModel.callLogs[index].toAddress!.username ?? "Username Error", + lastName: historyListViewModel.callLogs[index].toAddress!.username!.components(separatedBy: " ").count > 1 + ? historyListViewModel.callLogs[index].toAddress!.username!.components(separatedBy: " ")[1] + : "")) + .resizable() + .frame(width: 45, height: 45) + .clipShape(Circle()) + } + + } else if historyListViewModel.callLogs[index].fromAddress != nil { + if historyListViewModel.callLogs[index].fromAddress!.displayName != nil { + Image(uiImage: contactsManager.textToImage( + firstName: historyListViewModel.callLogs[index].fromAddress!.displayName!, + lastName: historyListViewModel.callLogs[index].fromAddress!.displayName!.components(separatedBy: " ").count > 1 + ? historyListViewModel.callLogs[index].fromAddress!.displayName!.components(separatedBy: " ")[1] + : "")) + .resizable() + .frame(width: 45, height: 45) + .clipShape(Circle()) + } else { + Image(uiImage: contactsManager.textToImage( + firstName: historyListViewModel.callLogs[index].fromAddress!.username ?? "Username Error", + lastName: historyListViewModel.callLogs[index].fromAddress!.username!.components(separatedBy: " ").count > 1 + ? historyListViewModel.callLogs[index].fromAddress!.username!.components(separatedBy: " ")[1] + : "")) + .resizable() + .frame(width: 45, height: 45) + .clipShape(Circle()) + } + } else { + Image("profil-picture-default") + .resizable() + .frame(width: 45, height: 45) + .clipShape(Circle()) + } + } + } else { + VStack { + Image("users-three-square") + .renderingMode(.template) + .resizable() + .frame(width: 28, height: 28) + .foregroundStyle(Color.grayMain2c600) + } + .frame(width: 45, height: 45) + .background(Color.grayMain2c200) + .clipShape(Circle()) + } + + VStack(spacing: 0) { + Spacer() + if historyListViewModel.callLogsIsConference[index].isEmpty { + let fromAddressFriend = contactsManager.getFriendWithAddress(address: historyListViewModel.callLogs[index].fromAddress!) + let toAddressFriend = contactsManager.getFriendWithAddress(address: historyListViewModel.callLogs[index].toAddress!) + let addressFriend = historyListViewModel.callLogs[index].dir == .Incoming ? fromAddressFriend : toAddressFriend + + if addressFriend != nil { + Text(addressFriend!.name!) .default_text_style(styleSize: 14) .frame(maxWidth: .infinity, alignment: .leading) .lineLimit(1) - } else if historyListViewModel.callLogs[index].fromAddress != nil { - Text(historyListViewModel.callLogs[index].fromAddress!.displayName != nil - ? historyListViewModel.callLogs[index].fromAddress!.displayName! - : historyListViewModel.callLogs[index].fromAddress!.username!) - .default_text_style(styleSize: 14) - .frame(maxWidth: .infinity, alignment: .leading) - .lineLimit(1) + } else { + if historyListViewModel.callLogs[index].dir == .Outgoing && historyListViewModel.callLogs[index].toAddress != nil { + Text(historyListViewModel.callLogs[index].toAddress!.displayName != nil + ? historyListViewModel.callLogs[index].toAddress!.displayName! + : historyListViewModel.callLogs[index].toAddress!.username!) + .default_text_style(styleSize: 14) + .frame(maxWidth: .infinity, alignment: .leading) + .lineLimit(1) + } else if historyListViewModel.callLogs[index].fromAddress != nil { + Text(historyListViewModel.callLogs[index].fromAddress!.displayName != nil + ? historyListViewModel.callLogs[index].fromAddress!.displayName! + : historyListViewModel.callLogs[index].fromAddress!.username!) + .default_text_style(styleSize: 14) + .frame(maxWidth: .infinity, alignment: .leading) + .lineLimit(1) + } } + } else { + Text(historyListViewModel.callLogsIsConference[index]) + .default_text_style(styleSize: 14) + .frame(maxWidth: .infinity, alignment: .leading) + .lineLimit(1) } + HStack { Image(historyListViewModel.getCallIconResId(callStatus: historyListViewModel.callLogs[index].status, callDir: historyListViewModel.callLogs[index].dir)) - .resizable() - .frame( - width: historyListViewModel.getCallIconResId(callStatus: historyListViewModel.callLogs[index].status, callDir: historyListViewModel.callLogs[index].dir).contains("rejected") ? 12 : 8, - height: historyListViewModel.getCallIconResId(callStatus: historyListViewModel.callLogs[index].status, callDir: historyListViewModel.callLogs[index].dir).contains("rejected") ? 6 : 8) + .resizable() + .frame( + width: historyListViewModel.getCallIconResId(callStatus: historyListViewModel.callLogs[index].status, callDir: historyListViewModel.callLogs[index].dir).contains("rejected") ? 12 : 8, + height: historyListViewModel.getCallIconResId(callStatus: historyListViewModel.callLogs[index].status, callDir: historyListViewModel.callLogs[index].dir).contains("rejected") ? 6 : 8) Text(historyListViewModel.getCallTime(startDate: historyListViewModel.callLogs[index].startDate)) - .default_text_style_300(styleSize: 12) - .frame(maxWidth: .infinity, alignment: .leading) + .default_text_style_300(styleSize: 12) + .frame(maxWidth: .infinity, alignment: .leading) Spacer() } @@ -156,20 +176,22 @@ struct HistoryListFragment: View { Spacer() } - Image("phone") - .resizable() - .frame(width: 25, height: 25) - .padding(.all, 10) - .padding(.trailing, 5) - .highPriorityGesture( - TapGesture() - .onEnded { _ in - withAnimation { - doCall(index: index) - historyViewModel.displayedCall = nil + if historyListViewModel.callLogsIsConference[index].isEmpty { + Image("phone") + .resizable() + .frame(width: 25, height: 25) + .padding(.all, 10) + .padding(.trailing, 5) + .highPriorityGesture( + TapGesture() + .onEnded { _ in + withAnimation { + doCall(index: index) + historyViewModel.displayedCall = nil + } } - } - ) + ) + } } } .buttonStyle(.borderless) @@ -179,6 +201,7 @@ struct HistoryListFragment: View { .onTapGesture { withAnimation { historyViewModel.displayedCall = historyListViewModel.callLogs[index] + historyViewModel.getConferenceSubject() } } .onLongPressGesture(minimumDuration: 0.2) { diff --git a/Linphone/UI/Main/History/ViewModel/HistoryListViewModel.swift b/Linphone/UI/Main/History/ViewModel/HistoryListViewModel.swift index cf9132158..480c3c3f2 100644 --- a/Linphone/UI/Main/History/ViewModel/HistoryListViewModel.swift +++ b/Linphone/UI/Main/History/ViewModel/HistoryListViewModel.swift @@ -25,6 +25,7 @@ class HistoryListViewModel: ObservableObject { private var coreContext = CoreContext.shared @Published var callLogs: [CallLog] = [] + @Published var callLogsIsConference: [String] = [] var callLogsTmp: [CallLog] = [] var callLogsAddressToDelete = "" @@ -42,28 +43,46 @@ class HistoryListViewModel: ObservableObject { let account = core.defaultAccount let logs = account?.callLogs != nil ? account!.callLogs : core.callLogs + var callLogsBis: [CallLog] = [] + var callLogsIsConferenceBis: [String] = [] + var callLogsTmpBis: [CallLog] = [] + + logs.forEach { log in + callLogsBis.append(log) + callLogsIsConferenceBis.append(log.conferenceInfo != nil && log.conferenceInfo!.subject != nil ? log.conferenceInfo!.subject! : "") + callLogsTmpBis.append(log) + } + DispatchQueue.main.async { self.callLogs.removeAll() self.callLogsTmp.removeAll() - logs.forEach { log in - self.callLogs.append(log) - self.callLogsTmp.append(log) - } + self.callLogs = callLogsBis + self.callLogsIsConference = callLogsIsConferenceBis + self.callLogsTmp = callLogsTmpBis } self.callLogSubscription = core.publisher?.onCallLogUpdated?.postOnCoreQueue { (_: (_: Core, _: CallLog)) in let account = core.defaultAccount - let logs = account != nil ? account!.callLogs : core.callLogs + let logs = account?.callLogs != nil ? account!.callLogs : core.callLogs + + var callLogsBis: [CallLog] = [] + var callLogsIsConferenceBis: [String] = [] + var callLogsTmpBis: [CallLog] = [] + + logs.forEach { log in + callLogsBis.append(log) + callLogsIsConferenceBis.append(log.conferenceInfo != nil && log.conferenceInfo!.subject != nil ? log.conferenceInfo!.subject! : "") + callLogsTmpBis.append(log) + } DispatchQueue.main.async { self.callLogs.removeAll() self.callLogsTmp.removeAll() - logs.forEach { log in - self.callLogs.append(log) - self.callLogsTmp.append(log) - } + self.callLogs = callLogsBis + self.callLogsIsConference = callLogsIsConferenceBis + self.callLogsTmp = callLogsTmpBis } self.updateMissedCallsCount() diff --git a/Linphone/UI/Main/History/ViewModel/HistoryViewModel.swift b/Linphone/UI/Main/History/ViewModel/HistoryViewModel.swift index 02425274d..cfbdf6d27 100644 --- a/Linphone/UI/Main/History/ViewModel/HistoryViewModel.swift +++ b/Linphone/UI/Main/History/ViewModel/HistoryViewModel.swift @@ -23,8 +23,22 @@ import linphonesw class HistoryViewModel: ObservableObject { @Published var displayedCall: CallLog? + @Published var displayedCallIsConference: String = "" var selectedCall: CallLog? init() {} + + func getConferenceSubject() { + CoreContext.shared.doOnCoreQueue { core in + var displayedCallIsConferenceTmp = "" + if self.displayedCall?.conferenceInfo != nil { + displayedCallIsConferenceTmp = self.displayedCall?.conferenceInfo?.subject ?? "" + } + + DispatchQueue.main.async { + self.displayedCallIsConference = displayedCallIsConferenceTmp + } + } + } }