From 0e635ec9fcbe416b27810cb116f7efef14b06f18 Mon Sep 17 00:00:00 2001 From: Benoit Martins Date: Fri, 13 Dec 2024 11:51:33 +0100 Subject: [PATCH] Remove NavigationView in ContentView --- Linphone/UI/Main/ContentView.swift | 2182 ++++++++--------- .../Fragments/AccountProfileFragment.swift | 526 ++-- 2 files changed, 1351 insertions(+), 1357 deletions(-) diff --git a/Linphone/UI/Main/ContentView.swift b/Linphone/UI/Main/ContentView.swift index 6e6728ad6..1f29cd241 100644 --- a/Linphone/UI/Main/ContentView.swift +++ b/Linphone/UI/Main/ContentView.swift @@ -83,601 +83,53 @@ struct ContentView: View { var body: some View { let pub = NotificationCenter.default .publisher(for: NSNotification.Name("ContactLoaded")) - NavigationView { - GeometryReader { geometry in - VStack(spacing: 0) { - if (telecomManager.callInProgress && !fullscreenVideo && ((!telecomManager.callDisplayed && callViewModel.callsCounter == 1) || callViewModel.callsCounter > 1)) || isShowConversationFragment { - HStack { - Image("phone") - .renderingMode(.template) - .resizable() - .foregroundStyle(.white) - .frame(width: 26, height: 26) - .padding(.leading, 10) - - if callViewModel.callsCounter > 1 { - Text(String(format: String(localized: "calls_count_label"), callViewModel.callsCounter)) - .default_text_style_white(styleSize: 16) - } else { - Text("\(callViewModel.displayName)") - .default_text_style_white(styleSize: 16) - } - - Spacer() - - if callViewModel.callsCounter == 1 { - Text(String(localized: "\(callViewModel.isPaused || telecomManager.isPausedByRemote ? "call_state_paused" : "call_state_connected")")) - .default_text_style_white(styleSize: 16) - .padding(.trailing, 10) - } + GeometryReader { geometry in + VStack(spacing: 0) { + if (telecomManager.callInProgress && !fullscreenVideo && ((!telecomManager.callDisplayed && callViewModel.callsCounter == 1) || callViewModel.callsCounter > 1)) || isShowConversationFragment { + HStack { + Image("phone") + .renderingMode(.template) + .resizable() + .foregroundStyle(.white) + .frame(width: 26, height: 26) + .padding(.leading, 10) + + if callViewModel.callsCounter > 1 { + Text(String(format: String(localized: "calls_count_label"), callViewModel.callsCounter)) + .default_text_style_white(styleSize: 16) + } else { + Text("\(callViewModel.displayName)") + .default_text_style_white(styleSize: 16) } - .frame(maxWidth: .infinity) - .frame(height: 30) - .background(Color.greenSuccess500) - .onTapGesture { - withAnimation { - telecomManager.callDisplayed = true - } + + Spacer() + + if callViewModel.callsCounter == 1 { + Text(String(localized: "\(callViewModel.isPaused || telecomManager.isPausedByRemote ? "call_state_paused" : "call_state_connected")")) + .default_text_style_white(styleSize: 16) + .padding(.trailing, 10) } } - - ZStack { - VStack(spacing: 0) { - HStack(spacing: 0) { - if orientation == .landscapeLeft - || orientation == .landscapeRight - || UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height { - VStack(spacing: 0) { - Group { - Spacer() - - Button(action: { - self.index = 0 - historyViewModel.displayedCall = nil - conversationViewModel.displayedConversation = nil - meetingViewModel.displayedMeeting = nil - }, label: { - VStack { - Image("address-book") - .renderingMode(.template) - .resizable() - .foregroundStyle(self.index == 0 ? Color.orangeMain500 : Color.grayMain2c600) - .frame(width: 25, height: 25) - if self.index == 0 { - Text("bottom_navigation_contacts_label") - .default_text_style_700(styleSize: 10) - } else { - Text("bottom_navigation_contacts_label") - .default_text_style(styleSize: 10) - } - } - }) - .padding(.top) - .frame(height: geometry.size.height/4) - - ZStack { - if historyListViewModel.missedCallsCount > 0 { - VStack { - HStack { - Text( - historyListViewModel.missedCallsCount < 99 - ? String(historyListViewModel.missedCallsCount) - : "99+" - ) - .foregroundStyle(.white) - .default_text_style(styleSize: 10) - .lineLimit(1) - } - .frame(width: 18, height: 18) - .background(Color.redDanger500) - .cornerRadius(50) - } - .padding(.bottom, 30) - .padding(.leading, 30) - } - - Button(action: { - self.index = 1 - contactViewModel.indexDisplayedFriend = nil - conversationViewModel.displayedConversation = nil - meetingViewModel.displayedMeeting = nil - if historyListViewModel.missedCallsCount > 0 { - historyListViewModel.resetMissedCallsCount() - } - }, label: { - VStack { - Image("phone") - .renderingMode(.template) - .resizable() - .foregroundStyle(self.index == 1 ? Color.orangeMain500 : Color.grayMain2c600) - .frame(width: 25, height: 25) - if self.index == 1 { - Text("bottom_navigation_calls_label") - .default_text_style_700(styleSize: 10) - } else { - Text("bottom_navigation_calls_label") - .default_text_style(styleSize: 10) - } - } - }) - .padding(.top) - } - .frame(height: geometry.size.height/4) - - ZStack { - if conversationsListViewModel.unreadMessages > 0 { - VStack { - HStack { - Text( - conversationsListViewModel.unreadMessages < 99 - ? String(conversationsListViewModel.unreadMessages) - : "99+" - ) - .foregroundStyle(.white) - .default_text_style(styleSize: 10) - .lineLimit(1) - } - .frame(width: 18, height: 18) - .background(Color.redDanger500) - .cornerRadius(50) - } - .padding(.bottom, 30) - .padding(.leading, 30) - } - - Button(action: { - self.index = 2 - historyViewModel.displayedCall = nil - contactViewModel.indexDisplayedFriend = nil - meetingViewModel.displayedMeeting = nil - }, label: { - VStack { - Image("chat-teardrop-text") - .renderingMode(.template) - .resizable() - .foregroundStyle(self.index == 2 ? Color.orangeMain500 : Color.grayMain2c600) - .frame(width: 25, height: 25) - - if self.index == 2 { - Text("bottom_navigation_conversations_label") - .default_text_style_700(styleSize: 10) - } else { - Text("bottom_navigation_conversations_label") - .default_text_style(styleSize: 10) - } - } - }) - .padding(.top) - } - .frame(height: geometry.size.height/4) - - Button(action: { - self.index = 3 - contactViewModel.indexDisplayedFriend = nil - historyViewModel.displayedCall = nil - conversationViewModel.displayedConversation = nil - }, label: { - VStack { - Image("video-conference") - .renderingMode(.template) - .resizable() - .foregroundStyle(self.index == 3 ? Color.orangeMain500 : Color.grayMain2c600) - .frame(width: 25, height: 25) - if self.index == 0 { - Text("bottom_navigation_meetings_label") - .default_text_style_700(styleSize: 10) - } else { - Text("bottom_navigation_meetings_label") - .default_text_style(styleSize: 10) - } - } - }) - .padding(.top) - .frame(height: geometry.size.height/4) - - Spacer() - } - } - .frame(width: 75, height: geometry.size.height) - .padding(.leading, - orientation == .landscapeRight && geometry.safeAreaInsets.bottom > 0 - ? -geometry.safeAreaInsets.leading - : 0) - } - + .frame(maxWidth: .infinity) + .frame(height: 30) + .background(Color.greenSuccess500) + .onTapGesture { + withAnimation { + telecomManager.callDisplayed = true + } + } + } + + ZStack { + VStack(spacing: 0) { + HStack(spacing: 0) { + if orientation == .landscapeLeft + || orientation == .landscapeRight + || UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height { VStack(spacing: 0) { - Rectangle() - .foregroundColor(Color.orangeMain500) - .edgesIgnoringSafeArea(.top) - .frame(height: 1) - - ZStack { - VStack { - Rectangle() - .foregroundColor( - (orientation == .landscapeLeft - || orientation == .landscapeRight - || UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height) - ? Color.white - : Color.orangeMain500 - ) - .frame(height: 100) - - Spacer() - } - - VStack(spacing: 0) { - if searchIsActive == false { - HStack { - AsyncImage(url: accountProfileViewModel.getImagePath()) { image in - switch image { - case .empty: - ProgressView() - .frame(width: avatarSize, height: avatarSize) - case .success(let image): - image - .resizable() - .aspectRatio(contentMode: .fill) - .frame(width: avatarSize, height: avatarSize) - .clipShape(Circle()) - case .failure: - Image(uiImage: contactsManager.textToImage( - firstName: accountProfileViewModel.avatarModel?.name ?? "", - lastName: "")) - .resizable() - .frame(width: avatarSize, height: avatarSize) - .clipShape(Circle()) - @unknown default: - EmptyView() - } - } - .onTapGesture { - openMenu() - } - - Text(String(localized: index == 0 ? "bottom_navigation_contacts_label" : (index == 1 ? "bottom_navigation_calls_label" : (index == 2 ? "bottom_navigation_conversations_label" : "bottom_navigation_meetings_label")))) - .default_text_style_white_800(styleSize: 20) - .padding(.leading, 10) - - Spacer() - - Button { - withAnimation { - searchIsActive.toggle() - } - } label: { - Image("magnifying-glass") - .renderingMode(.template) - .resizable() - .foregroundStyle(.white) - .frame(width: 25, height: 25, alignment: .leading) - .padding(.all, 10) - } - .padding(.trailing, index == 2 ? 10 : 0) - - if index == 3 { - Button { - NotificationCenter.default.post(name: MeetingsListViewModel.ScrollToTodayNotification, object: nil) - } label: { - Image("calendar") - .renderingMode(.template) - .resizable() - .foregroundStyle(.white) - .frame(width: 25, height: 25, alignment: .leading) - .padding(.all, 10) - } - .padding(.trailing, 10) - } else if index != 2 { - Menu { - if index == 0 { - Button { - contactViewModel.indexDisplayedFriend = nil - isMenuOpen = false - magicSearch.allContact = true - MagicSearchSingleton.shared.searchForContacts( - sourceFlags: MagicSearch.Source.Friends.rawValue | MagicSearch.Source.LdapServers.rawValue) - } label: { - HStack { - Text("contacts_list_filter_popup_see_all") - Spacer() - if magicSearch.allContact { - Image("green-check") - .resizable() - .frame(width: 25, height: 25, alignment: .leading) - .padding(.all, 10) - } - } - } - - Button { - contactViewModel.indexDisplayedFriend = nil - isMenuOpen = false - magicSearch.allContact = false - MagicSearchSingleton.shared.searchForContacts( - sourceFlags: MagicSearch.Source.Friends.rawValue | MagicSearch.Source.LdapServers.rawValue) - } label: { - HStack { - Text(String(format: String(localized: "contacts_list_filter_popup_see_linphone_only"), Bundle.main.displayName)) - Spacer() - if !magicSearch.allContact { - Image("green-check") - .resizable() - .frame(width: 25, height: 25, alignment: .leading) - .padding(.all, 10) - } - } - } - } else { - Button(role: .destructive) { - isMenuOpen = false - isShowDeleteAllHistoryPopup.toggle() - } label: { - HStack { - Text("menu_delete_history") - Spacer() - Image("trash-simple-red") - .resizable() - .frame(width: 25, height: 25, alignment: .leading) - .padding(.all, 10) - } - } - } - } label: { - Image(index == 0 ? "funnel" : "dots-three-vertical") - .renderingMode(.template) - .resizable() - .foregroundStyle(.white) - .frame(width: 25, height: 25, alignment: .leading) - .padding(.all, 10) - } - .padding(.trailing, 10) - .onTapGesture { - isMenuOpen = true - } - } - } - .frame(maxWidth: .infinity) - .frame(height: 50) - .padding(.leading) - .padding(.top, 2.5) - .padding(.bottom, 2.5) - .background(Color.orangeMain500) - .roundedCorner(10, corners: [.bottomRight, .bottomLeft]) - } else { - HStack { - Button { - withAnimation { - self.focusedField = false - searchIsActive.toggle() - } - - text = "" - - if index == 0 { - magicSearch.currentFilter = "" - MagicSearchSingleton.shared.searchForContacts( - sourceFlags: MagicSearch.Source.Friends.rawValue | MagicSearch.Source.LdapServers.rawValue) - } else if index == 1 { - historyListViewModel.resetFilterCallLogs() - } else if index == 2 { - conversationsListViewModel.resetFilterConversations() - } else if index == 3 { - meetingsListViewModel.currentFilter = "" - meetingsListViewModel.computeMeetingsList() - } - } label: { - Image("caret-left") - .renderingMode(.template) - .resizable() - .foregroundStyle(.white) - .frame(width: 25, height: 25, alignment: .leading) - .padding(.all, 10) - .padding(.leading, -10) - } - - if #available(iOS 16.0, *) { - TextEditor(text: Binding( - get: { - return text - }, - set: { value in - var newValue = value - if value.contains("\n") { - newValue = value.replacingOccurrences(of: "\n", with: "") - } - text = newValue - } - )) - .default_text_style_white_700(styleSize: 15) - .padding(.all, 6) - .disableAutocorrection(true) - .autocapitalization(.none) - .accentColor(.white) - .scrollContentBackground(.hidden) - .focused($focusedField) - .onAppear { - self.focusedField = true - } - .onChange(of: text) { newValue in - if index == 0 { - magicSearch.currentFilter = newValue - MagicSearchSingleton.shared.searchForContacts( - sourceFlags: MagicSearch.Source.Friends.rawValue | MagicSearch.Source.LdapServers.rawValue) - } else if index == 1 { - if text.isEmpty { - historyListViewModel.resetFilterCallLogs() - } else { - historyListViewModel.filterCallLogs(filter: text) - } - } else if index == 2 { - if text.isEmpty { - conversationsListViewModel.resetFilterConversations() - } else { - conversationsListViewModel.filterConversations(filter: text) - } - } else if index == 3 { - meetingsListViewModel.currentFilter = text - meetingsListViewModel.computeMeetingsList() - } - } - } else { - TextEditor(text: Binding( - get: { - return text - }, - set: { value in - var newValue = value - if value.contains("\n") { - newValue = value.replacingOccurrences(of: "\n", with: "") - } - text = newValue - } - )) - .default_text_style_700(styleSize: 15) - .padding(.all, 6) - .focused($focusedField) - .disableAutocorrection(true) - .autocapitalization(.none) - .onAppear { - self.focusedField = true - } - .onChange(of: text) { newValue in - if index == 0 { - magicSearch.currentFilter = newValue - MagicSearchSingleton.shared.searchForContacts( - sourceFlags: MagicSearch.Source.Friends.rawValue | MagicSearch.Source.LdapServers.rawValue) - } else if index == 1 { - historyListViewModel.filterCallLogs(filter: text) - } else if index == 2 { - conversationsListViewModel.filterConversations(filter: text) - } else if index == 3 { - meetingsListViewModel.currentFilter = text - meetingsListViewModel.computeMeetingsList() - } - } - } - - Button { - text = "" - } label: { - Image("x") - .renderingMode(.template) - .resizable() - .foregroundStyle(.white) - .frame(width: 25, height: 25, alignment: .leading) - .padding(.all, 10) - } - .padding(.leading) - } - .frame(maxWidth: .infinity) - .frame(height: 50) - .padding(.horizontal) - .padding(.bottom, 5) - .background(Color.orangeMain500) - .roundedCorner(10, corners: [.bottomRight, .bottomLeft]) - } - - if self.index == 0 { - ContactsView( - contactViewModel: contactViewModel, - historyViewModel: historyViewModel, - editContactViewModel: editContactViewModel, - isShowEditContactFragment: $isShowEditContactFragment, - isShowDeletePopup: $isShowDeleteContactPopup, - text: $text - ) - .roundedCorner(25, corners: [.topRight, .topLeft]) - .shadow( - color: (orientation == .landscapeLeft - || orientation == .landscapeRight - || UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height) - ? .white.opacity(0.0) - : .black.opacity(0.2), - radius: 25 - ) - } else if self.index == 1 { - HistoryView( - historyListViewModel: historyListViewModel, - historyViewModel: historyViewModel, - contactViewModel: contactViewModel, - editContactViewModel: editContactViewModel, - index: $index, - isShowStartCallFragment: $isShowStartCallFragment, - isShowEditContactFragment: $isShowEditContactFragment, - text: $text - ) - .roundedCorner(25, corners: [.topRight, .topLeft]) - .shadow( - color: (orientation == .landscapeLeft - || orientation == .landscapeRight - || UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height) - ? .white.opacity(0.0) - : .black.opacity(0.2), - radius: 25 - ) - } else if self.index == 2 { - ConversationsView( - conversationViewModel: conversationViewModel, - conversationsListViewModel: conversationsListViewModel, - text: $text, - isShowStartConversationFragment: $isShowStartConversationFragment - ) - .roundedCorner(25, corners: [.topRight, .topLeft]) - .shadow( - color: (orientation == .landscapeLeft - || orientation == .landscapeRight - || UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height) - ? .white.opacity(0.0) - : .black.opacity(0.2), - radius: 25 - ) - } else if self.index == 3 { - MeetingsView( - meetingsListViewModel: meetingsListViewModel, - meetingViewModel: meetingViewModel, - isShowScheduleMeetingFragment: $isShowScheduleMeetingFragment, - isShowSendCancelMeetingNotificationPopup: $isShowSendCancelMeetingNotificationPopup, - text: $text - ) - .roundedCorner(25, corners: [.topRight, .topLeft]) - .shadow( - color: (orientation == .landscapeLeft - || orientation == .landscapeRight - || UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height) - ? .white.opacity(0.0) - : .black.opacity(0.2), - radius: 25 - ) - } - } - } - } - .frame(maxWidth: - (orientation == .landscapeLeft - || orientation == .landscapeRight - || UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height) - ? geometry.size.width/100*40 - : .infinity - ) - .background( - Color.white - .shadow(color: Color.gray200, radius: 4, x: 0, y: 0) - .mask(Rectangle().padding(.horizontal, -8)) - ) - - if orientation == .landscapeLeft - || orientation == .landscapeRight - || UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height { - Spacer() - } - } - - if !(orientation == .landscapeLeft - || orientation == .landscapeRight - || UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height) && !searchIsActive { - HStack { Group { Spacer() + Button(action: { self.index = 0 historyViewModel.displayedCall = nil @@ -700,9 +152,7 @@ struct ContentView: View { } }) .padding(.top) - .frame(width: 66) - - Spacer() + .frame(height: geometry.size.height/4) ZStack { if historyListViewModel.missedCallsCount > 0 { @@ -742,18 +192,16 @@ struct ContentView: View { .frame(width: 25, height: 25) if self.index == 1 { Text("bottom_navigation_calls_label") - .default_text_style_700(styleSize: 9) + .default_text_style_700(styleSize: 10) } else { Text("bottom_navigation_calls_label") - .default_text_style(styleSize: 9) + .default_text_style(styleSize: 10) } } }) .padding(.top) - .frame(width: 66) } - - Spacer() + .frame(height: geometry.size.height/4) ZStack { if conversationsListViewModel.unreadMessages > 0 { @@ -791,18 +239,17 @@ struct ContentView: View { if self.index == 2 { Text("bottom_navigation_conversations_label") - .default_text_style_700(styleSize: 9) + .default_text_style_700(styleSize: 10) } else { Text("bottom_navigation_conversations_label") - .default_text_style(styleSize: 9) + .default_text_style(styleSize: 10) } } }) .padding(.top) - .frame(width: 66) } + .frame(height: geometry.size.height/4) - Spacer() Button(action: { self.index = 3 contactViewModel.indexDisplayedFriend = nil @@ -815,532 +262,1083 @@ struct ContentView: View { .resizable() .foregroundStyle(self.index == 3 ? Color.orangeMain500 : Color.grayMain2c600) .frame(width: 25, height: 25) - if self.index == 3 { + if self.index == 0 { Text("bottom_navigation_meetings_label") - .default_text_style_700(styleSize: 9) + .default_text_style_700(styleSize: 10) } else { Text("bottom_navigation_meetings_label") + .default_text_style(styleSize: 10) + } + } + }) + .padding(.top) + .frame(height: geometry.size.height/4) + + Spacer() + } + } + .frame(width: 75, height: geometry.size.height) + .padding(.leading, + orientation == .landscapeRight && geometry.safeAreaInsets.bottom > 0 + ? -geometry.safeAreaInsets.leading + : 0) + } + + VStack(spacing: 0) { + Rectangle() + .foregroundColor(Color.orangeMain500) + .edgesIgnoringSafeArea(.top) + .frame(height: 1) + + ZStack { + VStack { + Rectangle() + .foregroundColor( + (orientation == .landscapeLeft + || orientation == .landscapeRight + || UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height) + ? Color.white + : Color.orangeMain500 + ) + .frame(height: 100) + + Spacer() + } + + VStack(spacing: 0) { + if searchIsActive == false { + HStack { + AsyncImage(url: accountProfileViewModel.getImagePath()) { image in + switch image { + case .empty: + ProgressView() + .frame(width: avatarSize, height: avatarSize) + case .success(let image): + image + .resizable() + .aspectRatio(contentMode: .fill) + .frame(width: avatarSize, height: avatarSize) + .clipShape(Circle()) + case .failure: + Image(uiImage: contactsManager.textToImage( + firstName: accountProfileViewModel.avatarModel?.name ?? "", + lastName: "")) + .resizable() + .frame(width: avatarSize, height: avatarSize) + .clipShape(Circle()) + @unknown default: + EmptyView() + } + } + .onTapGesture { + openMenu() + } + + Text(String(localized: index == 0 ? "bottom_navigation_contacts_label" : (index == 1 ? "bottom_navigation_calls_label" : (index == 2 ? "bottom_navigation_conversations_label" : "bottom_navigation_meetings_label")))) + .default_text_style_white_800(styleSize: 20) + .padding(.leading, 10) + + Spacer() + + Button { + withAnimation { + searchIsActive.toggle() + } + } label: { + Image("magnifying-glass") + .renderingMode(.template) + .resizable() + .foregroundStyle(.white) + .frame(width: 25, height: 25, alignment: .leading) + .padding(.all, 10) + } + .padding(.trailing, index == 2 ? 10 : 0) + + if index == 3 { + Button { + NotificationCenter.default.post(name: MeetingsListViewModel.ScrollToTodayNotification, object: nil) + } label: { + Image("calendar") + .renderingMode(.template) + .resizable() + .foregroundStyle(.white) + .frame(width: 25, height: 25, alignment: .leading) + .padding(.all, 10) + } + .padding(.trailing, 10) + } else if index != 2 { + Menu { + if index == 0 { + Button { + contactViewModel.indexDisplayedFriend = nil + isMenuOpen = false + magicSearch.allContact = true + MagicSearchSingleton.shared.searchForContacts( + sourceFlags: MagicSearch.Source.Friends.rawValue | MagicSearch.Source.LdapServers.rawValue) + } label: { + HStack { + Text("contacts_list_filter_popup_see_all") + Spacer() + if magicSearch.allContact { + Image("green-check") + .resizable() + .frame(width: 25, height: 25, alignment: .leading) + .padding(.all, 10) + } + } + } + + Button { + contactViewModel.indexDisplayedFriend = nil + isMenuOpen = false + magicSearch.allContact = false + MagicSearchSingleton.shared.searchForContacts( + sourceFlags: MagicSearch.Source.Friends.rawValue | MagicSearch.Source.LdapServers.rawValue) + } label: { + HStack { + Text(String(format: String(localized: "contacts_list_filter_popup_see_linphone_only"), Bundle.main.displayName)) + Spacer() + if !magicSearch.allContact { + Image("green-check") + .resizable() + .frame(width: 25, height: 25, alignment: .leading) + .padding(.all, 10) + } + } + } + } else { + Button(role: .destructive) { + isMenuOpen = false + isShowDeleteAllHistoryPopup.toggle() + } label: { + HStack { + Text("menu_delete_history") + Spacer() + Image("trash-simple-red") + .resizable() + .frame(width: 25, height: 25, alignment: .leading) + .padding(.all, 10) + } + } + } + } label: { + Image(index == 0 ? "funnel" : "dots-three-vertical") + .renderingMode(.template) + .resizable() + .foregroundStyle(.white) + .frame(width: 25, height: 25, alignment: .leading) + .padding(.all, 10) + } + .padding(.trailing, 10) + .onTapGesture { + isMenuOpen = true + } + } + } + .frame(maxWidth: .infinity) + .frame(height: 50) + .padding(.leading) + .padding(.top, 2.5) + .padding(.bottom, 2.5) + .background(Color.orangeMain500) + .roundedCorner(10, corners: [.bottomRight, .bottomLeft]) + } else { + HStack { + Button { + withAnimation { + self.focusedField = false + searchIsActive.toggle() + } + + text = "" + + if index == 0 { + magicSearch.currentFilter = "" + MagicSearchSingleton.shared.searchForContacts( + sourceFlags: MagicSearch.Source.Friends.rawValue | MagicSearch.Source.LdapServers.rawValue) + } else if index == 1 { + historyListViewModel.resetFilterCallLogs() + } else if index == 2 { + conversationsListViewModel.resetFilterConversations() + } else if index == 3 { + meetingsListViewModel.currentFilter = "" + meetingsListViewModel.computeMeetingsList() + } + } label: { + Image("caret-left") + .renderingMode(.template) + .resizable() + .foregroundStyle(.white) + .frame(width: 25, height: 25, alignment: .leading) + .padding(.all, 10) + .padding(.leading, -10) + } + + if #available(iOS 16.0, *) { + TextEditor(text: Binding( + get: { + return text + }, + set: { value in + var newValue = value + if value.contains("\n") { + newValue = value.replacingOccurrences(of: "\n", with: "") + } + text = newValue + } + )) + .default_text_style_white_700(styleSize: 15) + .padding(.all, 6) + .disableAutocorrection(true) + .autocapitalization(.none) + .accentColor(.white) + .scrollContentBackground(.hidden) + .focused($focusedField) + .onAppear { + self.focusedField = true + } + .onChange(of: text) { newValue in + if index == 0 { + magicSearch.currentFilter = newValue + MagicSearchSingleton.shared.searchForContacts( + sourceFlags: MagicSearch.Source.Friends.rawValue | MagicSearch.Source.LdapServers.rawValue) + } else if index == 1 { + if text.isEmpty { + historyListViewModel.resetFilterCallLogs() + } else { + historyListViewModel.filterCallLogs(filter: text) + } + } else if index == 2 { + if text.isEmpty { + conversationsListViewModel.resetFilterConversations() + } else { + conversationsListViewModel.filterConversations(filter: text) + } + } else if index == 3 { + meetingsListViewModel.currentFilter = text + meetingsListViewModel.computeMeetingsList() + } + } + } else { + TextEditor(text: Binding( + get: { + return text + }, + set: { value in + var newValue = value + if value.contains("\n") { + newValue = value.replacingOccurrences(of: "\n", with: "") + } + text = newValue + } + )) + .default_text_style_700(styleSize: 15) + .padding(.all, 6) + .focused($focusedField) + .disableAutocorrection(true) + .autocapitalization(.none) + .onAppear { + self.focusedField = true + } + .onChange(of: text) { newValue in + if index == 0 { + magicSearch.currentFilter = newValue + MagicSearchSingleton.shared.searchForContacts( + sourceFlags: MagicSearch.Source.Friends.rawValue | MagicSearch.Source.LdapServers.rawValue) + } else if index == 1 { + historyListViewModel.filterCallLogs(filter: text) + } else if index == 2 { + conversationsListViewModel.filterConversations(filter: text) + } else if index == 3 { + meetingsListViewModel.currentFilter = text + meetingsListViewModel.computeMeetingsList() + } + } + } + + Button { + text = "" + } label: { + Image("x") + .renderingMode(.template) + .resizable() + .foregroundStyle(.white) + .frame(width: 25, height: 25, alignment: .leading) + .padding(.all, 10) + } + .padding(.leading) + } + .frame(maxWidth: .infinity) + .frame(height: 50) + .padding(.horizontal) + .padding(.bottom, 5) + .background(Color.orangeMain500) + .roundedCorner(10, corners: [.bottomRight, .bottomLeft]) + } + + if self.index == 0 { + ContactsView( + contactViewModel: contactViewModel, + historyViewModel: historyViewModel, + editContactViewModel: editContactViewModel, + isShowEditContactFragment: $isShowEditContactFragment, + isShowDeletePopup: $isShowDeleteContactPopup, + text: $text + ) + .roundedCorner(25, corners: [.topRight, .topLeft]) + .shadow( + color: (orientation == .landscapeLeft + || orientation == .landscapeRight + || UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height) + ? .white.opacity(0.0) + : .black.opacity(0.2), + radius: 25 + ) + } else if self.index == 1 { + HistoryView( + historyListViewModel: historyListViewModel, + historyViewModel: historyViewModel, + contactViewModel: contactViewModel, + editContactViewModel: editContactViewModel, + index: $index, + isShowStartCallFragment: $isShowStartCallFragment, + isShowEditContactFragment: $isShowEditContactFragment, + text: $text + ) + .roundedCorner(25, corners: [.topRight, .topLeft]) + .shadow( + color: (orientation == .landscapeLeft + || orientation == .landscapeRight + || UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height) + ? .white.opacity(0.0) + : .black.opacity(0.2), + radius: 25 + ) + } else if self.index == 2 { + ConversationsView( + conversationViewModel: conversationViewModel, + conversationsListViewModel: conversationsListViewModel, + text: $text, + isShowStartConversationFragment: $isShowStartConversationFragment + ) + .roundedCorner(25, corners: [.topRight, .topLeft]) + .shadow( + color: (orientation == .landscapeLeft + || orientation == .landscapeRight + || UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height) + ? .white.opacity(0.0) + : .black.opacity(0.2), + radius: 25 + ) + } else if self.index == 3 { + MeetingsView( + meetingsListViewModel: meetingsListViewModel, + meetingViewModel: meetingViewModel, + isShowScheduleMeetingFragment: $isShowScheduleMeetingFragment, + isShowSendCancelMeetingNotificationPopup: $isShowSendCancelMeetingNotificationPopup, + text: $text + ) + .roundedCorner(25, corners: [.topRight, .topLeft]) + .shadow( + color: (orientation == .landscapeLeft + || orientation == .landscapeRight + || UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height) + ? .white.opacity(0.0) + : .black.opacity(0.2), + radius: 25 + ) + } + } + } + } + .frame(maxWidth: + (orientation == .landscapeLeft + || orientation == .landscapeRight + || UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height) + ? geometry.size.width/100*40 + : .infinity + ) + .background( + Color.white + .shadow(color: Color.gray200, radius: 4, x: 0, y: 0) + .mask(Rectangle().padding(.horizontal, -8)) + ) + + if orientation == .landscapeLeft + || orientation == .landscapeRight + || UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height { + Spacer() + } + } + + if !(orientation == .landscapeLeft + || orientation == .landscapeRight + || UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height) && !searchIsActive { + HStack { + Group { + Spacer() + Button(action: { + self.index = 0 + historyViewModel.displayedCall = nil + conversationViewModel.displayedConversation = nil + meetingViewModel.displayedMeeting = nil + }, label: { + VStack { + Image("address-book") + .renderingMode(.template) + .resizable() + .foregroundStyle(self.index == 0 ? Color.orangeMain500 : Color.grayMain2c600) + .frame(width: 25, height: 25) + if self.index == 0 { + Text("bottom_navigation_contacts_label") + .default_text_style_700(styleSize: 10) + } else { + Text("bottom_navigation_contacts_label") + .default_text_style(styleSize: 10) + } + } + }) + .padding(.top) + .frame(width: 66) + + Spacer() + + ZStack { + if historyListViewModel.missedCallsCount > 0 { + VStack { + HStack { + Text( + historyListViewModel.missedCallsCount < 99 + ? String(historyListViewModel.missedCallsCount) + : "99+" + ) + .foregroundStyle(.white) + .default_text_style(styleSize: 10) + .lineLimit(1) + } + .frame(width: 18, height: 18) + .background(Color.redDanger500) + .cornerRadius(50) + } + .padding(.bottom, 30) + .padding(.leading, 30) + } + + Button(action: { + self.index = 1 + contactViewModel.indexDisplayedFriend = nil + conversationViewModel.displayedConversation = nil + meetingViewModel.displayedMeeting = nil + if historyListViewModel.missedCallsCount > 0 { + historyListViewModel.resetMissedCallsCount() + } + }, label: { + VStack { + Image("phone") + .renderingMode(.template) + .resizable() + .foregroundStyle(self.index == 1 ? Color.orangeMain500 : Color.grayMain2c600) + .frame(width: 25, height: 25) + if self.index == 1 { + Text("bottom_navigation_calls_label") + .default_text_style_700(styleSize: 9) + } else { + Text("bottom_navigation_calls_label") .default_text_style(styleSize: 9) } } }) .padding(.top) .frame(width: 66) - - Spacer() } - } - .padding(.bottom, geometry.safeAreaInsets.bottom > 0 ? 0 : 15) - .background( - Color.white - .shadow(color: Color.gray200, radius: 4, x: 0, y: 0) - .mask(Rectangle().padding(.top, -8)) - ) - } - } - - if contactViewModel.indexDisplayedFriend != nil || historyViewModel.displayedCall != nil || conversationViewModel.displayedConversation != nil || - meetingViewModel.displayedMeeting != nil { - HStack(spacing: 0) { - Spacer() - .frame(maxWidth: - (orientation == .landscapeLeft - || orientation == .landscapeRight - || UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height) - ? (geometry.size.width/100*40) + 75 - : 0 - ) - if self.index == 0 { - ContactFragment( - contactViewModel: contactViewModel, - editContactViewModel: editContactViewModel, - conversationViewModel: conversationViewModel, - isShowDeletePopup: $isShowDeleteContactPopup, - isShowDismissPopup: $isShowDismissPopup, - isShowSipAddressesPopup: $isShowSipAddressesPopup, - isShowSipAddressesPopupType: $isShowSipAddressesPopupType - ) - .frame(maxWidth: .infinity) - .background(Color.gray100) - .ignoresSafeArea(.keyboard) - } else if self.index == 1 { - if historyViewModel.displayedCall != nil && historyViewModel.displayedCall!.avatarModel != nil { - HistoryContactFragment( - contactAvatarModel: historyViewModel.displayedCall!.avatarModel!, - historyViewModel: historyViewModel, - historyListViewModel: historyListViewModel, - contactViewModel: contactViewModel, - editContactViewModel: editContactViewModel, - isShowDeleteAllHistoryPopup: $isShowDeleteAllHistoryPopup, - isShowEditContactFragment: $isShowEditContactFragment, - indexPage: $index - ) - .frame(maxWidth: .infinity) - .background(Color.gray100) - .ignoresSafeArea(.keyboard) - } - } else if self.index == 2 { - ConversationFragment( - conversationViewModel: conversationViewModel, - conversationsListViewModel: conversationsListViewModel, - conversationForwardMessageViewModel: conversationForwardMessageViewModel, - contactViewModel: contactViewModel, - editContactViewModel: editContactViewModel, - meetingViewModel: meetingViewModel, - accountProfileViewModel: accountProfileViewModel, - isShowConversationFragment: $isShowConversationFragment, - isShowStartCallGroupPopup: $isShowStartCallGroupPopup, - isShowEditContactFragment: $isShowEditContactFragment, - indexPage: $index, - isShowScheduleMeetingFragment: $isShowScheduleMeetingFragment - ) - .frame(maxWidth: .infinity) - .background(Color.gray100) - .ignoresSafeArea(.keyboard) - } else if self.index == 3 { - MeetingFragment(meetingViewModel: meetingViewModel, meetingsListViewModel: meetingsListViewModel, isShowScheduleMeetingFragment: $isShowScheduleMeetingFragment, isShowSendCancelMeetingNotificationPopup: $isShowSendCancelMeetingNotificationPopup) - .frame(maxWidth: .infinity) - .background(Color.gray100) - .ignoresSafeArea(.keyboard) - } - - } - .onAppear { - if !(orientation == .landscapeLeft - || orientation == .landscapeRight - || UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height) - && searchIsActive { - self.focusedField = false - } - } - .onDisappear { - if !(orientation == .landscapeLeft - || orientation == .landscapeRight - || UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height) - && searchIsActive { - self.focusedField = true - } - } - .padding(.leading, - orientation == .landscapeRight && geometry.safeAreaInsets.bottom > 0 - ? -geometry.safeAreaInsets.leading - : 0) - .transition(.move(edge: .trailing)) - .zIndex(1) - } - - SideMenu( - accountProfileViewModel: accountProfileViewModel, - width: geometry.size.width / 5 * 4, - isOpen: self.sideMenuIsOpen, - menuClose: self.openMenu, - safeAreaInsets: geometry.safeAreaInsets, - isShowLoginFragment: $isShowLoginFragment, - isShowAccountProfileFragment: $isShowAccountProfileFragment - ) - .ignoresSafeArea(.all) - .zIndex(2) - - if isShowLoginFragment { - LoginFragment( - accountLoginViewModel: AccountLoginViewModel(), - isShowBack: true, - onBackPressed: { - withAnimation { - isShowLoginFragment.toggle() - } - }) - .zIndex(3) - .transition(.move(edge: .bottom)) - .onAppear { - } - } - - if isShowEditContactFragment { - EditContactFragment( - editContactViewModel: editContactViewModel, - contactViewModel: contactViewModel, - isShowEditContactFragment: $isShowEditContactFragment, - isShowDismissPopup: $isShowDismissPopup - ) - .zIndex(3) - .transition(.opacity.combined(with: .move(edge: .bottom))) - .onAppear { - contactViewModel.indexDisplayedFriend = nil - } - } - - if isShowStartCallFragment { - if #available(iOS 16.4, *), idiom != .pad { - StartCallFragment( - callViewModel: callViewModel, - startCallViewModel: startCallViewModel, - isShowStartCallFragment: $isShowStartCallFragment, - showingDialer: $showingDialer, - resetCallView: {callViewModel.resetCallView()} - ) - .zIndex(6) - .transition(.opacity.combined(with: .move(edge: .bottom))) - .sheet(isPresented: $showingDialer) { - DialerBottomSheet( - startCallViewModel: startCallViewModel, - callViewModel: callViewModel, - isShowStartCallFragment: $isShowStartCallFragment, - showingDialer: $showingDialer, - currentCall: nil - ) - .presentationDetents([.medium]) - .presentationBackgroundInteraction(.enabled(upThrough: .medium)) - } - } else { - StartCallFragment( - callViewModel: callViewModel, - startCallViewModel: startCallViewModel, - isShowStartCallFragment: $isShowStartCallFragment, - showingDialer: $showingDialer, - resetCallView: {callViewModel.resetCallView()} - ) - .zIndex(6) - .transition(.opacity.combined(with: .move(edge: .bottom))) - .halfSheet(showSheet: $showingDialer) { - DialerBottomSheet( - startCallViewModel: startCallViewModel, - callViewModel: callViewModel, - isShowStartCallFragment: $isShowStartCallFragment, - showingDialer: $showingDialer, - currentCall: nil - ) - } onDismiss: {} - } - } - - if isShowStartConversationFragment { - StartConversationFragment( - startConversationViewModel: startConversationViewModel, - conversationViewModel: conversationViewModel, - isShowStartConversationFragment: $isShowStartConversationFragment - ) - .zIndex(6) - .transition(.opacity.combined(with: .move(edge: .bottom))) - } - - if isShowDeleteContactPopup { - PopupView(isShowPopup: $isShowDeleteContactPopup, - title: Text(String(format: String(localized: "contact_dialog_delete_title"), contactViewModel.selectedFriend != nil - ? contactViewModel.selectedFriend!.name! - : (contactViewModel.indexDisplayedFriend != nil - ? contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.name! - : "Error Name"))), - content: Text("contact_dialog_delete_message"), - titleFirstButton: Text("dialog_cancel"), - actionFirstButton: { - self.isShowDeleteContactPopup.toggle()}, - titleSecondButton: Text("dialog_ok"), - actionSecondButton: { - if contactViewModel.selectedFriendToDelete != nil { - if contactViewModel.indexDisplayedFriend != nil { - withAnimation { - contactViewModel.indexDisplayedFriend = nil + + Spacer() + + ZStack { + if conversationsListViewModel.unreadMessages > 0 { + VStack { + HStack { + Text( + conversationsListViewModel.unreadMessages < 99 + ? String(conversationsListViewModel.unreadMessages) + : "99+" + ) + .foregroundStyle(.white) + .default_text_style(styleSize: 10) + .lineLimit(1) + } + .frame(width: 18, height: 18) + .background(Color.redDanger500) + .cornerRadius(50) + } + .padding(.bottom, 30) + .padding(.leading, 30) } + + Button(action: { + self.index = 2 + historyViewModel.displayedCall = nil + contactViewModel.indexDisplayedFriend = nil + meetingViewModel.displayedMeeting = nil + }, label: { + VStack { + Image("chat-teardrop-text") + .renderingMode(.template) + .resizable() + .foregroundStyle(self.index == 2 ? Color.orangeMain500 : Color.grayMain2c600) + .frame(width: 25, height: 25) + + if self.index == 2 { + Text("bottom_navigation_conversations_label") + .default_text_style_700(styleSize: 9) + } else { + Text("bottom_navigation_conversations_label") + .default_text_style(styleSize: 9) + } + } + }) + .padding(.top) + .frame(width: 66) } - contactViewModel.selectedFriendToDelete!.remove() - } else if contactViewModel.indexDisplayedFriend != nil { - let tmpIndex = contactViewModel.indexDisplayedFriend - withAnimation { - contactViewModel.indexDisplayedFriend = nil - } - contactsManager.lastSearch[tmpIndex!].friend!.remove() - } - MagicSearchSingleton.shared.searchForContacts( - sourceFlags: MagicSearch.Source.Friends.rawValue | MagicSearch.Source.LdapServers.rawValue) - self.isShowDeleteContactPopup.toggle() - }) - .background(.black.opacity(0.65)) - .zIndex(3) - .onTapGesture { - self.isShowDeleteContactPopup.toggle() - } - .onAppear { - contactViewModel.selectedFriendToDelete = contactViewModel.selectedFriend - } - } - - if isShowDeleteAllHistoryPopup { - PopupView(isShowPopup: $isShowDeleteContactPopup, - title: Text("history_dialog_delete_all_call_logs_title"), - content: Text("history_dialog_delete_all_call_logs_message"), - titleFirstButton: Text("dialog_cancel"), - actionFirstButton: { - self.isShowDeleteAllHistoryPopup.toggle() - historyListViewModel.callLogsAddressToDelete = "" - }, - titleSecondButton: Text("dialog_ok"), - actionSecondButton: { - historyListViewModel.removeCallLogs() - self.isShowDeleteAllHistoryPopup.toggle() - historyViewModel.displayedCall = nil - - ToastViewModel.shared.toastMessage = "Success_remove_call_logs" - ToastViewModel.shared.displayToast.toggle() - }) - .background(.black.opacity(0.65)) - .zIndex(3) - .onTapGesture { - self.isShowDeleteAllHistoryPopup.toggle() - } - } - - if isShowDismissPopup { - PopupView(isShowPopup: $isShowDismissPopup, - title: Text("contact_editor_dialog_abort_confirmation_title"), - content: Text("contact_editor_dialog_abort_confirmation_message"), - titleFirstButton: Text("dialog_cancel"), - actionFirstButton: {self.isShowDismissPopup.toggle()}, - titleSecondButton: Text("dialog_ok"), - actionSecondButton: { - if editContactViewModel.selectedEditFriend == nil { - self.isShowDismissPopup.toggle() - editContactViewModel.removePopup = true - editContactViewModel.resetValues() - withAnimation { - isShowEditContactFragment.toggle() - } - } else { - self.isShowDismissPopup.toggle() - editContactViewModel.resetValues() - withAnimation { - editContactViewModel.removePopup = true - } - } - }) - .background(.black.opacity(0.65)) - .zIndex(3) - .onTapGesture { - self.isShowDismissPopup.toggle() - } - } - - if isShowSipAddressesPopup { - SipAddressesPopup( - contactAvatarModel: ContactsManager.shared.avatarListModel[contactViewModel.indexDisplayedFriend != nil ? contactViewModel.indexDisplayedFriend! : 0], - contactViewModel: contactViewModel, - isShowSipAddressesPopup: $isShowSipAddressesPopup, - isShowSipAddressesPopupType: $isShowSipAddressesPopupType - ) - .background(.black.opacity(0.65)) - .zIndex(3) - .onTapGesture { - isShowSipAddressesPopup.toggle() - } - } - - if contactViewModel.operationInProgress { - PopupLoadingView() - .background(.black.opacity(0.65)) - .zIndex(3) - .onDisappear { - if contactViewModel.displayedConversation != nil { + + Spacer() + Button(action: { + self.index = 3 contactViewModel.indexDisplayedFriend = nil historyViewModel.displayedCall = nil - index = 2 - DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { - withAnimation { - self.conversationViewModel.changeDisplayedChatRoom(conversationModel: contactViewModel.displayedConversation!) + conversationViewModel.displayedConversation = nil + }, label: { + VStack { + Image("video-conference") + .renderingMode(.template) + .resizable() + .foregroundStyle(self.index == 3 ? Color.orangeMain500 : Color.grayMain2c600) + .frame(width: 25, height: 25) + if self.index == 3 { + Text("bottom_navigation_meetings_label") + .default_text_style_700(styleSize: 9) + } else { + Text("bottom_navigation_meetings_label") + .default_text_style(styleSize: 9) } - contactViewModel.displayedConversation = nil } - } + }) + .padding(.top) + .frame(width: 66) + + Spacer() } - } - - if isShowScheduleMeetingFragment { - ScheduleMeetingFragment( - meetingViewModel: meetingViewModel, - meetingsListViewModel: meetingsListViewModel, - isShowScheduleMeetingFragment: $isShowScheduleMeetingFragment + } + .padding(.bottom, geometry.safeAreaInsets.bottom > 0 ? 0 : 15) + .background( + Color.white + .shadow(color: Color.gray200, radius: 4, x: 0, y: 0) + .mask(Rectangle().padding(.top, -8)) ) - .zIndex(3) - .transition(.move(edge: .bottom)) - .onAppear { + } + } + + if contactViewModel.indexDisplayedFriend != nil || historyViewModel.displayedCall != nil || conversationViewModel.displayedConversation != nil || + meetingViewModel.displayedMeeting != nil { + HStack(spacing: 0) { + Spacer() + .frame(maxWidth: + (orientation == .landscapeLeft + || orientation == .landscapeRight + || UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height) + ? (geometry.size.width/100*40) + 75 + : 0 + ) + if self.index == 0 { + ContactFragment( + contactViewModel: contactViewModel, + editContactViewModel: editContactViewModel, + conversationViewModel: conversationViewModel, + isShowDeletePopup: $isShowDeleteContactPopup, + isShowDismissPopup: $isShowDismissPopup, + isShowSipAddressesPopup: $isShowSipAddressesPopup, + isShowSipAddressesPopupType: $isShowSipAddressesPopupType + ) + .frame(maxWidth: .infinity) + .background(Color.gray100) + .ignoresSafeArea(.keyboard) + } else if self.index == 1 { + if historyViewModel.displayedCall != nil && historyViewModel.displayedCall!.avatarModel != nil { + HistoryContactFragment( + contactAvatarModel: historyViewModel.displayedCall!.avatarModel!, + historyViewModel: historyViewModel, + historyListViewModel: historyListViewModel, + contactViewModel: contactViewModel, + editContactViewModel: editContactViewModel, + isShowDeleteAllHistoryPopup: $isShowDeleteAllHistoryPopup, + isShowEditContactFragment: $isShowEditContactFragment, + indexPage: $index + ) + .frame(maxWidth: .infinity) + .background(Color.gray100) + .ignoresSafeArea(.keyboard) + } + } else if self.index == 2 { + ConversationFragment( + conversationViewModel: conversationViewModel, + conversationsListViewModel: conversationsListViewModel, + conversationForwardMessageViewModel: conversationForwardMessageViewModel, + contactViewModel: contactViewModel, + editContactViewModel: editContactViewModel, + meetingViewModel: meetingViewModel, + accountProfileViewModel: accountProfileViewModel, + isShowConversationFragment: $isShowConversationFragment, + isShowStartCallGroupPopup: $isShowStartCallGroupPopup, + isShowEditContactFragment: $isShowEditContactFragment, + indexPage: $index, + isShowScheduleMeetingFragment: $isShowScheduleMeetingFragment + ) + .frame(maxWidth: .infinity) + .background(Color.gray100) + .ignoresSafeArea(.keyboard) + } else if self.index == 3 { + MeetingFragment(meetingViewModel: meetingViewModel, meetingsListViewModel: meetingsListViewModel, isShowScheduleMeetingFragment: $isShowScheduleMeetingFragment, isShowSendCancelMeetingNotificationPopup: $isShowSendCancelMeetingNotificationPopup) + .frame(maxWidth: .infinity) + .background(Color.gray100) + .ignoresSafeArea(.keyboard) + } + + } + .onAppear { + if !(orientation == .landscapeLeft + || orientation == .landscapeRight + || UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height) + && searchIsActive { + self.focusedField = false } } - - if isShowAccountProfileFragment { - AccountProfileFragment( - accountProfileViewModel: accountProfileViewModel, - registerViewModel: RegisterViewModel(), - isShowAccountProfileFragment: $isShowAccountProfileFragment - ) - .zIndex(3) - .transition(.move(edge: .trailing)) + .onDisappear { + if !(orientation == .landscapeLeft + || orientation == .landscapeRight + || UIScreen.main.bounds.size.width > UIScreen.main.bounds.size.height) + && searchIsActive { + self.focusedField = true + } } - - if isShowSendCancelMeetingNotificationPopup { - PopupView(isShowPopup: $isShowSendCancelMeetingNotificationPopup, - title: Text("meeting_schedule_cancel_dialog_title"), - content: Text("meeting_schedule_cancel_dialog_message"), - titleFirstButton: Text("dialog_cancel"), - actionFirstButton: { - meetingViewModel.displayedMeeting = nil - meetingsListViewModel.deleteSelectedMeeting() - self.isShowSendCancelMeetingNotificationPopup.toggle( - ) }, - titleSecondButton: Text("dialog_ok"), - actionSecondButton: { - meetingViewModel.displayedMeeting = nil - if let meetingToDelete = self.meetingsListViewModel.selectedMeetingToDelete { - self.meetingViewModel.cancelMeetingWithNotifications(meeting: meetingToDelete) - meetingsListViewModel.deleteSelectedMeeting() - self.isShowSendCancelMeetingNotificationPopup.toggle() + .padding(.leading, + orientation == .landscapeRight && geometry.safeAreaInsets.bottom > 0 + ? -geometry.safeAreaInsets.leading + : 0) + .transition(.move(edge: .trailing)) + .zIndex(1) + } + + SideMenu( + accountProfileViewModel: accountProfileViewModel, + width: geometry.size.width / 5 * 4, + isOpen: self.sideMenuIsOpen, + menuClose: self.openMenu, + safeAreaInsets: geometry.safeAreaInsets, + isShowLoginFragment: $isShowLoginFragment, + isShowAccountProfileFragment: $isShowAccountProfileFragment + ) + .ignoresSafeArea(.all) + .zIndex(2) + + if isShowLoginFragment { + LoginFragment( + accountLoginViewModel: AccountLoginViewModel(), + isShowBack: true, + onBackPressed: { + withAnimation { + isShowLoginFragment.toggle() } }) + .zIndex(3) + .transition(.move(edge: .bottom)) + .onAppear { + } + } + + if isShowEditContactFragment { + EditContactFragment( + editContactViewModel: editContactViewModel, + contactViewModel: contactViewModel, + isShowEditContactFragment: $isShowEditContactFragment, + isShowDismissPopup: $isShowDismissPopup + ) + .zIndex(3) + .transition(.opacity.combined(with: .move(edge: .bottom))) + .onAppear { + contactViewModel.indexDisplayedFriend = nil + } + } + + if isShowStartCallFragment { + if #available(iOS 16.4, *), idiom != .pad { + StartCallFragment( + callViewModel: callViewModel, + startCallViewModel: startCallViewModel, + isShowStartCallFragment: $isShowStartCallFragment, + showingDialer: $showingDialer, + resetCallView: {callViewModel.resetCallView()} + ) + .zIndex(6) + .transition(.opacity.combined(with: .move(edge: .bottom))) + .sheet(isPresented: $showingDialer) { + DialerBottomSheet( + startCallViewModel: startCallViewModel, + callViewModel: callViewModel, + isShowStartCallFragment: $isShowStartCallFragment, + showingDialer: $showingDialer, + currentCall: nil + ) + .presentationDetents([.medium]) + .presentationBackgroundInteraction(.enabled(upThrough: .medium)) + } + } else { + StartCallFragment( + callViewModel: callViewModel, + startCallViewModel: startCallViewModel, + isShowStartCallFragment: $isShowStartCallFragment, + showingDialer: $showingDialer, + resetCallView: {callViewModel.resetCallView()} + ) + .zIndex(6) + .transition(.opacity.combined(with: .move(edge: .bottom))) + .halfSheet(showSheet: $showingDialer) { + DialerBottomSheet( + startCallViewModel: startCallViewModel, + callViewModel: callViewModel, + isShowStartCallFragment: $isShowStartCallFragment, + showingDialer: $showingDialer, + currentCall: nil + ) + } onDismiss: {} + } + } + + if isShowStartConversationFragment { + StartConversationFragment( + startConversationViewModel: startConversationViewModel, + conversationViewModel: conversationViewModel, + isShowStartConversationFragment: $isShowStartConversationFragment + ) + .zIndex(6) + .transition(.opacity.combined(with: .move(edge: .bottom))) + } + + if isShowDeleteContactPopup { + PopupView(isShowPopup: $isShowDeleteContactPopup, + title: Text(String(format: String(localized: "contact_dialog_delete_title"),contactViewModel.selectedFriend != nil + ? contactViewModel.selectedFriend!.name! + : (contactViewModel.indexDisplayedFriend != nil + ? contactsManager.lastSearch[contactViewModel.indexDisplayedFriend!].friend!.name! + : "Error Name"))), + content: Text("contact_dialog_delete_message"), + titleFirstButton: Text("dialog_cancel"), + actionFirstButton: { + self.isShowDeleteContactPopup.toggle()}, + titleSecondButton: Text("dialog_ok"), + actionSecondButton: { + if contactViewModel.selectedFriendToDelete != nil { + if contactViewModel.indexDisplayedFriend != nil { + withAnimation { + contactViewModel.indexDisplayedFriend = nil + } + } + contactViewModel.selectedFriendToDelete!.remove() + } else if contactViewModel.indexDisplayedFriend != nil { + let tmpIndex = contactViewModel.indexDisplayedFriend + withAnimation { + contactViewModel.indexDisplayedFriend = nil + } + contactsManager.lastSearch[tmpIndex!].friend!.remove() + } + MagicSearchSingleton.shared.searchForContacts( + sourceFlags: MagicSearch.Source.Friends.rawValue | MagicSearch.Source.LdapServers.rawValue) + self.isShowDeleteContactPopup.toggle() + }) + .background(.black.opacity(0.65)) + .zIndex(3) + .onTapGesture { + self.isShowDeleteContactPopup.toggle() + } + .onAppear { + contactViewModel.selectedFriendToDelete = contactViewModel.selectedFriend + } + } + + if isShowDeleteAllHistoryPopup { + PopupView(isShowPopup: $isShowDeleteContactPopup, + title: Text("history_dialog_delete_all_call_logs_title"), + content: Text("history_dialog_delete_all_call_logs_message"), + titleFirstButton: Text("dialog_cancel"), + actionFirstButton: { + self.isShowDeleteAllHistoryPopup.toggle() + historyListViewModel.callLogsAddressToDelete = "" + }, + titleSecondButton: Text("dialog_ok"), + actionSecondButton: { + historyListViewModel.removeCallLogs() + self.isShowDeleteAllHistoryPopup.toggle() + historyViewModel.displayedCall = nil + + ToastViewModel.shared.toastMessage = "Success_remove_call_logs" + ToastViewModel.shared.displayToast.toggle() + }) + .background(.black.opacity(0.65)) + .zIndex(3) + .onTapGesture { + self.isShowDeleteAllHistoryPopup.toggle() + } + } + + if isShowDismissPopup { + PopupView(isShowPopup: $isShowDismissPopup, + title: Text("contact_editor_dialog_abort_confirmation_title"), + content: Text("contact_editor_dialog_abort_confirmation_message"), + titleFirstButton: Text("dialog_cancel"), + actionFirstButton: {self.isShowDismissPopup.toggle()}, + titleSecondButton: Text("dialog_ok"), + actionSecondButton: { + if editContactViewModel.selectedEditFriend == nil { + self.isShowDismissPopup.toggle() + editContactViewModel.removePopup = true + editContactViewModel.resetValues() + withAnimation { + isShowEditContactFragment.toggle() + } + } else { + self.isShowDismissPopup.toggle() + editContactViewModel.resetValues() + withAnimation { + editContactViewModel.removePopup = true + } + } + }) + .background(.black.opacity(0.65)) + .zIndex(3) + .onTapGesture { + self.isShowDismissPopup.toggle() + } + } + + if isShowSipAddressesPopup { + SipAddressesPopup( + contactAvatarModel: ContactsManager.shared.avatarListModel[contactViewModel.indexDisplayedFriend != nil ? contactViewModel.indexDisplayedFriend! : 0], + contactViewModel: contactViewModel, + isShowSipAddressesPopup: $isShowSipAddressesPopup, + isShowSipAddressesPopupType: $isShowSipAddressesPopupType + ) + .background(.black.opacity(0.65)) + .zIndex(3) + .onTapGesture { + isShowSipAddressesPopup.toggle() + } + } + + if contactViewModel.operationInProgress { + PopupLoadingView() .background(.black.opacity(0.65)) .zIndex(3) - .onTapGesture { + .onDisappear { + if contactViewModel.displayedConversation != nil { + contactViewModel.indexDisplayedFriend = nil + historyViewModel.displayedCall = nil + index = 2 + DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { + withAnimation { + self.conversationViewModel.changeDisplayedChatRoom(conversationModel: contactViewModel.displayedConversation!) + } + contactViewModel.displayedConversation = nil + } + } + } + } + + if isShowScheduleMeetingFragment { + ScheduleMeetingFragment( + meetingViewModel: meetingViewModel, + meetingsListViewModel: meetingsListViewModel, + isShowScheduleMeetingFragment: $isShowScheduleMeetingFragment + ) + .zIndex(3) + .transition(.move(edge: .bottom)) + .onAppear { + } + } + + if isShowAccountProfileFragment { + AccountProfileFragment( + accountProfileViewModel: accountProfileViewModel, + registerViewModel: RegisterViewModel(), + isShowAccountProfileFragment: $isShowAccountProfileFragment + ) + .zIndex(3) + .transition(.move(edge: .trailing)) + } + + if isShowSendCancelMeetingNotificationPopup { + PopupView(isShowPopup: $isShowSendCancelMeetingNotificationPopup, + title: Text("meeting_schedule_cancel_dialog_title"), + content: Text("meeting_schedule_cancel_dialog_message"), + titleFirstButton: Text("dialog_cancel"), + actionFirstButton: { + meetingViewModel.displayedMeeting = nil + meetingsListViewModel.deleteSelectedMeeting() + self.isShowSendCancelMeetingNotificationPopup.toggle( + ) }, + titleSecondButton: Text("dialog_ok"), + actionSecondButton: { + meetingViewModel.displayedMeeting = nil + if let meetingToDelete = self.meetingsListViewModel.selectedMeetingToDelete { + self.meetingViewModel.cancelMeetingWithNotifications(meeting: meetingToDelete) + meetingsListViewModel.deleteSelectedMeeting() self.isShowSendCancelMeetingNotificationPopup.toggle() } - } - - if isShowStartCallGroupPopup { - PopupView( - isShowPopup: $isShowStartCallGroupPopup, - title: Text("conversation_info_confirm_start_group_call_dialog_title"), - content: Text("conversation_info_confirm_start_group_call_dialog_message"), - titleFirstButton: Text("dialog_cancel"), - actionFirstButton: { - self.isShowStartCallGroupPopup.toggle() - }, - titleSecondButton: Text("dialog_ok"), - actionSecondButton: { - if conversationViewModel.displayedConversation != nil { - conversationViewModel.displayedConversation!.createGroupCall() - } - self.isShowStartCallGroupPopup.toggle() - } - ) - .background(.black.opacity(0.65)) - .zIndex(3) - .onTapGesture { - self.isShowStartCallGroupPopup.toggle() - } - } - - if isShowStartCallGroupPopup { - PopupView( - isShowPopup: $isShowStartCallGroupPopup, - title: Text("conversation_info_confirm_start_group_call_dialog_title"), - content: Text("conversation_info_confirm_start_group_call_dialog_message"), - titleFirstButton: Text("dialog_cancel"), - actionFirstButton: { - self.isShowStartCallGroupPopup.toggle() - }, - titleSecondButton: Text("dialog_ok"), - actionSecondButton: { - if conversationViewModel.displayedConversation != nil { - conversationViewModel.displayedConversation!.createGroupCall() - } - self.isShowStartCallGroupPopup.toggle() - } - ) - .background(.black.opacity(0.65)) - .zIndex(3) - .onTapGesture { - self.isShowStartCallGroupPopup.toggle() - } - } - - if conversationViewModel.isShowConversationInfoPopup { - PopupViewWithTextField(conversationViewModel: conversationViewModel) - .background(.black.opacity(0.65)) - .zIndex(3) - .onTapGesture { - conversationViewModel.isShowConversationInfoPopup = false - } - } - - if telecomManager.meetingWaitingRoomDisplayed { - MeetingWaitingRoomFragment(meetingWaitingRoomViewModel: meetingWaitingRoomViewModel) - .zIndex(3) - .transition(.opacity.combined(with: .move(edge: .bottom))) - .onAppear { - meetingWaitingRoomViewModel.resetMeetingRoomView() - } - } - - if telecomManager.callDisplayed && ((telecomManager.callInProgress && telecomManager.outgoingCallStarted) || telecomManager.callConnected) && !telecomManager.meetingWaitingRoomDisplayed { - CallView( - callViewModel: callViewModel, - conversationViewModel: conversationViewModel, - conversationsListViewModel: conversationsListViewModel, - conversationForwardMessageViewModel: conversationForwardMessageViewModel, - contactViewModel: contactViewModel, - editContactViewModel: editContactViewModel, - meetingViewModel: meetingViewModel, - accountProfileViewModel: accountProfileViewModel, - fullscreenVideo: $fullscreenVideo, - isShowStartCallFragment: $isShowStartCallFragment, - isShowConversationFragment: $isShowConversationFragment, - isShowStartCallGroupPopup: $isShowStartCallGroupPopup, - isShowEditContactFragment: $isShowEditContactFragment, - indexPage: $index, - isShowScheduleMeetingFragment: $isShowScheduleMeetingFragment - ) - .zIndex(5) - .transition(.scale.combined(with: .move(edge: .top))) - .onAppear { - UIApplication.shared.isIdleTimerDisabled = true - callViewModel.resetCallView() - if callViewModel.callsCounter >= 1 { - DispatchQueue.main.asyncAfter(deadline: .now() + 1) { - callViewModel.resetCallView() - } - } - } - .onDisappear { - UIApplication.shared.isIdleTimerDisabled = false - } - } - - ToastView() - .zIndex(6) - } - } - .onAppear { - MagicSearchSingleton.shared.searchForContacts(sourceFlags: MagicSearch.Source.Friends.rawValue | MagicSearch.Source.LdapServers.rawValue) - } - .onChange(of: navigationManager.selectedCallId) { newCallId in - if newCallId != nil { - self.index = 2 - } - } - .onReceive(pub) { _ in - conversationsListViewModel.computeChatRoomsList(filter: "") - historyListViewModel.refreshHistoryAvatarModel() - } - } - .overlay { - if isMenuOpen { - Color.white.opacity(0.001) - .ignoresSafeArea() - .frame(maxWidth: .infinity, maxHeight: .infinity) + }) + .background(.black.opacity(0.65)) + .zIndex(3) .onTapGesture { - isMenuOpen = false + self.isShowSendCancelMeetingNotificationPopup.toggle() } + } + + if isShowStartCallGroupPopup { + PopupView( + isShowPopup: $isShowStartCallGroupPopup, + title: Text("conversation_info_confirm_start_group_call_dialog_title"), + content: Text("conversation_info_confirm_start_group_call_dialog_message"), + titleFirstButton: Text("dialog_cancel"), + actionFirstButton: { + self.isShowStartCallGroupPopup.toggle() + }, + titleSecondButton: Text("dialog_ok"), + actionSecondButton: { + if conversationViewModel.displayedConversation != nil { + conversationViewModel.displayedConversation!.createGroupCall() + } + self.isShowStartCallGroupPopup.toggle() + } + ) + .background(.black.opacity(0.65)) + .zIndex(3) + .onTapGesture { + self.isShowStartCallGroupPopup.toggle() + } + } + + if isShowStartCallGroupPopup { + PopupView( + isShowPopup: $isShowStartCallGroupPopup, + title: Text("conversation_info_confirm_start_group_call_dialog_title"), + content: Text("conversation_info_confirm_start_group_call_dialog_message"), + titleFirstButton: Text("dialog_cancel"), + actionFirstButton: { + self.isShowStartCallGroupPopup.toggle() + }, + titleSecondButton: Text("dialog_ok"), + actionSecondButton: { + if conversationViewModel.displayedConversation != nil { + conversationViewModel.displayedConversation!.createGroupCall() + } + self.isShowStartCallGroupPopup.toggle() + } + ) + .background(.black.opacity(0.65)) + .zIndex(3) + .onTapGesture { + self.isShowStartCallGroupPopup.toggle() + } + } + + if conversationViewModel.isShowConversationInfoPopup { + PopupViewWithTextField(conversationViewModel: conversationViewModel) + .background(.black.opacity(0.65)) + .zIndex(3) + .onTapGesture { + conversationViewModel.isShowConversationInfoPopup = false + } + } + + if telecomManager.meetingWaitingRoomDisplayed { + MeetingWaitingRoomFragment(meetingWaitingRoomViewModel: meetingWaitingRoomViewModel) + .zIndex(3) + .transition(.opacity.combined(with: .move(edge: .bottom))) + .onAppear { + meetingWaitingRoomViewModel.resetMeetingRoomView() + } + } + + if telecomManager.callDisplayed && ((telecomManager.callInProgress && telecomManager.outgoingCallStarted) || telecomManager.callConnected) && !telecomManager.meetingWaitingRoomDisplayed { + CallView( + callViewModel: callViewModel, + conversationViewModel: conversationViewModel, + conversationsListViewModel: conversationsListViewModel, + conversationForwardMessageViewModel: conversationForwardMessageViewModel, + contactViewModel: contactViewModel, + editContactViewModel: editContactViewModel, + meetingViewModel: meetingViewModel, + accountProfileViewModel: accountProfileViewModel, + fullscreenVideo: $fullscreenVideo, + isShowStartCallFragment: $isShowStartCallFragment, + isShowConversationFragment: $isShowConversationFragment, + isShowStartCallGroupPopup: $isShowStartCallGroupPopup, + isShowEditContactFragment: $isShowEditContactFragment, + indexPage: $index, + isShowScheduleMeetingFragment: $isShowScheduleMeetingFragment + ) + .zIndex(5) + .transition(.scale.combined(with: .move(edge: .top))) + .onAppear { + UIApplication.shared.isIdleTimerDisabled = true + callViewModel.resetCallView() + if callViewModel.callsCounter >= 1 { + DispatchQueue.main.asyncAfter(deadline: .now() + 1) { + callViewModel.resetCallView() + } + } + } + .onDisappear { + UIApplication.shared.isIdleTimerDisabled = false + } + } + + ToastView() + .zIndex(6) } } - .onRotate { newOrientation in - if (contactViewModel.indexDisplayedFriend != nil || historyViewModel.displayedCall != nil || conversationViewModel.displayedConversation != nil) && searchIsActive { - self.focusedField = false - } else if searchIsActive { - self.focusedField = true + .onAppear { + MagicSearchSingleton.shared.searchForContacts(sourceFlags: MagicSearch.Source.Friends.rawValue | MagicSearch.Source.LdapServers.rawValue) + } + .onChange(of: navigationManager.selectedCallId) { newCallId in + if newCallId != nil { + self.index = 2 } - orientation = newOrientation } - .onChange(of: scenePhase) { newPhase in - CoreContext.shared.enteredForeground = newPhase == .active - orientation = UIDevice.current.orientation + .onReceive(pub) { _ in + conversationsListViewModel.computeChatRoomsList(filter: "") + historyListViewModel.refreshHistoryAvatarModel() } } + .overlay { + if isMenuOpen { + Color.white.opacity(0.001) + .ignoresSafeArea() + .frame(maxWidth: .infinity, maxHeight: .infinity) + .onTapGesture { + isMenuOpen = false + } + } + } + .onRotate { newOrientation in + if (contactViewModel.indexDisplayedFriend != nil || historyViewModel.displayedCall != nil || conversationViewModel.displayedConversation != nil) && searchIsActive { + self.focusedField = false + } else if searchIsActive { + self.focusedField = true + } + orientation = newOrientation + } + .onChange(of: scenePhase) { newPhase in + CoreContext.shared.enteredForeground = newPhase == .active + orientation = UIDevice.current.orientation + } } func openMenu() { diff --git a/Linphone/UI/Main/Settings/Fragments/AccountProfileFragment.swift b/Linphone/UI/Main/Settings/Fragments/AccountProfileFragment.swift index a62224db6..1ce788ecb 100644 --- a/Linphone/UI/Main/Settings/Fragments/AccountProfileFragment.swift +++ b/Linphone/UI/Main/Settings/Fragments/AccountProfileFragment.swift @@ -40,176 +40,121 @@ struct AccountProfileFragment: View { private let avatarSize = 100.0 var body: some View { - GeometryReader { geometry in - VStack(spacing: 1) { - Rectangle() - .foregroundColor(Color.orangeMain500) - .edgesIgnoringSafeArea(.top) - .frame(height: 0) - - HStack { - Image("caret-left") - .renderingMode(.template) - .resizable() - .foregroundStyle(Color.orangeMain500) - .frame(width: 25, height: 25, alignment: .leading) - .padding(.all, 10) - .padding(.top, 4) - .padding(.leading, -10) - .onTapGesture { - accountProfileViewModel.saveChangesWhenLeaving() - withAnimation { - if isShowAccountProfileFragment { - isShowAccountProfileFragment = false - } + VStack(spacing: 1) { + Rectangle() + .foregroundColor(Color.orangeMain500) + .edgesIgnoringSafeArea(.top) + .frame(height: 0) + + HStack { + Image("caret-left") + .renderingMode(.template) + .resizable() + .foregroundStyle(Color.orangeMain500) + .frame(width: 25, height: 25, alignment: .leading) + .padding(.all, 10) + .padding(.top, 4) + .padding(.leading, -10) + .onTapGesture { + accountProfileViewModel.saveChangesWhenLeaving() + withAnimation { + if isShowAccountProfileFragment { + isShowAccountProfileFragment = false } } - - Text("manage_account_title") - .default_text_style_orange_800(styleSize: 16) - .frame(maxWidth: .infinity, alignment: .leading) - .padding(.top, 4) - .lineLimit(1) - - Spacer() - } - .frame(maxWidth: .infinity) - .frame(height: 50) - .padding(.horizontal) - .padding(.bottom, 4) - .background(.white) + } - ScrollView { + Text("manage_account_title") + .default_text_style_orange_800(styleSize: 16) + .frame(maxWidth: .infinity, alignment: .leading) + .padding(.top, 4) + .lineLimit(1) + + Spacer() + } + .frame(maxWidth: .infinity) + .frame(height: 50) + .padding(.horizontal) + .padding(.bottom, 4) + .background(.white) + + ScrollView { + VStack(spacing: 0) { VStack(spacing: 0) { - VStack(spacing: 0) { - if #unavailable(iOS 16.0) { - Rectangle() - .foregroundColor(Color.gray100) - .frame(height: 7) - } - - if accountProfileViewModel.avatarModel != nil { - VStack(spacing: 0) { - if accountProfileViewModel.avatarModel != nil - && accountProfileViewModel.photoAvatarModel != nil - && !accountProfileViewModel.photoAvatarModel!.isEmpty - && selectedImage == nil && !removedImage { - - AsyncImage(url: accountProfileViewModel.getImagePath()) { image in - switch image { - case .empty: - ProgressView() - .frame(width: avatarSize, height: avatarSize) - case .success(let image): - image - .resizable() - .aspectRatio(contentMode: .fill) - .frame(width: avatarSize, height: avatarSize) - .clipShape(Circle()) - case .failure: - Image(uiImage: contactsManager.textToImage( - firstName: accountProfileViewModel.avatarModel?.name ?? "", - lastName: "")) + if #unavailable(iOS 16.0) { + Rectangle() + .foregroundColor(Color.gray100) + .frame(height: 7) + } + + if accountProfileViewModel.avatarModel != nil { + VStack(spacing: 0) { + if accountProfileViewModel.avatarModel != nil + && accountProfileViewModel.photoAvatarModel != nil + && !accountProfileViewModel.photoAvatarModel!.isEmpty + && selectedImage == nil && !removedImage { + + AsyncImage(url: accountProfileViewModel.getImagePath()) { image in + switch image { + case .empty: + ProgressView() + .frame(width: avatarSize, height: avatarSize) + case .success(let image): + image .resizable() + .aspectRatio(contentMode: .fill) .frame(width: avatarSize, height: avatarSize) .clipShape(Circle()) - @unknown default: - EmptyView() - } - } - } else if selectedImage == nil { - Image(uiImage: contactsManager.textToImage( - firstName: accountProfileViewModel.avatarModel?.name ?? "", - lastName: "")) - .resizable() - .frame(width: avatarSize, height: avatarSize) - .clipShape(Circle()) - } else { - Image(uiImage: selectedImage!) + case .failure: + Image(uiImage: contactsManager.textToImage( + firstName: accountProfileViewModel.avatarModel?.name ?? "", + lastName: "")) .resizable() - .aspectRatio(contentMode: .fill) .frame(width: avatarSize, height: avatarSize) .clipShape(Circle()) - } - - if accountProfileViewModel.avatarModel != nil - && accountProfileViewModel.photoAvatarModel != nil - && !accountProfileViewModel.photoAvatarModel!.isEmpty - && (accountProfileViewModel.photoAvatarModel!.suffix(11) != "default.png" || selectedImage != nil) - && !removedImage { - HStack { - Spacer() - - Button(action: { - showPhotoPicker = true - }, label: { - HStack { - Image("pencil-simple") - .resizable() - .frame(width: 20, height: 20) - - Text("manage_account_edit_picture") - .foregroundStyle(Color.grayMain2c700) - .multilineTextAlignment(.center) - .default_text_style(styleSize: 14) - } - }) - .padding(.top, 10) - .padding(.trailing, 10) - .sheet(isPresented: $showPhotoPicker) { - PhotoPicker(filter: .images, limit: 1) { results in - PhotoPicker.convertToUIImageArray(fromResults: results) { imagesOrNil, errorOrNil in - if let error = errorOrNil { - print(error) - } - if let images = imagesOrNil { - if let first = images.first { - selectedImage = first - removedImage = false - saveImage() - } - } - } - } - .edgesIgnoringSafeArea(.all) - } - - Button(action: { - removedImage = true - selectedImage = nil - saveImage() - }, label: { - HStack { - Image("trash-simple") - .resizable() - .frame(width: 20, height: 20) - - Text("manage_account_remove_picture") - .foregroundStyle(Color.grayMain2c700) - .multilineTextAlignment(.center) - .default_text_style(styleSize: 14) - } - }) - .padding(.top, 10) - - Spacer() + @unknown default: + EmptyView() } - } else { + } + } else if selectedImage == nil { + Image(uiImage: contactsManager.textToImage( + firstName: accountProfileViewModel.avatarModel?.name ?? "", + lastName: "")) + .resizable() + .frame(width: avatarSize, height: avatarSize) + .clipShape(Circle()) + } else { + Image(uiImage: selectedImage!) + .resizable() + .aspectRatio(contentMode: .fill) + .frame(width: avatarSize, height: avatarSize) + .clipShape(Circle()) + } + + if accountProfileViewModel.avatarModel != nil + && accountProfileViewModel.photoAvatarModel != nil + && !accountProfileViewModel.photoAvatarModel!.isEmpty + && (accountProfileViewModel.photoAvatarModel!.suffix(11) != "default.png" || selectedImage != nil) + && !removedImage { + HStack { + Spacer() + Button(action: { showPhotoPicker = true }, label: { HStack { - Image("camera") + Image("pencil-simple") .resizable() .frame(width: 20, height: 20) - Text("manage_account_add_picture") + Text("manage_account_edit_picture") .foregroundStyle(Color.grayMain2c700) .multilineTextAlignment(.center) .default_text_style(styleSize: 14) } }) .padding(.top, 10) + .padding(.trailing, 10) .sheet(isPresented: $showPhotoPicker) { PhotoPicker(filter: .images, limit: 1) { results in PhotoPicker.convertToUIImageArray(fromResults: results) { imagesOrNil, errorOrNil in @@ -220,7 +165,6 @@ struct AccountProfileFragment: View { if let first = images.first { selectedImage = first removedImage = false - showPhotoPicker = false saveImage() } } @@ -228,141 +172,193 @@ struct AccountProfileFragment: View { } .edgesIgnoringSafeArea(.all) } - } - } - .frame(minHeight: 150) - .frame(maxWidth: .infinity) - .padding(.top, 10) - .padding(.bottom, 2) - .background(Color.gray100) - } - - HStack(alignment: .center) { - Text("manage_account_details_title") - .default_text_style_800(styleSize: 18) - .frame(maxWidth: .infinity, alignment: .leading) - - Spacer() - - Image(detailIsOpen ? "caret-up" : "caret-down") - .renderingMode(.template) - .resizable() - .foregroundStyle(Color.grayMain2c600) - .frame(width: 25, height: 25, alignment: .leading) - .padding(.all, 10) - } - .padding(.top, 30) - .padding(.bottom, 10) - .padding(.horizontal, 20) - .background(Color.gray100) - .onTapGesture { - withAnimation { - detailIsOpen.toggle() - } - } - - if detailIsOpen { - VStack(spacing: 0) { - VStack(spacing: 30) { - HStack { - Text(String(localized: "sip_address") + ":") - .default_text_style_600(styleSize: 14) - - Text(accountProfileViewModel.avatarModel!.address) - .foregroundStyle(Color.grayMain2c700) - .default_text_style(styleSize: 14) - .frame(maxWidth: .infinity, alignment: .leading) - .lineLimit(1) - - Button(action: { - UIPasteboard.general.setValue( - accountProfileViewModel.avatarModel!.address, - forPasteboardType: UTType.plainText.identifier - ) - - ToastViewModel.shared.toastMessage = "Success_address_copied_into_clipboard" - ToastViewModel.shared.displayToast.toggle() - }, label: { - Image("copy") + + Button(action: { + removedImage = true + selectedImage = nil + saveImage() + }, label: { + HStack { + Image("trash-simple") .resizable() .frame(width: 20, height: 20) - }) - } + + Text("manage_account_remove_picture") + .foregroundStyle(Color.grayMain2c700) + .multilineTextAlignment(.center) + .default_text_style(styleSize: 14) + } + }) + .padding(.top, 10) - VStack(alignment: .leading) { - Text("sip_address_display_name") - .default_text_style_700(styleSize: 15) - .padding(.bottom, -5) - TextField(accountProfileViewModel.displayName, text: $accountProfileViewModel.displayName) - .default_text_style(styleSize: 15) - .frame(height: 25) - .padding(.horizontal, 20) - .padding(.vertical, 15) - .background(.white) - .cornerRadius(60) - .overlay( - RoundedRectangle(cornerRadius: 60) - .inset(by: 0.5) - .stroke(isDisplayNameFocused ? Color.orangeMain500 : Color.gray200, lineWidth: 1) - ) - .focused($isDisplayNameFocused) - } - - VStack(alignment: .leading) { - Text("sip_address_display_name") - .default_text_style_700(styleSize: 15) - .padding(.bottom, -5) + Spacer() + } + } else { + Button(action: { + showPhotoPicker = true + }, label: { + HStack { + Image("camera") + .resizable() + .frame(width: 20, height: 20) - Menu { - Picker("", selection: $accountProfileViewModel.dialPlanValueSelected) { - ForEach(registerViewModel.dialPlansLabelList, id: \.self) { dialPlan in - Text(dialPlan).tag(dialPlan) + Text("manage_account_add_picture") + .foregroundStyle(Color.grayMain2c700) + .multilineTextAlignment(.center) + .default_text_style(styleSize: 14) + } + }) + .padding(.top, 10) + .sheet(isPresented: $showPhotoPicker) { + PhotoPicker(filter: .images, limit: 1) { results in + PhotoPicker.convertToUIImageArray(fromResults: results) { imagesOrNil, errorOrNil in + if let error = errorOrNil { + print(error) + } + if let images = imagesOrNil { + if let first = images.first { + selectedImage = first + removedImage = false + showPhotoPicker = false + saveImage() } } - } label: { - HStack { - Text(accountProfileViewModel.dialPlanValueSelected) - .default_text_style(styleSize: 15) - .frame(maxWidth: .infinity, alignment: .leading) - - Image("caret-down") - .resizable() - .frame(width: 20, height: 20) - } - .frame(height: 25) - .padding(.horizontal, 20) - .padding(.vertical, 15) - .background(.white) - .cornerRadius(60) - .overlay( - RoundedRectangle(cornerRadius: 60) - .inset(by: 0.5) - .stroke(Color.gray200, lineWidth: 1) - ) } } + .edgesIgnoringSafeArea(.all) } - .padding(.vertical, 30) - .padding(.horizontal, 20) } - .background(.white) - .cornerRadius(15) - .padding(.horizontal) - .zIndex(-1) - .transition(.move(edge: .top)) + } + .frame(minHeight: 150) + .frame(maxWidth: .infinity) + .padding(.top, 10) + .padding(.bottom, 2) + .background(Color.gray100) + } + + HStack(alignment: .center) { + Text("manage_account_details_title") + .default_text_style_800(styleSize: 18) + .frame(maxWidth: .infinity, alignment: .leading) + + Spacer() + + Image(detailIsOpen ? "caret-up" : "caret-down") + .renderingMode(.template) + .resizable() + .foregroundStyle(Color.grayMain2c600) + .frame(width: 25, height: 25, alignment: .leading) + .padding(.all, 10) + } + .padding(.top, 30) + .padding(.bottom, 10) + .padding(.horizontal, 20) + .background(Color.gray100) + .onTapGesture { + withAnimation { + detailIsOpen.toggle() } } - .frame(maxWidth: sharedMainViewModel.maxWidth) + + if detailIsOpen { + VStack(spacing: 0) { + VStack(spacing: 30) { + HStack { + Text(String(localized: "sip_address") + ":") + .default_text_style_600(styleSize: 14) + + Text(accountProfileViewModel.avatarModel!.address) + .foregroundStyle(Color.grayMain2c700) + .default_text_style(styleSize: 14) + .frame(maxWidth: .infinity, alignment: .leading) + .lineLimit(1) + + Button(action: { + UIPasteboard.general.setValue( + accountProfileViewModel.avatarModel!.address, + forPasteboardType: UTType.plainText.identifier + ) + + ToastViewModel.shared.toastMessage = "Success_address_copied_into_clipboard" + ToastViewModel.shared.displayToast.toggle() + }, label: { + Image("copy") + .resizable() + .frame(width: 20, height: 20) + }) + } + + VStack(alignment: .leading) { + Text("sip_address_display_name") + .default_text_style_700(styleSize: 15) + .padding(.bottom, -5) + TextField(accountProfileViewModel.displayName, text: $accountProfileViewModel.displayName) + .default_text_style(styleSize: 15) + .frame(height: 25) + .padding(.horizontal, 20) + .padding(.vertical, 15) + .background(.white) + .cornerRadius(60) + .overlay( + RoundedRectangle(cornerRadius: 60) + .inset(by: 0.5) + .stroke(isDisplayNameFocused ? Color.orangeMain500 : Color.gray200, lineWidth: 1) + ) + .focused($isDisplayNameFocused) + } + + VStack(alignment: .leading) { + Text("sip_address_display_name") + .default_text_style_700(styleSize: 15) + .padding(.bottom, -5) + + Menu { + Picker("", selection: $accountProfileViewModel.dialPlanValueSelected) { + ForEach(registerViewModel.dialPlansLabelList, id: \.self) { dialPlan in + Text(dialPlan).tag(dialPlan) + } + } + } label: { + HStack { + Text(accountProfileViewModel.dialPlanValueSelected) + .default_text_style(styleSize: 15) + .frame(maxWidth: .infinity, alignment: .leading) + + Image("caret-down") + .resizable() + .frame(width: 20, height: 20) + } + .frame(height: 25) + .padding(.horizontal, 20) + .padding(.vertical, 15) + .background(.white) + .cornerRadius(60) + .overlay( + RoundedRectangle(cornerRadius: 60) + .inset(by: 0.5) + .stroke(Color.gray200, lineWidth: 1) + ) + } + } + } + .padding(.vertical, 30) + .padding(.horizontal, 20) + } + .background(.white) + .cornerRadius(15) + .padding(.horizontal) + .zIndex(-1) + .transition(.move(edge: .top)) + } } - .frame(maxWidth: .infinity) - .padding(.top, 2) + .frame(maxWidth: sharedMainViewModel.maxWidth) } - .background(Color.gray100) + .frame(maxWidth: .infinity) + .padding(.top, 2) } .background(Color.gray100) } - .navigationTitle("") - .navigationBarHidden(true) + .background(Color.gray100) } func saveImage() {