From cb26bc0bae44faef57954940cca093344c25b126 Mon Sep 17 00:00:00 2001 From: Benoit Martins Date: Wed, 9 Jul 2025 13:09:31 +0200 Subject: [PATCH] Add banner for account error state --- .../Localizable/cs.lproj/Localizable.strings | 2 + .../Localizable/en.lproj/Localizable.strings | 2 + .../Localizable/fr.lproj/Localizable.strings | 2 + .../Localizable/uk.lproj/Localizable.strings | 2 + Linphone/UI/Main/ContentView.swift | 57 ++++++++++++++++++- .../Main/Fragments/SideMenuAccountRow.swift | 6 ++ .../ViewModel/AccountProfileViewModel.swift | 9 ++- Linphone/UI/Main/Viewmodel/AccountModel.swift | 3 + 8 files changed, 79 insertions(+), 4 deletions(-) diff --git a/Linphone/Localizable/cs.lproj/Localizable.strings b/Linphone/Localizable/cs.lproj/Localizable.strings index b273f077e..2588c89fc 100644 --- a/Linphone/Localizable/cs.lproj/Localizable.strings +++ b/Linphone/Localizable/cs.lproj/Localizable.strings @@ -109,6 +109,7 @@ "conference_layout_active_speaker" = "Mluvčí"; "conference_layout_audio_only" = "Pouze zvuk"; "conference_layout_grid" = "Mozaika"; +"connection_error_for_non_default_account" = "Chyba při připojení účtu(ů)"; "contact_details_actions_title" = "Další akce"; "contact_details_add_to_favourites" = "Přidat do oblíbených"; "contact_details_delete" = "Smazat"; @@ -172,6 +173,7 @@ "conversation_message_meeting_updated_label" = "Schůzka byla aktualizována"; "conversation_text_field_hint" = "Napište něco…"; "conversations_list_empty" = "Momentálně žádné konverzace…"; +"default_account_disabled" = "Zvolený účet je momentálně zákázán"; "dialog_call" = "Volat"; "dialog_cancel" = "Zrušit"; "dialog_continue" = "Pokračovat"; diff --git a/Linphone/Localizable/en.lproj/Localizable.strings b/Linphone/Localizable/en.lproj/Localizable.strings index 84af55f12..acf3b543b 100644 --- a/Linphone/Localizable/en.lproj/Localizable.strings +++ b/Linphone/Localizable/en.lproj/Localizable.strings @@ -160,6 +160,7 @@ "conference_participant_joining_text" = "Joining…"; "conference_participant_paused_text" = "Paused"; "conference_share_link_title" = "Share invitation"; +"connection_error_for_non_default_account" = "Account(s) connection error"; "contact_call_action" = "Call"; "contact_details_actions_title" = "Other actions"; "contact_details_add_to_favourites" = "Add to favourites"; @@ -252,6 +253,7 @@ "conversation_file_cant_be_opened_error_toast" = "File can't be opened!"; "debug_logs_copied_to_clipboard_toast" = "Debug logs copied to clipboard"; "Default" = "Default"; +"default_account_disabled" = "Selected account is currently disabled"; "Default mode" = "Default mode"; "dialog_accept" = "Accept"; "dialog_call" = "Call"; diff --git a/Linphone/Localizable/fr.lproj/Localizable.strings b/Linphone/Localizable/fr.lproj/Localizable.strings index 8e7891cea..266c09c94 100644 --- a/Linphone/Localizable/fr.lproj/Localizable.strings +++ b/Linphone/Localizable/fr.lproj/Localizable.strings @@ -160,6 +160,7 @@ "conference_participant_joining_text" = "En train de rejoindre…"; "conference_participant_paused_text" = "En pause"; "conference_share_link_title" = "Partager le lien"; +"connection_error_for_non_default_account" = "Compte(s) non connecté(s)"; "contact_call_action" = "Appel"; "contact_details_actions_title" = "Autres actions"; "contact_details_add_to_favourites" = "Ajouter aux favoris"; @@ -252,6 +253,7 @@ "conversation_file_cant_be_opened_error_toast" = "Impossible d'ouvrir le fichier!"; "debug_logs_copied_to_clipboard_toast" = "Les journaux ont été ajoutés au presse-papier"; "Default" = "Default"; +"default_account_disabled" = "Le compte selectionné est désactivé"; "Default mode" = "Default mode"; "dialog_accept" = "Accepter"; "dialog_call" = "Appeler"; diff --git a/Linphone/Localizable/uk.lproj/Localizable.strings b/Linphone/Localizable/uk.lproj/Localizable.strings index d892e94fb..b51871703 100644 --- a/Linphone/Localizable/uk.lproj/Localizable.strings +++ b/Linphone/Localizable/uk.lproj/Localizable.strings @@ -24,6 +24,7 @@ "conference_participant_joining_text" = "Приєднання…"; "conference_participant_paused_text" = "Призупинено"; "conference_share_link_title" = "Поділитися запрошенням"; +"connection_error_for_non_default_account" = "Помилка підключення облікового запису(ів)"; "contact_call_action" = "Дзвінок"; "contact_details_actions_title" = "Інші дії"; "contact_details_add_to_favourites" = "Додати в обрані"; @@ -82,6 +83,7 @@ "conversation_message_meeting_updated_label" = "Нараду оновлено"; "conversation_text_field_hint" = "Скажіть щось…"; "conversations_list_empty" = "Наразі жодної розмови…"; +"default_account_disabled" = "Обраний обліковий запис наразі вимкнено"; "dialog_call" = "Дзвінок"; "dialog_cancel" = "Скасувати"; "dialog_continue" = "Продовжити"; diff --git a/Linphone/UI/Main/ContentView.swift b/Linphone/UI/Main/ContentView.swift index 9f93e6476..c350a78c2 100644 --- a/Linphone/UI/Main/ContentView.swift +++ b/Linphone/UI/Main/ContentView.swift @@ -88,6 +88,56 @@ struct ContentView: View { var body: some View { GeometryReader { geometry in VStack(spacing: 0) { + if accountProfileViewModel.accountError && (!telecomManager.callInProgress || (telecomManager.callInProgress && !telecomManager.callDisplayed)) { + HStack { + if let index = accountProfileViewModel.defaultAccountModelIndex, + index < coreContext.accounts.count, coreContext.accounts[index].isDefaultAccount, coreContext.accounts[index].registrationStateAssociatedUIColor == .orangeWarning600 { + Image("warning-circle") + .renderingMode(.template) + .resizable() + .foregroundStyle(.white) + .frame(width: 26, height: 26) + .padding(.leading, 10) + + + Text(String(localized: "default_account_disabled")) + .default_text_style_white(styleSize: 16) + } else { + Image("bell-simple") + .renderingMode(.template) + .resizable() + .foregroundStyle(.white) + .frame(width: 26, height: 26) + .padding(.leading, 10) + + + Text(String(localized: "connection_error_for_non_default_account")) + .default_text_style_white(styleSize: 16) + } + Spacer() + + Button( + action: { + withAnimation { + accountProfileViewModel.accountError = false + } + }, label: { + Image("x") + .renderingMode(.template) + .resizable() + .foregroundStyle(.white) + .frame(width: 26, height: 26) + .padding(.trailing, 10) + } + ) + + } + .frame(maxWidth: .infinity) + .frame(height: 40) + .padding(.horizontal, 10) + .background(Color.redDanger500) + } + if !sharedMainViewModel.fileUrlsToShare.isEmpty && (!telecomManager.callInProgress || (telecomManager.callInProgress && !telecomManager.callDisplayed)) { HStack { Image("share-network") @@ -1358,7 +1408,12 @@ struct ContentView: View { } .onReceive(NotificationCenter.default.publisher(for: NSNotification.Name("DefaultAccountChanged"))) { _ in accountProfileViewModel.defaultAccountModelIndex = CoreContext.shared.accounts.firstIndex(where: {$0.isDefaultAccount}) - + + accountProfileViewModel.accountError = CoreContext.shared.accounts.contains { + ($0.registrationState == .Cleared && $0.isDefaultAccount) || + $0.registrationState == .Failed + } + withAnimation { if self.sideMenuIsOpen { self.sideMenuIsOpen = false diff --git a/Linphone/UI/Main/Fragments/SideMenuAccountRow.swift b/Linphone/UI/Main/Fragments/SideMenuAccountRow.swift index 6b713f323..89960f524 100644 --- a/Linphone/UI/Main/Fragments/SideMenuAccountRow.swift +++ b/Linphone/UI/Main/Fragments/SideMenuAccountRow.swift @@ -69,6 +69,12 @@ struct SideMenuAccountRow: View { Text(model.humanReadableRegistrationState) .default_text_style_uncolored(styleSize: 12) .foregroundStyle(model.registrationStateAssociatedUIColor) + .onChange(of: model.registrationStateAssociatedUIColor) { _ in + accountProfileViewModel.accountError = CoreContext.shared.accounts.contains { + ($0.registrationState == .Cleared && $0.isDefaultAccount) || + $0.registrationState == .Failed + } + } } .padding(EdgeInsets(top: 4, leading: 8, bottom: 4, trailing: 8)) .background(Color.grayMain2c200) diff --git a/Linphone/UI/Main/Settings/ViewModel/AccountProfileViewModel.swift b/Linphone/UI/Main/Settings/ViewModel/AccountProfileViewModel.swift index 020381264..949fa4bce 100644 --- a/Linphone/UI/Main/Settings/ViewModel/AccountProfileViewModel.swift +++ b/Linphone/UI/Main/Settings/ViewModel/AccountProfileViewModel.swift @@ -30,6 +30,7 @@ class AccountProfileViewModel: ObservableObject { @Published var accountModelIndex: Int? = 0 @Published var defaultAccountModelIndex: Int? = 0 + @Published var accountError: Bool = false init() { SharedMainViewModel.shared.getDialPlansList() @@ -97,7 +98,9 @@ class AccountProfileViewModel: ObservableObject { } let accountDisplayName = accountTmp.account.displayName() - + + let defaultAccountModelIndexTmp = CoreContext.shared.accounts.firstIndex(where: {$0.isDefaultAccount}) + DispatchQueue.main.async { accountTmp.avatarModel = ContactAvatarModel( friend: nil, @@ -106,8 +109,8 @@ class AccountProfileViewModel: ObservableObject { withPresence: false ) - self.defaultAccountModelIndex = CoreContext.shared.accounts.firstIndex(where: {$0.isDefaultAccount}) - + self.defaultAccountModelIndex = defaultAccountModelIndexTmp + self.dialPlanValueSelected = dialPlanValueSelectedTmp } } diff --git a/Linphone/UI/Main/Viewmodel/AccountModel.swift b/Linphone/UI/Main/Viewmodel/AccountModel.swift index 6e42b3ac5..4667da3b9 100644 --- a/Linphone/UI/Main/Viewmodel/AccountModel.swift +++ b/Linphone/UI/Main/Viewmodel/AccountModel.swift @@ -26,6 +26,7 @@ class AccountModel: ObservableObject { static let TAG = "[AccountModel]" let account: Account + @Published var registrationState: RegistrationState = .None @Published var humanReadableRegistrationState: String = "" @Published var summary: String = "" @Published var registrationStateAssociatedUIColor: Color = .clear @@ -139,6 +140,8 @@ class AccountModel: ObservableObject { registrationStateAssociatedUIColor = .grayMain2c500 } + registrationState = state + isRegistrered = state == .Ok isDefaultAccount = isDefault self.displayName = displayName