From 375c8b0ce6f0f1d93a55251e6a845c6079b496ed Mon Sep 17 00:00:00 2001 From: Benoit Martins Date: Thu, 16 Nov 2023 16:59:10 +0100 Subject: [PATCH] Add history call detail --- Linphone/Localizable.xcstrings | 6 +- Linphone/UI/Main/ContentView.swift | 9 +- .../Fragments/HistoryContactFragment.swift | 409 +++++++++++++++++- .../Fragments/HistoryListFragment.swift | 40 +- .../History/ViewModel/HistoryViewModel.swift | 2 +- 5 files changed, 418 insertions(+), 48 deletions(-) diff --git a/Linphone/Localizable.xcstrings b/Linphone/Localizable.xcstrings index 695ac7218..dda26ce71 100644 --- a/Linphone/Localizable.xcstrings +++ b/Linphone/Localizable.xcstrings @@ -145,6 +145,9 @@ }, "Block the number" : { + }, + "Call history" : { + }, "Calls" : { @@ -253,9 +256,6 @@ }, "First name*" : { - }, - "History Contact fragment" : { - }, "I prefere create an account" : { diff --git a/Linphone/UI/Main/ContentView.swift b/Linphone/UI/Main/ContentView.swift index 6c677de8a..62f76caca 100644 --- a/Linphone/UI/Main/ContentView.swift +++ b/Linphone/UI/Main/ContentView.swift @@ -61,6 +61,7 @@ struct ContentView: View { Spacer() Button(action: { self.index = 0 + historyViewModel.displayedCall = nil }, label: { VStack { Image("address-book") @@ -178,7 +179,6 @@ struct ContentView: View { Button(role: .destructive) { isMenuOpen = false isShowDeleteAllHistoryPopup.toggle() - //historyListViewModel.removeCallLogs() } label: { HStack { Text("Delete all history") @@ -353,6 +353,7 @@ struct ContentView: View { Spacer() Button(action: { self.index = 0 + historyViewModel.displayedCall = nil }, label: { VStack { Image("address-book") @@ -405,7 +406,7 @@ struct ContentView: View { } } - if contactViewModel.indexDisplayedFriend != nil || historyViewModel.indexDisplayedCall != nil { + if contactViewModel.indexDisplayedFriend != nil || historyViewModel.displayedCall != nil { HStack(spacing: 0) { Spacer() .frame(maxWidth: @@ -426,7 +427,7 @@ struct ContentView: View { .background(Color.gray100) .ignoresSafeArea(.keyboard) } else if self.index == 1 { - HistoryContactFragment() + HistoryContactFragment(historyViewModel: historyViewModel, isShowDeleteAllHistoryPopup: $isShowDeleteAllHistoryPopup) .frame(maxWidth: .infinity) .background(Color.gray100) .ignoresSafeArea(.keyboard) @@ -581,7 +582,7 @@ struct ContentView: View { } } .onRotate { newOrientation in - if (contactViewModel.indexDisplayedFriend != nil || historyViewModel.indexDisplayedCall != nil) && searchIsActive { + if (contactViewModel.indexDisplayedFriend != nil || historyViewModel.displayedCall != nil) && searchIsActive { self.focusedField = false } else if searchIsActive { self.focusedField = true diff --git a/Linphone/UI/Main/History/Fragments/HistoryContactFragment.swift b/Linphone/UI/Main/History/Fragments/HistoryContactFragment.swift index ef7dc3419..97489fb0b 100644 --- a/Linphone/UI/Main/History/Fragments/HistoryContactFragment.swift +++ b/Linphone/UI/Main/History/Fragments/HistoryContactFragment.swift @@ -20,15 +20,410 @@ import SwiftUI struct HistoryContactFragment: View { - var body: some View { - VStack { - Spacer() - Text("History Contact fragment") - Spacer() + + @State private var orientation = UIDevice.current.orientation + + @ObservedObject var sharedMainViewModel = SharedMainViewModel() + @ObservedObject var historyViewModel: HistoryViewModel + + @State var isMenuOpen = false + + @Binding var isShowDeleteAllHistoryPopup: Bool + + 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(.top, 2) + .onTapGesture { + withAnimation { + historyViewModel.displayedCall = nil + } + } + } + + Text("Call history") + .default_text_style_orange_800(styleSize: 20) + + Spacer() + + Menu { + Button { + isMenuOpen = false + } label: { + HStack { + Text("See all") + Spacer() + Image("green-check") + .resizable() + .frame(width: 25, height: 25, alignment: .leading) + } + } + + Button { + isMenuOpen = false + } label: { + HStack { + Text("See Linphone contact") + Spacer() + Image("green-check") + .resizable() + .frame(width: 25, height: 25, alignment: .leading) + } + } + + Button(role: .destructive) { + isMenuOpen = false + } label: { + HStack { + Text("Delete all history") + Spacer() + Image("trash-simple-red") + .resizable() + .frame(width: 25, height: 25, alignment: .leading) + } + } + } label: { + Image("dots-three-vertical") + .renderingMode(.template) + .resizable() + .foregroundStyle(Color.orangeMain500) + .frame(width: 25, height: 25, alignment: .leading) + } + .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) { + VStack(spacing: 0) { + + let fromAddressFriend = historyViewModel.displayedCall != nil ? ContactsManager.shared.getFriendWithAddress(address: historyViewModel.displayedCall!.fromAddress!) : nil + let toAddressFriend = historyViewModel.displayedCall != nil ? ContactsManager.shared.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 { + AsyncImage( + url: ContactsManager.shared.getImagePath( + friendPhotoPath: addressFriend!.photo!)) { image in + switch image { + case .empty: + ProgressView() + .frame(width: 100, height: 100) + case .success(let image): + image + .resizable() + .aspectRatio(contentMode: .fill) + .frame(width: 100, height: 100) + .clipShape(Circle()) + case .failure: + Image("profil-picture-default") + .resizable() + .frame(width: 100, height: 100) + .clipShape(Circle()) + @unknown default: + EmptyView() + } + } + } else if historyViewModel.displayedCall != nil { + if historyViewModel.displayedCall!.dir == .Outgoing && historyViewModel.displayedCall!.toAddress != nil { + if historyViewModel.displayedCall!.toAddress!.displayName != nil { + Image(uiImage: ContactsManager.shared.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("") + .multilineTextAlignment(.center) + .default_text_style_300(styleSize: 12) + .frame(maxWidth: .infinity) + .frame(height: 20) + } else { + Image(uiImage: ContactsManager.shared.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("") + .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.shared.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("") + .multilineTextAlignment(.center) + .default_text_style_300(styleSize: 12) + .frame(maxWidth: .infinity) + .frame(height: 20) + } else { + Image(uiImage: ContactsManager.shared.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("") + .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) + + Text("En ligne") + .foregroundStyle(Color.greenSuccess500) + .multilineTextAlignment(.center) + .default_text_style_300(styleSize: 12) + .frame(maxWidth: .infinity) + .frame(height: 20) + } + } + .frame(minHeight: 150) + .frame(maxWidth: .infinity) + .padding(.top, 10) + .background(Color.gray100) + + HStack { + Spacer() + + Button(action: { + }, label: { + VStack { + HStack(alignment: .center) { + Image("phone") + .renderingMode(.template) + .resizable() + .foregroundStyle(Color.grayMain2c600) + .frame(width: 25, height: 25) + .onTapGesture { + withAnimation { + + } + } + } + .padding(16) + .background(Color.grayMain2c200) + .cornerRadius(40) + + Text("Appel") + .default_text_style(styleSize: 14) + } + }) + + Spacer() + + Button(action: { + + }, label: { + VStack { + HStack(alignment: .center) { + Image("chat-teardrop-text") + .renderingMode(.template) + .resizable() + .foregroundStyle(Color.grayMain2c600) + .frame(width: 25, height: 25) + .onTapGesture { + withAnimation { + + } + } + } + .padding(16) + .background(Color.grayMain2c200) + .cornerRadius(40) + + Text("Message") + .default_text_style(styleSize: 14) + } + }) + + Spacer() + + Button(action: { + + }, label: { + VStack { + HStack(alignment: .center) { + Image("video-camera") + .renderingMode(.template) + .resizable() + .foregroundStyle(Color.grayMain2c600) + .frame(width: 25, height: 25) + .onTapGesture { + withAnimation { + + } + } + } + .padding(16) + .background(Color.grayMain2c200) + .cornerRadius(40) + + Text("Video Call") + .default_text_style(styleSize: 14) + } + }) + + Spacer() + } + .padding(.top, 20) + .frame(maxWidth: .infinity) + .background(Color.gray100) + + VStack(spacing: 0) { + + let fromAddressFriend = historyViewModel.displayedCall != nil ? ContactsManager.shared.getFriendWithAddress(address: historyViewModel.displayedCall!.fromAddress!) : nil + let toAddressFriend = historyViewModel.displayedCall != nil ? ContactsManager.shared.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 != nil { + ForEach(0..