diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3c9736da..ceb7ffa5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -71,7 +71,7 @@ set(COMMON_SOURCES
${SRC_DIR}/pluginhandleritemlistmodel.cpp
${SRC_DIR}/preferenceitemlistmodel.cpp
${SRC_DIR}/mediacodeclistmodel.cpp
- ${SRC_DIR}/accountstomigratelistmodel.cpp
+ ${SRC_DIR}/currentaccounttomigrate.cpp
${SRC_DIR}/audiodevicemodel.cpp
${SRC_DIR}/pluginlistpreferencemodel.cpp
${SRC_DIR}/audiomanagerlistmodel.cpp
@@ -125,7 +125,7 @@ set(COMMON_HEADERS
${SRC_DIR}/pluginhandleritemlistmodel.h
${SRC_DIR}/preferenceitemlistmodel.h
${SRC_DIR}/mediacodeclistmodel.h
- ${SRC_DIR}/accountstomigratelistmodel.h
+ ${SRC_DIR}/currentaccounttomigrate.h
${SRC_DIR}/audiodevicemodel.h
${SRC_DIR}/pluginlistpreferencemodel.h
${SRC_DIR}/audiomanagerlistmodel.h
diff --git a/qml.qrc b/qml.qrc
index 65342816..b096a67f 100644
--- a/qml.qrc
+++ b/qml.qrc
@@ -15,7 +15,6 @@
src/commoncomponents/CustomBorder.qml
src/commoncomponents/PushButton.qml
src/commoncomponents/JamiFileDialog.qml
- src/commoncomponents/AccountMigrationDialog.qml
src/commoncomponents/MaterialButton.qml
src/commoncomponents/ElidedTextLabel.qml
src/commoncomponents/SpinnerButton.qml
@@ -173,5 +172,6 @@
src/commoncomponents/JamiScrollBar.qml
qtquickcontrols2.conf
src/commoncomponents/JamiFlickable.qml
+ src/AccountMigrationView.qml
diff --git a/src/commoncomponents/AccountMigrationDialog.qml b/src/AccountMigrationView.qml
similarity index 57%
rename from src/commoncomponents/AccountMigrationDialog.qml
rename to src/AccountMigrationView.qml
index ae5b14a0..d0cef649 100644
--- a/src/commoncomponents/AccountMigrationDialog.qml
+++ b/src/AccountMigrationView.qml
@@ -25,110 +25,36 @@ import net.jami.Models 1.1
import net.jami.Adapters 1.1
import net.jami.Constants 1.1
-import "../wizardview/components"
+import "commoncomponents"
// Account Migration Dialog for migrating account
+Rectangle {
+ id: root
-Window {
- id: accountMigrationDialog
-
- AccountsToMigrateListModel {
- id: accountsToMigrateListModel
-
- lrcInstance: LRCInstance
+ enum AccountMigrationStep {
+ PasswordEnter,
+ Synching
}
- property string accountID: ""
- property string password: ""
+ property bool successState: true
- property bool nonOperationClosing: true
- property bool successState : true
+ // signal to redirect the page to main view
+ signal loaderSourceChangeRequested(int sourceToLoad)
- signal accountMigrationFinished
+ function slotMigrationButtonClicked() {
+ stackedWidget.currentIndex = AccountMigrationView.AccountMigrationStep.Synching
- function startAccountMigrationOfTopStack() {
- passwordInputLineEdit.clear()
- accountsToMigrateListModel.reset()
-
- if (accountsToMigrateListModel.rowCount() <= 0) {
- closeWithoutOperation()
-
- return false
- }
-
- var managerUsername = accountsToMigrateListModel.data(accountsToMigrateListModel.index(
- 0, 0), AccountsToMigrateListModel.ManagerUsername)
- var managerUri = accountsToMigrateListModel.data(accountsToMigrateListModel.index(
- 0, 0), AccountsToMigrateListModel.ManagerUri)
- var username = accountsToMigrateListModel.data(accountsToMigrateListModel.index(
- 0, 0), AccountsToMigrateListModel.Username)
- var alias = accountsToMigrateListModel.data(accountsToMigrateListModel.index(
- 0, 0), AccountsToMigrateListModel.Alias)
-
- if (managerUri.length !== 0) {
- managerUriInputLabel.text = managerUri
- } else {
- managerUriInputLabel.text = "N/A"
- }
-
- if (username.length !== 0) {
- usernameInputLabel.text = username
- } else if (managerUsername.length !== 0) {
- usernameInputLabel.text = managerUsername
- } else {
- usernameInputLabel.text = "N/A"
- }
-
- if (alias.length !== 0) {
- aliasInputLabel.text = alias
- } else {
- aliasInputLabel.text = "N/A"
- }
-
- accountID = accountsToMigrateListModel.data(accountsToMigrateListModel.index(
- 0, 0), AccountsToMigrateListModel.Account_ID)
-
- connectionMigrationEnded.enabled = false
- migrationPushButton.enabled = false
- stackedWidget.currentIndex = 0
-
- successState = true
- nonOperationClosing = true
-
- accountMigrationDialog.show()
- return true
+ AccountAdapter.setArchivePasswordAsync(
+ CurrentAccountToMigrate.accountId, passwordInputLineEdit.text)
}
- function checkIfAccountMigrationFinishedAndClose() {
- accountsToMigrateListModel.reset()
- if (accountsToMigrateListModel.rowCount() > 0) {
- startAccountMigrationOfTopStack()
- } else {
- accountMigrationFinished()
- if (!nonOperationClosing) {
- nonOperationClosing = true
- accountMigrationDialog.close()
- }
- }
+ function slotDeleteButtonClicked() {
+ stackedWidget.currentIndex = AccountMigrationView.AccountMigrationStep.Synching
+
+ CurrentAccountToMigrate.removeCurrentAccountToMigrate()
}
- function acceptMigration() {
- nonOperationClosing = false
- accountsToMigrateListModel.dataChanged(accountsToMigrateListModel.index(0, 0),
- accountsToMigrateListModel.index(
- accountsToMigrateListModel.rowCount() - 1, 0))
- checkIfAccountMigrationFinishedAndClose()
- }
-
- function refuseMigrationAndDeleteAccount() {
- AccountAdapter.model.removeAccount(accountID)
- acceptMigration()
- }
-
- function closeWithoutOperation() {
- nonOperationClosing = false
- accountMigrationDialog.close()
- }
+ color: JamiTheme.backgroundColor
Timer {
id: timerFailureReturn
@@ -137,73 +63,46 @@ Window {
repeat: false
onTriggered: {
- stackedWidget.currentIndex = 0
+ stackedWidget.currentIndex =
+ AccountMigrationView.AccountMigrationStep.PasswordEnter
successState = true
}
}
Connections {
id: connectionMigrationEnded
- enabled: false
- target: AccountAdapter.model
- function onMigrationEnded(accountIdIn, ok) {
- nonOperationClosing = true
- connectionMigrationEnded.enabled = false
- if (accountID !== accountIdIn) {
- return
- }
+ target: CurrentAccountToMigrate
+
+ function onMigrationEnded(ok) {
+ successState = ok
+
if (ok) {
- acceptMigration()
+ passwordInputLineEdit.clear()
+
+ stackedWidget.currentIndex =
+ AccountMigrationView.AccountMigrationStep.PasswordEnter
} else {
- successState = false
timerFailureReturn.restart()
}
}
- }
- function slotMigrationButtonClicked() {
- successState = true
- stackedWidget.currentIndex = 1
+ function onCurrentAccountToMigrateRemoved() {
+ successState = true
+ passwordInputLineEdit.clear()
- connectionMigrationEnded.enabled = true
- AccountAdapter.setArchivePasswordAsync(accountID,password)
- }
-
- function slotDeleteButtonClicked() {
- nonOperationClosing = false
- refuseMigrationAndDeleteAccount()
- }
-
- onClosing: {
- connectionMigrationEnded.enabled = false
- stackedWidget.currentIndex = 0
- accountID = ""
- password = ""
- passwordInputLineEdit.clear()
- managerUriInputLabel.text = ""
- usernameInputLabel.text = ""
- aliasInputLabel.text = ""
-
- if (nonOperationClosing) {
- checkIfAccountMigrationFinishedAndClose()
+ stackedWidget.currentIndex =
+ AccountMigrationView.AccountMigrationStep.PasswordEnter
}
- nonOperationClosing = true
- }
- visible: false
-
- title: JamiStrings.authenticate
- flags: Qt.WindowStaysOnTopHint
-
- width: 600
- height: 600
- minimumWidth: 600
- minimumHeight: 600
-
- Component.onCompleted: {
- setX(Screen.width / 2 - width / 2)
- setY(Screen.height / 2 - height / 2)
+ function onAllMigrationsFinished() {
+ if (UtilsAdapter.getAccountListSize() === 0)
+ root.loaderSourceChangeRequested(
+ MainApplicationWindow.LoadedSource.WizardView)
+ else
+ root.loaderSourceChangeRequested(
+ MainApplicationWindow.LoadedSource.MainView)
+ }
}
ColumnLayout {
@@ -217,22 +116,14 @@ Window {
Layout.fillHeight: true
Layout.alignment: Qt.AlignHCenter
- currentIndex: 0
-
// Index = 0
Rectangle {
id: accountMigrationPage
- Layout.fillWidth: true
- Layout.fillHeight: true
- Layout.alignment: Qt.AlignHCenter
-
ColumnLayout {
spacing: 8
- width: stackedWidget.width
- height: stackedWidget.height
- Layout.alignment: Qt.AlignHCenter
+ anchors.fill: accountMigrationPage
Label {
id: accountMigrationLabel
@@ -266,7 +157,7 @@ Window {
verticalAlignment: Text.AlignVCenter
}
- Label {
+ Avatar {
id: avatarLabel
Layout.preferredWidth: 200
@@ -274,19 +165,9 @@ Window {
Layout.alignment: Qt.AlignHCenter
- background: Rectangle {
- id: avatarLabelBackground
-
- anchors.fill: parent
- color: "transparent"
-
- Avatar {
- anchors.fill: parent
- showPresenceIndicator: false
- mode: Avatar.Mode.Account
- imageId: accountID
- }
- }
+ showPresenceIndicator: false
+ mode: Avatar.Mode.Account
+ imageId: CurrentAccountToMigrate.accountId
}
GridLayout {
@@ -321,6 +202,13 @@ Window {
Layout.preferredWidth: JamiTheme.preferredFieldWidth
Layout.preferredHeight: JamiTheme.preferredFieldHeight
+ text: {
+ if (CurrentAccountToMigrate.alias.length !== 0) {
+ return CurrentAccountToMigrate.alias
+ } else {
+ return JamiStrings.notAvailable
+ }
+ }
font.pointSize: JamiTheme.textFontSize
font.kerning: true
@@ -349,6 +237,15 @@ Window {
Layout.preferredWidth: JamiTheme.preferredFieldWidth
Layout.preferredHeight: JamiTheme.preferredFieldHeight
+ text: {
+ if (CurrentAccountToMigrate.username.length !== 0) {
+ return CurrentAccountToMigrate.username
+ } else if (CurrentAccountToMigrate.managerUsername.length !== 0) {
+ return CurrentAccountToMigrate.managerUsername
+ } else {
+ return JamiStrings.notAvailable
+ }
+ }
font.pointSize: JamiTheme.textFontSize
font.kerning: true
@@ -377,6 +274,13 @@ Window {
Layout.preferredWidth: JamiTheme.preferredFieldWidth
Layout.preferredHeight: JamiTheme.preferredFieldHeight
+ text: {
+ if (CurrentAccountToMigrate.managerUri.length !== 0) {
+ return CurrentAccountToMigrate.managerUri
+ } else {
+ return JamiStrings.notAvailable
+ }
+ }
font.pointSize: JamiTheme.textFontSize
font.kerning: true
@@ -410,22 +314,15 @@ Window {
Layout.preferredHeight: 48
echoMode: TextInput.Password
-
placeholderText: JamiStrings.password
- onTextChanged: {
- migrationPushButton.enabled = text.length > 0
- password = text
- }
-
- onEditingFinished: {
- password = text
- }
+ onAccepted: slotMigrationButtonClicked()
}
}
RowLayout {
spacing: 80
+
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
Layout.bottomMargin: JamiTheme.preferredMarginSize
@@ -441,12 +338,11 @@ Window {
hoveredColor: JamiTheme.buttonTintedBlackHovered
pressedColor: JamiTheme.buttonTintedBlackPressed
outlined: true
+ enabled: passwordInputLineEdit.text.length > 0
text: JamiStrings.authenticate
- onClicked: {
- slotMigrationButtonClicked()
- }
+ onClicked: slotMigrationButtonClicked()
}
MaterialButton {
@@ -462,9 +358,7 @@ Window {
outlined: true
text: JamiStrings.deleteAccount
- onClicked: {
- slotDeleteButtonClicked()
- }
+ onClicked: slotDeleteButtonClicked()
}
}
}
@@ -491,7 +385,24 @@ Window {
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
- Label {
+ ResponsiveImage {
+ id: errorLabel
+
+ Layout.alignment: Qt.AlignHCenter
+
+ Layout.preferredWidth: 200
+ Layout.preferredHeight: 200
+
+ containerHeight: Layout.preferredHeight
+ containerWidth: Layout.preferredWidth
+
+ visible: !successState
+
+ source: JamiResources.round_remove_circle_24dp_svg
+ color: JamiTheme.redColor
+ }
+
+ AnimatedImage {
id: spinnerLabel
Layout.alignment: Qt.AlignHCenter
@@ -499,29 +410,13 @@ Window {
Layout.preferredWidth: 200
Layout.preferredHeight: 200
- property string spinnerDisplyState: successState ? "spinnerLabel_Regular" : "spinnerLabel_Failure"
- onSpinnerDisplyStateChanged: {
- switch (spinnerDisplyState) {
- case "spinnerLabel_Regular":
- background = Qt.createQmlObject("import QtQuick;
- import \"qrc:/src/constant/\";
- AnimatedImage {
- source: JamiResources.jami_eclipse_spinner_gif
- playing: true
- paused: false
- fillMode: Image.PreserveAspectFit
- mipmap: true}", spinnerLabel)
- break
- case "spinnerLabel_Failure":
- background = Qt.createQmlObject("import QtQuick;
- import \"qrc:/src/constant/\";
- Image {
- anchors.fill: parent;
- source: JamiResources.error_outline_black_24dp_svg;
- mipmap: true;}", spinnerLabel)
- break
- }
- }
+ visible: successState
+
+ source: JamiResources.jami_eclipse_spinner_gif
+
+ playing: successState
+ fillMode: Image.PreserveAspectFit
+ mipmap: true
}
}
@@ -532,9 +427,10 @@ Window {
Layout.fillWidth: true
Layout.bottomMargin: 80
- color: successState? "black" : "red"
- text: successState? JamiStrings.inProgress : JamiStrings.authenticationFailed
- font.pointSize: JamiTheme.textFontSize
+ color: successState ? JamiTheme.textColor : JamiTheme.redColor
+ text: successState ? JamiStrings.inProgress :
+ JamiStrings.authenticationFailed
+ font.pointSize: JamiTheme.textFontSize + 5
font.kerning: true
horizontalAlignment: Text.AlignHCenter
diff --git a/src/MainApplicationWindow.qml b/src/MainApplicationWindow.qml
index 792e9ef8..5efde197 100644
--- a/src/MainApplicationWindow.qml
+++ b/src/MainApplicationWindow.qml
@@ -42,6 +42,7 @@ ApplicationWindow {
enum LoadedSource {
WizardView = 0,
MainView,
+ AccountMigrationView,
None
}
@@ -63,11 +64,7 @@ ApplicationWindow {
return MainApplicationWindow.LoadedSource.None
}
- function startAccountMigration(){
- return accountMigrationDialog.startAccountMigrationOfTopStack()
- }
-
- function startClient(){
+ function startClient() {
if (UtilsAdapter.getAccountListSize() !== 0) {
mainApplicationLoader.setSource(JamiQmlUtils.mainViewLoadPath)
} else {
@@ -75,6 +72,10 @@ ApplicationWindow {
}
}
+ function startAccountMigration() {
+ mainApplicationLoader.setSource(JamiQmlUtils.accountMigrationViewLoadPath)
+ }
+
function close(force = false) {
// If we're in the onboarding wizard or 'MinimizeOnClose'
// is set, then we can quit
@@ -123,14 +124,6 @@ ApplicationWindow {
anchors.fill: parent
}
- AccountMigrationDialog {
- id: accountMigrationDialog
-
- visible: false
-
- onAccountMigrationFinished: startClient()
- }
-
DaemonReconnectPopup {
id: daemonReconnectPopup
}
@@ -225,9 +218,11 @@ ApplicationWindow {
onScreenChanged: JamiQmlUtils.mainApplicationScreen = root.screen
Component.onCompleted: {
- if(!startAccountMigration()){
+ if (CurrentAccountToMigrate.accountToMigrateListSize <= 0)
startClient()
- }
+ else
+ startAccountMigration()
+
JamiQmlUtils.mainApplicationScreen = root.screen
if (Qt.platform.os !== "windows")
diff --git a/src/accountstomigratelistmodel.cpp b/src/accountstomigratelistmodel.cpp
deleted file mode 100644
index b05bd614..00000000
--- a/src/accountstomigratelistmodel.cpp
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2019-2020 by Savoir-faire Linux
- * Author: Yang Wang
- *
- * 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 .
- */
-
-#include "accountstomigratelistmodel.h"
-
-#include "lrcinstance.h"
-
-#include "api/account.h"
-#include "api/contact.h"
-#include "api/conversation.h"
-#include "api/newdevicemodel.h"
-
-AccountsToMigrateListModel::AccountsToMigrateListModel(QObject* parent)
- : AbstractListModelBase(parent)
-{}
-
-AccountsToMigrateListModel::~AccountsToMigrateListModel() {}
-
-int
-AccountsToMigrateListModel::rowCount(const QModelIndex& parent) const
-{
- if (!parent.isValid() && lrcInstance_) {
- /*
- * Count.
- */
- auto accountList = lrcInstance_->accountModel().getAccountList();
-
- int countAccountToMigrate = 0;
-
- for (const QString& i : accountList) {
- auto accountStatus = lrcInstance_->accountModel().getAccountInfo(i).status;
- if (accountStatus == lrc::api::account::Status::ERROR_NEED_MIGRATION) {
- countAccountToMigrate++;
- }
- }
-
- return countAccountToMigrate;
- }
- /*
- * A valid QModelIndex returns 0 as no entry has sub-elements.
- */
- return 0;
-}
-
-int
-AccountsToMigrateListModel::columnCount(const QModelIndex& parent) const
-{
- Q_UNUSED(parent);
- /*
- * Only need one column.
- */
- return 1;
-}
-
-QVariant
-AccountsToMigrateListModel::data(const QModelIndex& index, int role) const
-{
- auto accountList = lrcInstance_->accountModel().getAccountList();
- if (!index.isValid() || accountList.size() <= index.row()) {
- return QVariant();
- }
-
- QList accountToMigrateList;
-
- for (QString i : accountList) {
- auto accountStatus = lrcInstance_->accountModel().getAccountInfo(i).status;
- if (accountStatus == lrc::api::account::Status::ERROR_NEED_MIGRATION) {
- accountToMigrateList.append(i);
- }
- }
-
- QString accountId = accountToMigrateList.at(index.row());
-
- auto& avatarInfo = lrcInstance_->accountModel().getAccountInfo(accountId);
-
- switch (role) {
- case Role::Account_ID:
- return QVariant(accountId);
- case Role::ManagerUsername:
- return QVariant(avatarInfo.confProperties.managerUsername);
- case Role::ManagerUri:
- return QVariant(avatarInfo.confProperties.managerUri);
- case Role::Username:
- return QVariant(avatarInfo.confProperties.username);
- case Role::Alias:
- return QVariant(lrcInstance_->accountModel().getAccountInfo(accountId).profileInfo.alias);
- }
- return QVariant();
-}
-
-QHash
-AccountsToMigrateListModel::roleNames() const
-{
- QHash roles;
- roles[Account_ID] = "Account_ID";
- roles[ManagerUsername] = "ManagerUsername";
- roles[ManagerUri] = "ManagerUri";
- roles[Username] = "Username";
- roles[Alias] = "Alias";
- return roles;
-}
-
-QModelIndex
-AccountsToMigrateListModel::index(int row, int column, const QModelIndex& parent) const
-{
- Q_UNUSED(parent);
- if (column != 0) {
- return QModelIndex();
- }
-
- if (row >= 0 && row < rowCount()) {
- return createIndex(row, column);
- }
- return QModelIndex();
-}
-
-QModelIndex
-AccountsToMigrateListModel::parent(const QModelIndex& child) const
-{
- Q_UNUSED(child);
- return QModelIndex();
-}
-
-Qt::ItemFlags
-AccountsToMigrateListModel::flags(const QModelIndex& index) const
-{
- auto flags = QAbstractItemModel::flags(index) | Qt::ItemNeverHasChildren | Qt::ItemIsSelectable;
- if (!index.isValid()) {
- return QAbstractItemModel::flags(index);
- }
- return flags;
-}
-
-void
-AccountsToMigrateListModel::reset()
-{
- beginResetModel();
- endResetModel();
-}
diff --git a/src/accountstomigratelistmodel.h b/src/accountstomigratelistmodel.h
deleted file mode 100644
index 9b4d2ebf..00000000
--- a/src/accountstomigratelistmodel.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2019-2020 by Savoir-faire Linux
- * Author: Yang Wang
- *
- * 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 .
- */
-
-#pragma once
-
-#include "abstractlistmodelbase.h"
-
-class AccountsToMigrateListModel : public AbstractListModelBase
-{
- Q_OBJECT
-public:
- enum Role { Account_ID = Qt::UserRole + 1, ManagerUsername, ManagerUri, Username, Alias };
- Q_ENUM(Role)
-
- explicit AccountsToMigrateListModel(QObject* parent = nullptr);
- ~AccountsToMigrateListModel();
-
- /*
- * QAbstractListModel override.
- */
- int rowCount(const QModelIndex& parent = QModelIndex()) const override;
- int columnCount(const QModelIndex& parent) const override;
- QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
- /*
- * Override role name as access point in qml.
- */
- QHash roleNames() const override;
- QModelIndex index(int row, int column = 0, const QModelIndex& parent = QModelIndex()) const;
- QModelIndex parent(const QModelIndex& child) const;
- Qt::ItemFlags flags(const QModelIndex& index) const;
-
- /*
- * This function is to reset the model when there's new account added.
- */
- Q_INVOKABLE void reset();
-};
diff --git a/src/constant/JamiQmlUtils.qml b/src/constant/JamiQmlUtils.qml
index a1e9c2a3..b2f545ed 100644
--- a/src/constant/JamiQmlUtils.qml
+++ b/src/constant/JamiQmlUtils.qml
@@ -28,6 +28,7 @@ Item {
readonly property string mainViewLoadPath: "qrc:/src/mainview/MainView.qml"
readonly property string wizardViewLoadPath: "qrc:/src/wizardview/WizardView.qml"
+ readonly property string accountMigrationViewLoadPath: "qrc:/src/AccountMigrationView.qml"
readonly property string base64StringTitle: "data:image/png;base64,"
property var mainApplicationScreen: ""
diff --git a/src/currentaccounttomigrate.cpp b/src/currentaccounttomigrate.cpp
new file mode 100644
index 00000000..db3e86b3
--- /dev/null
+++ b/src/currentaccounttomigrate.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2019-2020 by Savoir-faire Linux
+ * Author: Yang Wang
+ * Author: Mingrui Zhang
+ *
+ * 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 .
+ */
+
+#include "currentaccounttomigrate.h"
+
+#include "lrcinstance.h"
+
+#include "api/account.h"
+#include "api/contact.h"
+#include "api/conversation.h"
+#include "api/newdevicemodel.h"
+
+CurrentAccountToMigrate::CurrentAccountToMigrate(LRCInstance* instance, QObject* parent)
+ : QObject(parent)
+ , lrcInstance_(instance)
+{
+ auto accountList = lrcInstance_->accountModel().getAccountList();
+
+ for (const QString& i : accountList) {
+ auto accountStatus = lrcInstance_->accountModel().getAccountInfo(i).status;
+ if (accountStatus == lrc::api::account::Status::ERROR_NEED_MIGRATION) {
+ accountToMigrateList_.append(i);
+ }
+ }
+
+ if (accountToMigrateList_.size()) {
+ migrationEndedConnection_ = connect(
+ &lrcInstance_->accountModel(),
+ &lrc::api::NewAccountModel::migrationEnded,
+ this,
+ [this](const QString& accountId, bool ok) {
+ if (ok && accountToMigrateList_.removeOne(accountId)) {
+ updateData();
+ }
+
+ if (accountToMigrateList_.isEmpty()) {
+ disconnect(migrationEndedConnection_);
+ Q_EMIT allMigrationsFinished();
+
+ return;
+ }
+
+ Q_EMIT migrationEnded(ok);
+ },
+ Qt::ConnectionType::QueuedConnection);
+
+ updateData();
+ }
+}
+
+CurrentAccountToMigrate::~CurrentAccountToMigrate() {}
+
+void
+CurrentAccountToMigrate::removeCurrentAccountToMigrate()
+{
+ if (accountToMigrateList_.removeOne(get_accountId())) {
+ updateData();
+ }
+
+ Utils::oneShotConnect(&lrcInstance_->accountModel(),
+ &lrc::api::NewAccountModel::accountRemoved,
+ [this] {
+ if (accountToMigrateList_.isEmpty())
+ Q_EMIT allMigrationsFinished();
+ else
+ Q_EMIT currentAccountToMigrateRemoved();
+ });
+
+ lrcInstance_->accountModel().removeAccount(get_accountId());
+}
+
+void
+CurrentAccountToMigrate::updateData()
+{
+ set_accountToMigrateListSize(accountToMigrateList_.size());
+ if (get_accountToMigrateListSize() == 0)
+ return;
+
+ QString accountId = accountToMigrateList_.at(0);
+
+ auto& avatarInfo = lrcInstance_->accountModel().getAccountInfo(accountId);
+
+ set_accountId(accountId);
+ set_managerUsername(avatarInfo.confProperties.managerUsername);
+ set_managerUri(avatarInfo.confProperties.managerUri);
+ set_username(avatarInfo.confProperties.username);
+ set_alias(lrcInstance_->accountModel().getAccountInfo(accountId).profileInfo.alias);
+}
diff --git a/src/currentaccounttomigrate.h b/src/currentaccounttomigrate.h
new file mode 100644
index 00000000..d39f4ff6
--- /dev/null
+++ b/src/currentaccounttomigrate.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2019-2020 by Savoir-faire Linux
+ * Author: Yang Wang
+ * Author: Mingrui Zhang
+ *
+ * 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 .
+ */
+
+#pragma once
+
+#include
+
+#include "qtutils.h"
+
+class LRCInstance;
+
+class CurrentAccountToMigrate : public QObject
+{
+ Q_OBJECT
+ QML_RO_PROPERTY(int, accountToMigrateListSize)
+ QML_RO_PROPERTY(QString, accountId)
+ QML_RO_PROPERTY(QString, managerUsername)
+ QML_RO_PROPERTY(QString, managerUri)
+ QML_RO_PROPERTY(QString, username)
+ QML_RO_PROPERTY(QString, alias)
+
+public:
+ explicit CurrentAccountToMigrate(LRCInstance* lrcInstance, QObject* parent = nullptr);
+ ~CurrentAccountToMigrate();
+
+ Q_INVOKABLE void removeCurrentAccountToMigrate();
+
+Q_SIGNALS:
+ void migrationEnded(bool success);
+ void allMigrationsFinished();
+ void currentAccountToMigrateRemoved();
+
+private:
+ void updateData();
+
+ LRCInstance* lrcInstance_;
+
+ // It will only be updated when starting to launch the client.
+ QList accountToMigrateList_;
+
+ QMetaObject::Connection migrationEndedConnection_;
+};
diff --git a/src/qmlregister.cpp b/src/qmlregister.cpp
index 759b0043..72182e29 100644
--- a/src/qmlregister.cpp
+++ b/src/qmlregister.cpp
@@ -30,9 +30,9 @@
#include "currentconversation.h"
#include "currentaccount.h"
#include "videodevices.h"
+#include "currentaccounttomigrate.h"
#include "accountlistmodel.h"
-#include "accountstomigratelistmodel.h"
#include "mediacodeclistmodel.h"
#include "audiodevicemodel.h"
#include "audiomanagerlistmodel.h"
@@ -117,6 +117,7 @@ registerTypes(QQmlEngine* engine,
auto currentConversation = new CurrentConversation(lrcInstance, parent);
auto currentAccount = new CurrentAccount(lrcInstance, settingsManager, parent);
auto videoDevices = new VideoDevices(lrcInstance, parent);
+ auto currentAccountToMigrate = new CurrentAccountToMigrate(lrcInstance, parent);
// qml adapter registration
QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, callAdapter, "CallAdapter");
@@ -130,6 +131,7 @@ registerTypes(QQmlEngine* engine,
QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, currentConversation, "CurrentConversation");
QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, currentAccount, "CurrentAccount");
QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, videoDevices, "VideoDevices");
+ QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, currentAccountToMigrate, "CurrentAccountToMigrate")
// TODO: remove these
QML_REGISTERSINGLETONTYPE_CUSTOM(NS_MODELS, AVModel, &lrcInstance->avModel())
@@ -151,7 +153,6 @@ registerTypes(QQmlEngine* engine,
QML_REGISTERTYPE(NS_MODELS, BannedListModel);
QML_REGISTERTYPE(NS_MODELS, ModeratorListModel);
QML_REGISTERTYPE(NS_MODELS, MediaCodecListModel);
- QML_REGISTERTYPE(NS_MODELS, AccountsToMigrateListModel);
QML_REGISTERTYPE(NS_MODELS, AudioDeviceModel);
QML_REGISTERTYPE(NS_MODELS, AudioManagerListModel);
QML_REGISTERTYPE(NS_MODELS, PluginListPreferenceModel);