diff --git a/linphone-app/assets/languages/en.ts b/linphone-app/assets/languages/en.ts
index 6634f9b08..11d74e8db 100644
--- a/linphone-app/assets/languages/en.ts
+++ b/linphone-app/assets/languages/en.ts
@@ -3410,6 +3410,10 @@ Click here: <a href="%1">%1</a>
deleteAccountDescription
Are you sure you wish to delete this account?
+
+ deleteAccountDescriptionUnregisterFailed
+ Unable to unregister this account from server. Do you wish to delete it anyway?
+
eraseAllPasswordsDescription
Are you sure you wish to remove all passwords?
diff --git a/linphone-app/assets/languages/fr_FR.ts b/linphone-app/assets/languages/fr_FR.ts
index 8074650e8..96f4a65d1 100644
--- a/linphone-app/assets/languages/fr_FR.ts
+++ b/linphone-app/assets/languages/fr_FR.ts
@@ -3385,6 +3385,10 @@ Cliquez ici : <a href="%1">%1</a>
deleteAccountDescription
Êtes-vous sûr de vouloir supprimer ce compte ?
+
+ deleteAccountDescriptionUnregisterFailed
+ Le désenregistrement de ce compte auprès du serveur a échoué. Le supprimer quand même ?
+
eraseAllPasswordsDescription
Êtes-vous sûr de vouloir supprimer tous vos mots de passe ?
diff --git a/linphone-app/src/components/settings/AccountSettingsModel.cpp b/linphone-app/src/components/settings/AccountSettingsModel.cpp
index 79bba2c8d..a95340a40 100644
--- a/linphone-app/src/components/settings/AccountSettingsModel.cpp
+++ b/linphone-app/src/components/settings/AccountSettingsModel.cpp
@@ -298,7 +298,7 @@ void AccountSettingsModel::enableRegister (std::shared_ptr ac
account->setParams(params);
}
-void AccountSettingsModel::removeAccount (const shared_ptr &account) {
+void AccountSettingsModel::removeAccount (const shared_ptr &account, bool unregisterFirst) {
CoreManager *coreManager = CoreManager::getInstance();
std::shared_ptr newAccount = nullptr;
@@ -312,6 +312,16 @@ void AccountSettingsModel::removeAccount (const shared_ptr &a
}
setDefaultAccount(newAccount);
}
+
+ if (!unregisterFirst || !account->getParams()->registerEnabled()) {
+ doRemoveAccount(account);
+ return;
+ }
+ if (account->getState() == linphone::RegistrationState::None) {
+ emit unregisterFailed();
+ return;
+ }
+
// "message-expires" is used to keep contact for messages. Setting to 0 will remove the contact for messages too.
// Check if a "message-expires" exists and set it to 0
QStringList parameters = Utils::coreStringToAppString(account->getParams()->getContactParameters()).split(";", Qt::SkipEmptyParts);
@@ -321,16 +331,26 @@ void AccountSettingsModel::removeAccount (const shared_ptr &a
parameters[i] = Constants::DefaultContactParametersOnRemove;
}
}
+
auto accountParams = account->getParams()->clone();
- accountParams->setContactParameters(Utils::appStringToCoreString(parameters.join(";")));
+ accountParams->setContactParameters(Utils::appStringToCoreString(parameters.join(";")));
+ accountParams->setExpires(0);
bool isRegistered = account->getState() == linphone::RegistrationState::Ok;
if (account->setParams(accountParams) == -1) {
qWarning() << QStringLiteral("Unable to reset message-expiry property before removing account: `%1`.")
.arg(QString::fromStdString(account->getParams()->getIdentityAddress()->asString()));
- }else if(isRegistered && account->getParams()->registerEnabled()) { // Wait for update
+ }else if (isRegistered) { // Wait for unregistration
mRemovingAccounts.push_back(account);
+ QTimer::singleShot(10000, [account, this](){// In case of unregistration failure.
+ if (!mRemovedAccounts.contains(account)) {
+ mRemovingAccounts.removeAll(account);
+ qInfo() << QStringLiteral("failed unregistering from server within 10 seconds, deleting account %1.").arg(Utils::coreStringToAppString(account->getParams()->getIdentityAddress()->asString()));
+ emit unregisterFailed();
+ } else
+ mRemovedAccounts.removeAll(account);
+ });
}else{// Registration is not enabled : Removing without wait.
- CoreManager::getInstance()->getCore()->removeAccount(account);
+ doRemoveAccount(account);
}
emit accountSettingsUpdated();
@@ -644,23 +664,27 @@ void AccountSettingsModel::handleRegistrationStateChanged (
const shared_ptr & account,
linphone::RegistrationState state
) {
- Q_UNUSED(state)
auto coreManager = CoreManager::getInstance();
shared_ptr defaultAccount = coreManager->getCore()->getDefaultAccount();
- if( state == linphone::RegistrationState::Cleared){
- auto authInfo = account->findAuthInfo();
- if(authInfo)
- QTimer::singleShot(60000, [authInfo](){// 60s is just to be sure. account_update remove deleted account only after 32s
- CoreManager::getInstance()->getCore()->removeAuthInfo(authInfo);
- });
- }else if(mRemovingAccounts.contains(account)){
+ if(mRemovingAccounts.contains(account) && state == linphone::RegistrationState::Cleared) {
mRemovingAccounts.removeAll(account);
- QTimer::singleShot(100, [account, this](){// removeAccount cannot be called from callback
- CoreManager::getInstance()->getCore()->removeAccount(account);
- emit accountsChanged();
- });
+ doRemoveAccount(account);
}
if(defaultAccount == account)
emit defaultRegistrationChanged();
emit registrationStateChanged();
}
+
+void AccountSettingsModel::doRemoveAccount (const shared_ptr &account) {
+ auto authInfo = account->findAuthInfo();
+ if(authInfo)
+ QTimer::singleShot(60000, [authInfo](){// 60s is just to be sure. account_update remove deleted account only after 32s
+ CoreManager::getInstance()->getCore()->removeAuthInfo(authInfo);
+ });
+ QTimer::singleShot(100, [account, this](){// removeAccount cannot be called from callback
+ CoreManager::getInstance()->getCore()->removeAccount(account);
+ emit accountsChanged();
+ });
+}
+
+
diff --git a/linphone-app/src/components/settings/AccountSettingsModel.hpp b/linphone-app/src/components/settings/AccountSettingsModel.hpp
index e523b487c..b54e47f33 100644
--- a/linphone-app/src/components/settings/AccountSettingsModel.hpp
+++ b/linphone-app/src/components/settings/AccountSettingsModel.hpp
@@ -95,7 +95,7 @@ public:
Q_INVOKABLE bool addOrUpdateAccount (const std::shared_ptr &account, const QVariantMap &data);
Q_INVOKABLE bool addOrUpdateAccount (const QVariantMap &data);// Create default account and apply data
- Q_INVOKABLE void removeAccount (const std::shared_ptr &account);
+ Q_INVOKABLE void removeAccount (const std::shared_ptr &account, bool unregisterFirst);
Q_INVOKABLE std::shared_ptr createAccount (const QString& assistantFile);
@@ -122,7 +122,8 @@ signals:
void primarySipAddressChanged();
void accountsChanged();
-
+ void unregisterFailed();
+
void accountSettingsUpdated ();
void defaultAccountChanged();
void publishPresenceChanged();
@@ -151,13 +152,15 @@ private:
QVariantList getAccounts () const;
// ---------------------------------------------------------------------------
-
+
void handleRegistrationStateChanged (
const std::shared_ptr &account,
linphone::RegistrationState state
);
-
+ void doRemoveAccount (const std::shared_ptr &account);
+
QVector > mRemovingAccounts;
+ QVector > mRemovedAccounts;
std::shared_ptr mSelectedAccount;
};
diff --git a/linphone-app/ui/views/App/Settings/SettingsSipAccounts.js b/linphone-app/ui/views/App/Settings/SettingsSipAccounts.js
index e6fc51807..7a966fbf8 100644
--- a/linphone-app/ui/views/App/Settings/SettingsSipAccounts.js
+++ b/linphone-app/ui/views/App/Settings/SettingsSipAccounts.js
@@ -33,16 +33,29 @@ function editAccount (account) {
})
}
-function deleteAccount (account) {
+function confirmDeleteAccount (account, confirmedLambda) {
window.attachVirtualWindow(Utils.buildCommonDialogUri('ConfirmDialog'), {
descriptionText: qsTr('deleteAccountDescription'),
}, function (status) {
if (status) {
- Linphone.AccountSettingsModel.removeAccount(account.account)
+ confirmedLambda()
+ Linphone.AccountSettingsModel.removeAccount(account.account, true)
}
})
}
+function confirmDeleteAccountUnregisterFailed (account, cancelLambda) {
+ window.attachVirtualWindow(Utils.buildCommonDialogUri('ConfirmDialog'), {
+ descriptionText: qsTr('deleteAccountDescriptionUnregisterFailed'),
+ }, function (status) {
+ if (status) {
+ Linphone.AccountSettingsModel.removeAccount(account.account, false)
+ } else {
+ cancelLambda()
+ }
+ })
+}
+
function eraseAllPasswords () {
window.attachVirtualWindow(Utils.buildCommonDialogUri('ConfirmDialog'), {
descriptionText: qsTr('eraseAllPasswordsDescription'),
diff --git a/linphone-app/ui/views/App/Settings/SettingsSipAccounts.qml b/linphone-app/ui/views/App/Settings/SettingsSipAccounts.qml
index 2f33ac6ea..a51bf1731 100644
--- a/linphone-app/ui/views/App/Settings/SettingsSipAccounts.qml
+++ b/linphone-app/ui/views/App/Settings/SettingsSipAccounts.qml
@@ -4,8 +4,10 @@ import QtQuick.Layouts 1.3
import Common 1.0
import Linphone 1.0
import UtilsCpp 1.0
+import 'qrc:/ui/scripts/Utils/utils.js' as Utils
import App.Styles 1.0
+import Common.Styles 1.0
import 'SettingsSipAccounts.js' as Logic
@@ -101,18 +103,42 @@ TabContainer {
isCustom: true
backgroundRadius: 4
colorSet: SettingsWindowStyle.buttons.editProxy
-
+ enabled: !deleteButton.deleteInProgress
onClicked: Logic.editAccount(modelData)
}
}
FormTableEntry {
ActionButton {
+ id: deleteButton
isCustom: true
backgroundRadius: 4
colorSet: SettingsWindowStyle.buttons.deleteProxy
-
- onClicked: Logic.deleteAccount(modelData)
+ property bool deleteInProgress: false
+ enabled: !deleteInProgress
+ onClicked: {
+ Logic.confirmDeleteAccount(modelData, function() {
+ deleteInProgress = true
+ })
+ }
+ Connections {
+ target: AccountSettingsModel
+ enabled: deleteButton.deleteInProgress
+ onUnregisterFailed: {
+ Logic.confirmDeleteAccountUnregisterFailed(modelData, function() {
+ deleteButton.deleteInProgress = false
+ })
+ }
+ }
+ BusyIndicator {
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ fill: parent
+ }
+ color: BusyIndicatorStyle.alternateColor.color
+ running: true
+ visible: deleteButton.deleteInProgress
+ }
}
}
}
diff --git a/linphone-app/ui/views/App/Styles/Settings/SettingsWindowStyle.qml b/linphone-app/ui/views/App/Styles/Settings/SettingsWindowStyle.qml
index 2a8b38e28..6307f9aa1 100644
--- a/linphone-app/ui/views/App/Styles/Settings/SettingsWindowStyle.qml
+++ b/linphone-app/ui/views/App/Styles/Settings/SettingsWindowStyle.qml
@@ -37,9 +37,11 @@ QtObject {
property string name : 'editProxy'
property string icon : 'edit_custom'
property var backgroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_n', icon, 'me_n_b_bg')
+ property var backgroundDisabledColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_n', icon, 'me_d_b_bg')
property var backgroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_h', icon, 'me_h_b_bg')
property var backgroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_p', icon, 'me_p_b_bg')
property var foregroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_n', icon, 'me_n_b_fg')
+ property var foregroundDisabledColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_n', icon, 'me_d_b_fg')
property var foregroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_h', icon, 'me_h_b_fg')
property var foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_p', icon, 'me_p_b_fg')
}
@@ -48,9 +50,11 @@ QtObject {
property string name : 'deleteProxy'
property string icon : 'delete_custom'
property var backgroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_n', icon, 'me_n_b_bg')
+ property var backgroundDisabledColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_n', icon, 'me_d_b_bg')
property var backgroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_h', icon, 'me_h_b_bg')
property var backgroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_p', icon, 'me_p_b_bg')
property var foregroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_n', icon, 'me_n_b_fg')
+ property var foregroundDisabledColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_n', icon, 'me_d_b_fg')
property var foregroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_h', icon, 'me_h_b_fg')
property var foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_p', icon, 'me_p_b_fg')
}