Added account removal confirmation dialog

This commit is contained in:
Sylvain Berfini 2023-03-13 13:02:32 +01:00
parent c39f350bdd
commit 8c6975a859
12 changed files with 109 additions and 25 deletions

View file

@ -14,6 +14,7 @@ Group changes to describe their impact on the project, as follows:
### Added
- Showing short term presence for contacts whom publish it + added setting to disable it (enabled by default for sip.linphone.org accounts)
- Confirmation dialog before removing account
### Changed
- Account EXPIRES is now set to 1 month instead of 1 year for sip.linphone.org accounts

View file

@ -191,6 +191,8 @@ class MasterChatRoomsFragment : MasterFragment<ChatRoomMasterFragmentBinding, Ch
override fun onRightToLeftSwipe(viewHolder: RecyclerView.ViewHolder) {
val viewModel = DialogViewModel(getString(R.string.chat_room_delete_one_dialog))
viewModel.showIcon = true
viewModel.iconResource = R.drawable.dialog_delete_icon
val dialog: Dialog = DialogUtils.getDialog(requireContext(), viewModel)
val index = viewHolder.bindingAdapterPosition

View file

@ -162,6 +162,8 @@ class DetailContactFragment : GenericFragment<ContactDetailFragmentBinding>() {
private fun confirmContactRemoval() {
val dialogViewModel = DialogViewModel(getString(R.string.contact_delete_one_dialog))
dialogViewModel.showIcon = true
dialogViewModel.iconResource = R.drawable.dialog_delete_icon
val dialog: Dialog = DialogUtils.getDialog(requireContext(), dialogViewModel)
dialogViewModel.showCancelButton {

View file

@ -154,6 +154,8 @@ class MasterContactsFragment : MasterFragment<ContactMasterFragmentBinding, Cont
override fun onRightToLeftSwipe(viewHolder: RecyclerView.ViewHolder) {
val viewModel = DialogViewModel(getString(R.string.contact_delete_one_dialog))
viewModel.showIcon = true
viewModel.iconResource = R.drawable.dialog_delete_icon
val dialog: Dialog = DialogUtils.getDialog(requireContext(), viewModel)
val index = viewHolder.bindingAdapterPosition

View file

@ -142,6 +142,8 @@ class MasterCallLogsFragment : MasterFragment<HistoryMasterFragmentBinding, Call
override fun onRightToLeftSwipe(viewHolder: RecyclerView.ViewHolder) {
val viewModel = DialogViewModel(getString(R.string.history_delete_one_dialog))
viewModel.showIcon = true
viewModel.iconResource = R.drawable.dialog_delete_icon
val dialog: Dialog = DialogUtils.getDialog(requireContext(), viewModel)
val index = viewHolder.bindingAdapterPosition

View file

@ -19,16 +19,20 @@
*/
package org.linphone.activities.main.settings.fragments
import android.app.Dialog
import android.os.Bundle
import android.view.View
import androidx.core.view.doOnPreDraw
import androidx.lifecycle.ViewModelProvider
import org.linphone.LinphoneApplication.Companion.corePreferences
import org.linphone.R
import org.linphone.activities.main.settings.viewmodels.AccountSettingsViewModel
import org.linphone.activities.main.settings.viewmodels.AccountSettingsViewModelFactory
import org.linphone.activities.main.viewmodels.DialogViewModel
import org.linphone.activities.navigateToPhoneLinking
import org.linphone.core.tools.Log
import org.linphone.databinding.SettingsAccountFragmentBinding
import org.linphone.utils.DialogUtils
import org.linphone.utils.Event
class AccountSettingsFragment : GenericSettingFragment<SettingsAccountFragmentBinding>() {
@ -100,6 +104,40 @@ class AccountSettingsFragment : GenericSettingFragment<SettingsAccountFragmentBi
}
}
viewModel.deleteAccountRequiredEvent.observe(
viewLifecycleOwner
) {
it.consume {
val defaultDomainAccount = viewModel.account.params.identityAddress?.domain == corePreferences.defaultDomain
Log.i("[Account Settings] User clicked on delete account, showing confirmation dialog for ${if (defaultDomainAccount) "default domain account" else "third party account"}")
val dialogViewModel = if (defaultDomainAccount) {
DialogViewModel(getString(R.string.account_setting_delete_sip_linphone_org_confirmation_dialog), getString(R.string.account_setting_delete_dialog_title))
} else {
DialogViewModel(getString(R.string.account_setting_delete_generic_confirmation_dialog), getString(R.string.account_setting_delete_dialog_title))
}
val dialog: Dialog = DialogUtils.getDialog(requireContext(), dialogViewModel)
dialogViewModel.showIcon = true
dialogViewModel.iconResource = R.drawable.dialog_delete_icon
dialogViewModel.showSubscribeLinphoneOrgLink = defaultDomainAccount
dialogViewModel.showCancelButton {
Log.i("[Account Settings] User cancelled account removal")
dialog.dismiss()
}
dialogViewModel.showDeleteButton(
{
viewModel.startDeleteAccount()
dialog.dismiss()
},
getString(R.string.dialog_delete)
)
dialog.show()
}
}
view.doOnPreDraw {
// Notifies fragment is ready to be drawn
sharedViewModel.accountSettingsFragmentOpenedEvent.value = Event(true)

View file

@ -89,7 +89,7 @@ class AccountSettingsViewModel(val account: Account) : GenericSettingsViewModel(
message: String
) {
if (state == RegistrationState.Cleared && account == accountToDelete) {
Log.i("[Account Settings] Account to remove registration is now cleared")
Log.i("[Account Settings] Account to remove ([${account.params.identityAddress?.asStringUriOnly()}]) registration is now cleared, removing it")
waitForUnregister.value = false
deleteAccount(account)
} else {
@ -236,35 +236,16 @@ class AccountSettingsViewModel(val account: Account) : GenericSettingsViewModel(
}
core.removeAccount(account)
accountToDelete = null
accountRemovedEvent.value = Event(true)
}
val deleteAccountRequiredEvent: MutableLiveData<Event<Boolean>> by lazy {
MutableLiveData<Event<Boolean>>()
}
val deleteListener = object : SettingListenerStub() {
override fun onClicked() {
accountToDelete = account
val registered = account.state == RegistrationState.Ok
waitForUnregister.value = registered
if (core.defaultAccount == account) {
Log.i("[Account Settings] Account was default, let's look for a replacement")
for (accountIterator in core.accountList) {
if (account != accountIterator) {
core.defaultAccount = accountIterator
Log.i("[Account Settings] New default account is $accountIterator")
break
}
}
}
val params = account.params.clone()
params.isRegisterEnabled = false
account.params = params
if (!registered) {
Log.w("[Account Settings] Account isn't registered, don't unregister before removing it")
deleteAccount(account)
}
deleteAccountRequiredEvent.value = Event(true)
}
}
@ -527,4 +508,34 @@ class AccountSettingsViewModel(val account: Account) : GenericSettingsViewModel(
transportLabels.value = labels
transportIndex.value = account.params.transport.toInt()
}
fun startDeleteAccount() {
Log.i("[Account Settings] Starting to delete account [${account.params.identityAddress?.asStringUriOnly()}]")
accountToDelete = account
val registered = account.state == RegistrationState.Ok
waitForUnregister.value = registered
if (core.defaultAccount == account) {
Log.i("[Account Settings] Account was default, let's look for a replacement")
for (accountIterator in core.accountList) {
if (account != accountIterator) {
core.defaultAccount = accountIterator
Log.i("[Account Settings] New default account is [${accountIterator.params.identityAddress?.asStringUriOnly()}]")
break
}
}
}
val params = account.params.clone()
params.isRegisterEnabled = false
account.params = params
if (!registered) {
Log.w("[Account Settings] Account isn't registered, don't unregister before removing it")
deleteAccount(account)
} else {
Log.i("[Account Settings] Waiting for account registration to be cleared before removing it")
}
}
}

View file

@ -40,6 +40,8 @@ class DialogViewModel(val message: String, val title: String = "") : ViewModel()
var iconResource: Int = 0
var showSubscribeLinphoneOrgLink: Boolean = false
val doNotAskAgain = MutableLiveData<Boolean>()
val dismissEvent = MutableLiveData<Event<Boolean>>()

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<bitmap android:src="@drawable/menu_delete_default"
android:tint="@color/white_color"/>
</item>
</selector>

View file

@ -43,6 +43,17 @@
android:gravity="center"
android:text="@{viewModel.message, default=Message}"/>
<TextView
android:textColor="?attr/accentColor"
android:textSize="16sp"
android:textColorLink="@color/primary_color"
android:autoLink="web"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/assistant_forgotten_password_link"
android:visibility="@{viewModel.showSubscribeLinphoneOrgLink ? View.VISIBLE : View.GONE}" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View file

@ -765,4 +765,7 @@
<string name="chat_room_presence_last_seen_online_today">En ligne aujourd\'hui à</string>
<string name="chat_room_presence_last_seen_online_yesterday">En ligne hier à</string>
<string name="chat_room_presence_last_seen_online">En ligne le</string>
<string name="account_setting_delete_dialog_title">Voulez-vous supprimer votre compte ?</string>
<string name="account_setting_delete_generic_confirmation_dialog">Votre compte sera supprimé localement.\nPour le supprimer de manière définitive, rendez-vous sur le site internet de votre fournisseur SIP.</string>
<string name="account_setting_delete_sip_linphone_org_confirmation_dialog">Votre compte sera supprimé localement.\nPour le supprimer de manière définitive, rendez-vous sur notre plateforme de gestion des comptes :</string>
</resources>

View file

@ -707,6 +707,9 @@
<string name="account_setting_audio_video_conference_factory_address">Audio/video conference factory URI</string>
<string name="account_setting_end_to_end_encryption_keys_server_url">E2E encryption keys server URL</string>
<string name="account_setting_publish_presence_title">Publish presence information</string>
<string name="account_setting_delete_dialog_title">Do you want to delete your account?</string>
<string name="account_setting_delete_generic_confirmation_dialog">Your account will only be deleted locally.\nTo delete it permanently, go on your SIP provider website.</string>
<string name="account_setting_delete_sip_linphone_org_confirmation_dialog">Your account will only be deleted locally.\nTo delete it permanently, go to our account management platform:</string>
<!-- Conferences settings -->
<string name="conferences_settings_layout_title">Default layout</string>