diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3c9736da21735b78504c2469fc2257e8c881e0da..ceb7ffa5d6a0a58be13c88286e0e17f15755020e 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 65342816fdd1fdaa2c246ddf76df794a7b9b03b4..b096a67f75b3b0afb0a4cef84a7ce5e88bd2bbec 100644
--- a/qml.qrc
+++ b/qml.qrc
@@ -15,7 +15,6 @@
         <file>src/commoncomponents/CustomBorder.qml</file>
         <file>src/commoncomponents/PushButton.qml</file>
         <file>src/commoncomponents/JamiFileDialog.qml</file>
-        <file>src/commoncomponents/AccountMigrationDialog.qml</file>
         <file>src/commoncomponents/MaterialButton.qml</file>
         <file>src/commoncomponents/ElidedTextLabel.qml</file>
         <file>src/commoncomponents/SpinnerButton.qml</file>
@@ -173,5 +172,6 @@
         <file>src/commoncomponents/JamiScrollBar.qml</file>
         <file>qtquickcontrols2.conf</file>
         <file>src/commoncomponents/JamiFlickable.qml</file>
+        <file>src/AccountMigrationView.qml</file>
     </qresource>
 </RCC>
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 ae5b14a04d1257871f5dbea99be60cdaa3f4b265..d0cef649bc3526e7f7ae56e2b4abc7bb70c271bd 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 nonOperationClosing: true
-    property bool successState : true
-
-    signal accountMigrationFinished
-
-    function startAccountMigrationOfTopStack() {
-        passwordInputLineEdit.clear()
-        accountsToMigrateListModel.reset()
-
-        if (accountsToMigrateListModel.rowCount() <= 0) {
-            closeWithoutOperation()
+    property bool successState: true
 
-            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"
-        }
+    // signal to redirect the page to main view
+    signal loaderSourceChangeRequested(int sourceToLoad)
 
-        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
-    }
+    function slotMigrationButtonClicked() {
+        stackedWidget.currentIndex = AccountMigrationView.AccountMigrationStep.Synching
 
-    function checkIfAccountMigrationFinishedAndClose() {
-        accountsToMigrateListModel.reset()
-        if (accountsToMigrateListModel.rowCount() > 0) {
-            startAccountMigrationOfTopStack()
-        } else {
-            accountMigrationFinished()
-            if (!nonOperationClosing) {
-                nonOperationClosing = true
-                accountMigrationDialog.close()
-            }
-        }
+        AccountAdapter.setArchivePasswordAsync(
+                    CurrentAccountToMigrate.accountId, passwordInputLineEdit.text)
     }
 
-    function acceptMigration() {
-        nonOperationClosing = false
-        accountsToMigrateListModel.dataChanged(accountsToMigrateListModel.index(0, 0),
-                                               accountsToMigrateListModel.index(
-                                               accountsToMigrateListModel.rowCount() - 1, 0))
-        checkIfAccountMigrationFinishedAndClose()
-    }
+    function slotDeleteButtonClicked() {
+        stackedWidget.currentIndex = AccountMigrationView.AccountMigrationStep.Synching
 
-    function refuseMigrationAndDeleteAccount() {
-        AccountAdapter.model.removeAccount(accountID)
-        acceptMigration()
+        CurrentAccountToMigrate.removeCurrentAccountToMigrate()
     }
 
-    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
-
-        connectionMigrationEnded.enabled = true
-        AccountAdapter.setArchivePasswordAsync(accountID,password)
-    }
-
-    function slotDeleteButtonClicked() {
-        nonOperationClosing = false
-        refuseMigrationAndDeleteAccount()
-    }
+        function onCurrentAccountToMigrateRemoved() {
+            successState = true
+            passwordInputLineEdit.clear()
 
-    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 792e9ef8da3e41dd8052dff2819e37c95f3384b3..5efde1979c107b7726d4229fd924cc5d5bb7f6d5 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 b05bd614623f5e981ce05de7913ebb8ef7c2d5f8..0000000000000000000000000000000000000000
--- a/src/accountstomigratelistmodel.cpp
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2019-2020 by Savoir-faire Linux
- * Author: Yang Wang   <yang.wang@savoirfairelinux.com>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-#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<QString> 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<int, QByteArray>
-AccountsToMigrateListModel::roleNames() const
-{
-    QHash<int, QByteArray> 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 9b4d2ebfcc6fcc9e7c5a49ccd5cc38e32af40280..0000000000000000000000000000000000000000
--- a/src/accountstomigratelistmodel.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2019-2020 by Savoir-faire Linux
- * Author: Yang Wang   <yang.wang@savoirfairelinux.com>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-#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<int, QByteArray> 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 a1e9c2a32a6310e8334fda8725f7fc5f51f6fddc..b2f545ed2e6eab3d89a820f45b48c06ba88fae06 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 0000000000000000000000000000000000000000..db3e86b3dc01a16fbd896a93a7286bab0a53d7dd
--- /dev/null
+++ b/src/currentaccounttomigrate.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2019-2020 by Savoir-faire Linux
+ * Author: Yang Wang   <yang.wang@savoirfairelinux.com>
+ * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#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 0000000000000000000000000000000000000000..d39f4ff6c90f323bb62c8143e1e426a0bf500110
--- /dev/null
+++ b/src/currentaccounttomigrate.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2019-2020 by Savoir-faire Linux
+ * Author: Yang Wang   <yang.wang@savoirfairelinux.com>
+ * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <QObject>
+
+#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<QString> accountToMigrateList_;
+
+    QMetaObject::Connection migrationEndedConnection_;
+};
diff --git a/src/qmlregister.cpp b/src/qmlregister.cpp
index 759b0043c37ecb9c43d671b2ed1d97faa487646f..72182e29055cb28225346ec7c683ce2e6531dd5a 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);