From 84b39df26c80e76000417456400bc81dc18beec7 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 31 May 2024 11:04:41 +0200 Subject: [PATCH] Removed unused code + updated account settings layout --- .../ui/assistant/fragment/LandingFragment.kt | 15 +- .../ui/assistant/fragment/LoginFragment.kt | 135 ----- .../assistant/fragment/ProfileModeFragment.kt | 82 --- .../RegisterCodeConfirmationFragment.kt | 8 +- .../viewmodel/AccountCreationViewModel.kt | 4 +- .../viewmodel/AccountLoginViewModel.kt | 19 + .../assistant/viewmodel/LandingViewModel.kt | 52 -- .../fragment/AccountSettingsFragment.kt | 6 +- .../viewmodel/AccountSettingsViewModel.kt | 15 +- .../res/layout/account_advanced_settings.xml | 389 ++++++++++++ .../res/layout/account_settings_fragment.xml | 566 ++++-------------- .../res/layout/assistant_landing_fragment.xml | 2 +- .../res/layout/assistant_login_fragment.xml | 185 ------ .../layout/assistant_secure_mode_fragment.xml | 217 ------- .../res/navigation/assistant_nav_graph.xml | 48 +- app/src/main/res/values-fr/strings.xml | 2 +- 16 files changed, 560 insertions(+), 1185 deletions(-) delete mode 100644 app/src/main/java/org/linphone/ui/assistant/fragment/LoginFragment.kt delete mode 100644 app/src/main/java/org/linphone/ui/assistant/fragment/ProfileModeFragment.kt delete mode 100644 app/src/main/java/org/linphone/ui/assistant/viewmodel/LandingViewModel.kt create mode 100644 app/src/main/res/layout/account_advanced_settings.xml delete mode 100644 app/src/main/res/layout/assistant_login_fragment.xml delete mode 100644 app/src/main/res/layout/assistant_secure_mode_fragment.xml diff --git a/app/src/main/java/org/linphone/ui/assistant/fragment/LandingFragment.kt b/app/src/main/java/org/linphone/ui/assistant/fragment/LandingFragment.kt index 16f02166c..c0a9c1c84 100644 --- a/app/src/main/java/org/linphone/ui/assistant/fragment/LandingFragment.kt +++ b/app/src/main/java/org/linphone/ui/assistant/fragment/LandingFragment.kt @@ -39,7 +39,7 @@ import org.linphone.databinding.AssistantLandingFragmentBinding import org.linphone.ui.GenericActivity import org.linphone.ui.GenericFragment import org.linphone.ui.assistant.model.AcceptConditionsAndPolicyDialogModel -import org.linphone.ui.assistant.viewmodel.LandingViewModel +import org.linphone.ui.assistant.viewmodel.AccountLoginViewModel import org.linphone.utils.DialogUtils import org.linphone.utils.PhoneNumberUtils @@ -51,7 +51,7 @@ class LandingFragment : GenericFragment() { private lateinit var binding: AssistantLandingFragmentBinding - private val viewModel: LandingViewModel by navGraphViewModels( + private val viewModel: AccountLoginViewModel by navGraphViewModels( R.id.assistant_nav_graph ) @@ -117,15 +117,8 @@ class LandingFragment : GenericFragment() { viewModel.accountLoggedInEvent.observe(viewLifecycleOwner) { it.consume { firstAccount -> - Log.i("$TAG Account successfully logged-in") - if (firstAccount) { - Log.i("$TAG First account, going to secure/interop mode chooser") - val action = LandingFragmentDirections.actionLandingFragmentToProfileModeFragment() - findNavController().navigate(action) - } else { - Log.i("$TAG Not first account, leaving assistant") - requireActivity().finish() - } + Log.i("$TAG Account successfully logged-in, leaving assistant") + requireActivity().finish() } } diff --git a/app/src/main/java/org/linphone/ui/assistant/fragment/LoginFragment.kt b/app/src/main/java/org/linphone/ui/assistant/fragment/LoginFragment.kt deleted file mode 100644 index a97747747..000000000 --- a/app/src/main/java/org/linphone/ui/assistant/fragment/LoginFragment.kt +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2010-2023 Belledonne Communications SARL. - * - * This file is part of linphone-android - * (see https://www.linphone.org). - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.linphone.ui.assistant.fragment - -import android.content.Intent -import android.net.Uri -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.annotation.UiThread -import androidx.lifecycle.lifecycleScope -import androidx.navigation.fragment.findNavController -import androidx.navigation.fragment.navArgs -import androidx.navigation.navGraphViewModels -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch -import org.linphone.LinphoneApplication.Companion.coreContext -import org.linphone.R -import org.linphone.core.tools.Log -import org.linphone.databinding.AssistantLoginFragmentBinding -import org.linphone.ui.GenericActivity -import org.linphone.ui.GenericFragment -import org.linphone.ui.assistant.viewmodel.AccountLoginViewModel -import org.linphone.utils.PhoneNumberUtils - -@UiThread -class LoginFragment : GenericFragment() { - companion object { - private const val TAG = "[Login Fragment]" - } - - private lateinit var binding: AssistantLoginFragmentBinding - - private val args: LoginFragmentArgs by navArgs() - - private val viewModel: AccountLoginViewModel by navGraphViewModels( - R.id.assistant_nav_graph - ) - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - binding = AssistantLoginFragmentBinding.inflate(layoutInflater) - return binding.root - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - binding.lifecycleOwner = viewLifecycleOwner - binding.viewModel = viewModel - observeToastEvents(viewModel) - - binding.setBackClickListener { - goBack() - } - - val identity = args.sipIdentity - viewModel.sipIdentity.value = identity - - binding.setForgottenPasswordClickListener { - val url = getString(R.string.web_platform_forgotten_password_url) - try { - val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) - startActivity(browserIntent) - } catch (ise: IllegalStateException) { - Log.e( - "$TAG Can't start ACTION_VIEW intent for URL [$url], IllegalStateException: $ise" - ) - } - } - - viewModel.showPassword.observe(viewLifecycleOwner) { - lifecycleScope.launch { - delay(50) - binding.password.setSelection(binding.password.text?.length ?: 0) - } - } - - viewModel.accountLoggedInEvent.observe(viewLifecycleOwner) { - it.consume { firstAccount -> - Log.i("$TAG Account successfully logged-in") - if (firstAccount) { - Log.i("$TAG First account, going to secure/interop mode chooser") - val action = LoginFragmentDirections.actionLoginFragmentToProfileModeFragment() - findNavController().navigate(action) - } else { - Log.i("$TAG Not first account, leaving assistant") - requireActivity().finish() - } - } - } - - viewModel.accountLoginErrorEvent.observe(viewLifecycleOwner) { - it.consume { message -> - (requireActivity() as GenericActivity).showRedToast( - message, - R.drawable.warning_circle - ) - } - } - - coreContext.postOnCoreThread { - val dialPlan = PhoneNumberUtils.getDeviceDialPlan(requireContext()) - if (dialPlan != null) { - viewModel.internationalPrefix.postValue(dialPlan.countryCallingCode) - viewModel.internationalPrefixIsoCountryCode.postValue(dialPlan.isoCountryCode) - } - } - } - - private fun goBack() { - findNavController().popBackStack() - } -} diff --git a/app/src/main/java/org/linphone/ui/assistant/fragment/ProfileModeFragment.kt b/app/src/main/java/org/linphone/ui/assistant/fragment/ProfileModeFragment.kt deleted file mode 100644 index f2ebed5ef..000000000 --- a/app/src/main/java/org/linphone/ui/assistant/fragment/ProfileModeFragment.kt +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2010-2023 Belledonne Communications SARL. - * - * This file is part of linphone-android - * (see https://www.linphone.org). - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.linphone.ui.assistant.fragment - -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.annotation.UiThread -import androidx.navigation.fragment.findNavController -import androidx.navigation.navGraphViewModels -import org.linphone.R -import org.linphone.databinding.AssistantSecureModeFragmentBinding -import org.linphone.ui.GenericFragment -import org.linphone.ui.assistant.viewmodel.AccountLoginViewModel -import org.linphone.utils.DialogUtils - -@UiThread -class ProfileModeFragment : GenericFragment() { - companion object { - private const val TAG = "[Profile Mode Fragment]" - } - - private lateinit var binding: AssistantSecureModeFragmentBinding - - private val viewModel: AccountLoginViewModel by navGraphViewModels( - R.id.assistant_nav_graph - ) - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - binding = AssistantSecureModeFragmentBinding.inflate(layoutInflater) - return binding.root - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - binding.lifecycleOwner = viewLifecycleOwner - binding.viewModel = viewModel - observeToastEvents(viewModel) - - binding.setBackClickListener { - findNavController().popBackStack() - } - - binding.setContinueClickListener { - viewModel.applySelectedMode() - requireActivity().finish() - } - - binding.setDefaultModeTooltipClickListener { - val dialog = DialogUtils.getAccountModeExplanationDialog(requireActivity(), true) - dialog.show() - } - - binding.setInteropModeTooltipClickListener { - val dialog = DialogUtils.getAccountModeExplanationDialog(requireActivity(), false) - dialog.show() - } - } -} diff --git a/app/src/main/java/org/linphone/ui/assistant/fragment/RegisterCodeConfirmationFragment.kt b/app/src/main/java/org/linphone/ui/assistant/fragment/RegisterCodeConfirmationFragment.kt index 1b29e899f..3132b03bd 100644 --- a/app/src/main/java/org/linphone/ui/assistant/fragment/RegisterCodeConfirmationFragment.kt +++ b/app/src/main/java/org/linphone/ui/assistant/fragment/RegisterCodeConfirmationFragment.kt @@ -66,13 +66,11 @@ class RegisterCodeConfirmationFragment : GenericFragment() { goBack() } - viewModel.goToLoginPageEvent.observe(viewLifecycleOwner) { + viewModel.accountCreatedEvent.observe(viewLifecycleOwner) { it.consume { - Log.i("$TAG Going to login fragment") val identity = viewModel.username.value.orEmpty() - val action = RegisterCodeConfirmationFragmentDirections.actionRegisterCodeConfirmationFragmentToLoginFragment( - identity - ) + Log.i("$TAG Account [$identity] has been created") + val action = RegisterCodeConfirmationFragmentDirections.actionRegisterCodeConfirmationFragmentToLandingFragment() findNavController().navigate(action) } } diff --git a/app/src/main/java/org/linphone/ui/assistant/viewmodel/AccountCreationViewModel.kt b/app/src/main/java/org/linphone/ui/assistant/viewmodel/AccountCreationViewModel.kt index f1067e824..59ee82fa9 100644 --- a/app/src/main/java/org/linphone/ui/assistant/viewmodel/AccountCreationViewModel.kt +++ b/app/src/main/java/org/linphone/ui/assistant/viewmodel/AccountCreationViewModel.kt @@ -92,7 +92,7 @@ class AccountCreationViewModel @UiThread constructor() : GenericViewModel() { val goToSmsCodeConfirmationViewEvent = MutableLiveData>() - val goToLoginPageEvent = MutableLiveData>() + val accountCreatedEvent = MutableLiveData>() val errorHappenedEvent: MutableLiveData> by lazy { MutableLiveData>() @@ -214,7 +214,7 @@ class AccountCreationViewModel @UiThread constructor() : GenericViewModel() { if (status == AccountCreator.Status.AccountActivated) { Log.i("$TAG Account has been successfully activated, going to login page") - goToLoginPageEvent.postValue(Event(true)) + accountCreatedEvent.postValue(Event(true)) } else { Log.e("$TAG Account couldn't be activated, an unexpected error occurred!") errorHappenedEvent.postValue( diff --git a/app/src/main/java/org/linphone/ui/assistant/viewmodel/AccountLoginViewModel.kt b/app/src/main/java/org/linphone/ui/assistant/viewmodel/AccountLoginViewModel.kt index 6bdcb78dd..2605e5431 100644 --- a/app/src/main/java/org/linphone/ui/assistant/viewmodel/AccountLoginViewModel.kt +++ b/app/src/main/java/org/linphone/ui/assistant/viewmodel/AccountLoginViewModel.kt @@ -45,6 +45,14 @@ open class AccountLoginViewModel @UiThread constructor() : GenericViewModel() { private const val TAG = "[Account Login ViewModel]" } + val showBackButton = MutableLiveData() + + val hideCreateAccount = MutableLiveData() + + val hideScanQrCode = MutableLiveData() + + val hideThirdPartyAccount = MutableLiveData() + val sipIdentity = MutableLiveData() val password = MutableLiveData() @@ -69,6 +77,8 @@ open class AccountLoginViewModel @UiThread constructor() : GenericViewModel() { MutableLiveData>() } + var conditionsAndPrivacyPolicyAccepted = false + private lateinit var newlyCreatedAuthInfo: AuthInfo private lateinit var newlyCreatedAccount: Account @@ -116,6 +126,15 @@ open class AccountLoginViewModel @UiThread constructor() : GenericViewModel() { } init { + coreContext.postOnCoreThread { core -> + // Prevent user from leaving assistant if no account was configured yet + showBackButton.postValue(core.accountList.isNotEmpty()) + hideCreateAccount.postValue(corePreferences.hideAssistantCreateAccount) + hideScanQrCode.postValue(corePreferences.hideAssistantScanQrCode) + hideThirdPartyAccount.postValue(corePreferences.hideAssistantThirdPartySipAccount) + conditionsAndPrivacyPolicyAccepted = corePreferences.conditionsAndPrivacyPolicyAccepted + } + showPassword.value = false registrationInProgress.value = false diff --git a/app/src/main/java/org/linphone/ui/assistant/viewmodel/LandingViewModel.kt b/app/src/main/java/org/linphone/ui/assistant/viewmodel/LandingViewModel.kt deleted file mode 100644 index ad9a2569c..000000000 --- a/app/src/main/java/org/linphone/ui/assistant/viewmodel/LandingViewModel.kt +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2010-2023 Belledonne Communications SARL. - * - * This file is part of linphone-android - * (see https://www.linphone.org). - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.linphone.ui.assistant.viewmodel - -import androidx.annotation.UiThread -import androidx.lifecycle.MutableLiveData -import org.linphone.LinphoneApplication.Companion.coreContext -import org.linphone.LinphoneApplication.Companion.corePreferences - -class LandingViewModel @UiThread constructor() : AccountLoginViewModel() { - companion object { - private const val TAG = "[Account Login ViewModel]" - } - - val showBackButton = MutableLiveData() - - val hideCreateAccount = MutableLiveData() - - val hideScanQrCode = MutableLiveData() - - val hideThirdPartyAccount = MutableLiveData() - - var conditionsAndPrivacyPolicyAccepted = false - - init { - coreContext.postOnCoreThread { core -> - // Prevent user from leaving assistant if no account was configured yet - showBackButton.postValue(core.accountList.isNotEmpty()) - hideCreateAccount.postValue(corePreferences.hideAssistantCreateAccount) - hideScanQrCode.postValue(corePreferences.hideAssistantScanQrCode) - hideThirdPartyAccount.postValue(corePreferences.hideAssistantThirdPartySipAccount) - conditionsAndPrivacyPolicyAccepted = corePreferences.conditionsAndPrivacyPolicyAccepted - } - } -} diff --git a/app/src/main/java/org/linphone/ui/main/settings/fragment/AccountSettingsFragment.kt b/app/src/main/java/org/linphone/ui/main/settings/fragment/AccountSettingsFragment.kt index e02628c65..104a1e367 100644 --- a/app/src/main/java/org/linphone/ui/main/settings/fragment/AccountSettingsFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/settings/fragment/AccountSettingsFragment.kt @@ -114,11 +114,11 @@ class AccountSettingsFragment : GenericMainFragment() { val currentTransport = viewModel.selectedTransport.value?.name?.uppercase( Locale.getDefault() ) - binding.transportSpinner.adapter = adapter - binding.transportSpinner.setSelection( + binding.accountAdvancedSettings.transportSpinner.adapter = adapter + binding.accountAdvancedSettings.transportSpinner.setSelection( viewModel.availableTransports.indexOf(currentTransport) ) - binding.transportSpinner.onItemSelectedListener = dropdownListener + binding.accountAdvancedSettings.transportSpinner.onItemSelectedListener = dropdownListener } } else { Log.e( diff --git a/app/src/main/java/org/linphone/ui/main/settings/viewmodel/AccountSettingsViewModel.kt b/app/src/main/java/org/linphone/ui/main/settings/viewmodel/AccountSettingsViewModel.kt index 159c1a3fd..369d59e87 100644 --- a/app/src/main/java/org/linphone/ui/main/settings/viewmodel/AccountSettingsViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/settings/viewmodel/AccountSettingsViewModel.kt @@ -37,6 +37,8 @@ class AccountSettingsViewModel @UiThread constructor() : GenericViewModel() { private const val TAG = "[Account Settings ViewModel]" } + val expandAdvancedSettings = MutableLiveData() + val pushNotificationsAvailable = MutableLiveData() val pushNotificationsEnabled = MutableLiveData() @@ -79,15 +81,17 @@ class AccountSettingsViewModel @UiThread constructor() : GenericViewModel() { private lateinit var natPolicy: NatPolicy init { + expandAdvancedSettings.value = false + availableTransports.add(TransportType.Udp.name.uppercase(Locale.getDefault())) availableTransports.add(TransportType.Tcp.name.uppercase(Locale.getDefault())) availableTransports.add(TransportType.Tls.name.uppercase(Locale.getDefault())) imEncryptionMandatoryAvailable.addSource(limeServerUrl) { - imEncryptionMandatoryAvailable.value = isImEncrptionMandatoryAvailable() + imEncryptionMandatoryAvailable.value = isImEncryptionMandatoryAvailable() } imEncryptionMandatoryAvailable.addSource(conferenceFactoryUri) { - imEncryptionMandatoryAvailable.value = isImEncrptionMandatoryAvailable() + imEncryptionMandatoryAvailable.value = isImEncryptionMandatoryAvailable() } } @@ -207,7 +211,12 @@ class AccountSettingsViewModel @UiThread constructor() : GenericViewModel() { } @UiThread - fun isImEncrptionMandatoryAvailable(): Boolean { + fun isImEncryptionMandatoryAvailable(): Boolean { return limeServerUrl.value.orEmpty().isNotEmpty() && conferenceFactoryUri.value.orEmpty().isNotEmpty() } + + @UiThread + fun toggleAdvancedSettingsExpand() { + expandAdvancedSettings.value = expandAdvancedSettings.value == false + } } diff --git a/app/src/main/res/layout/account_advanced_settings.xml b/app/src/main/res/layout/account_advanced_settings.xml new file mode 100644 index 000000000..bfb8e0e7d --- /dev/null +++ b/app/src/main/res/layout/account_advanced_settings.xml @@ -0,0 +1,389 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/account_settings_fragment.xml b/app/src/main/res/layout/account_settings_fragment.xml index 708ee5fba..95555bb77 100644 --- a/app/src/main/res/layout/account_settings_fragment.xml +++ b/app/src/main/res/layout/account_settings_fragment.xml @@ -1,7 +1,7 @@ - + @@ -57,468 +57,138 @@ app:layout_constraintTop_toBottomOf="@id/title" app:layout_constraintBottom_toBottomOf="parent"> - + android:layout_height="wrap_content" + android:orientation="vertical"> - - - - - - - - - + android:background="@drawable/shape_squircle_white_background"> - + - + + + + + + + + + + + + android:padding="5dp" + android:layout_marginStart="26dp" + android:layout_marginEnd="26dp" + android:layout_marginTop="16dp" + android:text="@string/settings_advanced_title" + android:drawableEnd="@{viewModel.expandAdvancedSettings ? @drawable/caret_up : @drawable/caret_down, default=@drawable/caret_up}" + android:drawableTint="?attr/color_main2_600"/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:visibility="@{viewModel.expandAdvancedSettings ? View.VISIBLE : View.GONE}" + layout="@layout/account_advanced_settings" + bind:viewModel="@{viewModel}"/> - + diff --git a/app/src/main/res/layout/assistant_landing_fragment.xml b/app/src/main/res/layout/assistant_landing_fragment.xml index 9fdedc43d..c1bc9a9af 100644 --- a/app/src/main/res/layout/assistant_landing_fragment.xml +++ b/app/src/main/res/layout/assistant_landing_fragment.xml @@ -22,7 +22,7 @@ type="View.OnClickListener" /> + type="org.linphone.ui.assistant.viewmodel.AccountLoginViewModel" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/assistant_secure_mode_fragment.xml b/app/src/main/res/layout/assistant_secure_mode_fragment.xml deleted file mode 100644 index d68ad4dc2..000000000 --- a/app/src/main/res/layout/assistant_secure_mode_fragment.xml +++ /dev/null @@ -1,217 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/navigation/assistant_nav_graph.xml b/app/src/main/res/navigation/assistant_nav_graph.xml index d5f86e01c..da7361a12 100644 --- a/app/src/main/res/navigation/assistant_nav_graph.xml +++ b/app/src/main/res/navigation/assistant_nav_graph.xml @@ -5,26 +5,6 @@ android:id="@+id/assistant_nav_graph" app:startDestination="@id/landingFragment"> - - - - - - - @@ -89,26 +69,18 @@ android:name="org.linphone.ui.assistant.fragment.RegisterCodeConfirmationFragment" android:label="RegisterCodeConfirmationFragment" tools:layout="@layout/assistant_register_confirm_sms_code_fragment" > - - + app:popExitAnim="@anim/slide_out_right"/> - - - - URL du serveur d\'échange de clés de chiffrement Mode "bundle" Utiliser CPIM dans les conversations "basiques" - URI de la boîte vocale + URI du serveur de messagerie vocale Autentification requise La connexion a échoué pour le compte \n%s.\n\nVous pouvez renseigner votre mot de passe à nouveau ou bien vérifier les options de configuration de votre compte.