From 2e0e250a2c53b7e307ba9a3caa89ef76b6d19e22 Mon Sep 17 00:00:00 2001
From: Ming Rui Zhang <mingrui.zhang@savoirfairelinux.com>
Date: Fri, 4 Sep 2020 14:57:36 -0400
Subject: [PATCH] wizardview: logic refinement for account creation and minor
 UI changes

1. Add spinner button and logic when waitting for account created to
prevent reclicking the buttons

2. Add back button when creating accounts in main view.

3. Fix the look up username bug

4. Change some buttons to blue styled

5. Change back button to back arrow

6. Add autofocus when entering certain page

Gitlab: #59
Change-Id: I3cada8c07a6605f091001db75a2913cde379c41b
---
 qml.qrc                                       |   2 +-
 src/accountadapter.cpp                        |   6 +-
 src/commoncomponents/MaterialButton.qml       |  20 +++
 src/commoncomponents/MaterialLineEdit.qml     | 102 +++++++----
 src/commoncomponents/SpinnerButton.qml        |  37 ++++
 src/settingsview/SettingsView.qml             |  10 +-
 src/wizardview/WizardView.qml                 | 163 +++++++-----------
 .../ConnectToAccountManagerPage.qml           |  67 ++++---
 .../components/CreateAccountPage.qml          | 106 ++++++------
 .../components/CreateSIPAccountPage.qml       |  40 +++--
 .../components/ImportFromBackupPage.qml       |  73 +++++---
 .../components/ImportFromDevicePage.qml       |  64 ++++---
 src/wizardview/components/ProfilePage.qml     |  21 ++-
 src/wizardview/components/SpinnerPage.qml     | 110 ------------
 src/wizardview/components/WelcomePage.qml     |  56 ++++--
 15 files changed, 468 insertions(+), 409 deletions(-)
 create mode 100644 src/commoncomponents/SpinnerButton.qml
 delete mode 100644 src/wizardview/components/SpinnerPage.qml

diff --git a/qml.qrc b/qml.qrc
index 6a45fb228..fcc6b2d32 100644
--- a/qml.qrc
+++ b/qml.qrc
@@ -45,7 +45,6 @@
         <file>src/wizardview/components/BackupKeyPage.qml</file>
         <file>src/wizardview/components/ImportFromDevicePage.qml</file>
         <file>src/wizardview/components/ConnectToAccountManagerPage.qml</file>
-        <file>src/wizardview/components/SpinnerPage.qml</file>
         <file>src/wizardview/components/ProfilePage.qml</file>
         <file>src/wizardview/components/CollapsiblePasswordWidget.qml</file>
         <file>src/MainApplicationWindow.qml</file>
@@ -111,5 +110,6 @@
         <file>src/commoncomponents/Scaffold.qml</file>
         <file>src/constant/JamiQmlUtils.qml</file>
         <file>src/wizardview/components/AccountCreationStepIndicator.qml</file>
+        <file>src/commoncomponents/SpinnerButton.qml</file>
     </qresource>
 </RCC>
diff --git a/src/accountadapter.cpp b/src/accountadapter.cpp
index d924bff90..723db1e90 100644
--- a/src/accountadapter.cpp
+++ b/src/accountadapter.cpp
@@ -86,6 +86,7 @@ AccountAdapter::createJamiAccount(QString registeredName,
                 Utils::oneShotConnect(&LRCInstance::accountModel(),
                                       &lrc::api::NewAccountModel::nameRegistrationEnded,
                                       [this, showBackup](const QString &accountId) {
+                                          emit LRCInstance::instance().accountListChanged();
                                           emit accountAdded(showBackup,
                                                             LRCInstance::accountModel()
                                                                 .getAccountList()
@@ -95,6 +96,7 @@ AccountAdapter::createJamiAccount(QString registeredName,
                                                          settings["password"].toString(),
                                                          registeredName);
             } else {
+                emit LRCInstance::instance().accountListChanged();
                 emit accountAdded(showBackup,
                                   LRCInstance::accountModel().getAccountList().indexOf(accountId));
             }
@@ -152,6 +154,7 @@ AccountAdapter::createSIPAccount(const QVariantMap &settings, QString photoBooth
                                                                    accountId);
                               }
 
+                              emit LRCInstance::instance().accountListChanged();
                               emit accountAdded(false,
                                                 LRCInstance::accountModel().getAccountList().indexOf(
                                                     accountId));
@@ -171,8 +174,6 @@ AccountAdapter::createSIPAccount(const QVariantMap &settings, QString photoBooth
                                                      "",
                                                      settings["username"].toString(),
                                                      additionalAccountConfig);
-        QThread::sleep(2);
-        emit LRCInstance::instance().accountListChanged();
     });
 }
 
@@ -209,6 +210,7 @@ void
 AccountAdapter::deleteCurrentAccount()
 {
     LRCInstance::accountModel().removeAccount(LRCInstance::getCurrAccId());
+    emit LRCInstance::instance().accountListChanged();
 }
 
 bool
diff --git a/src/commoncomponents/MaterialButton.qml b/src/commoncomponents/MaterialButton.qml
index 2129873f8..969a3c54f 100644
--- a/src/commoncomponents/MaterialButton.qml
+++ b/src/commoncomponents/MaterialButton.qml
@@ -26,12 +26,14 @@ import "../constant"
 Button {
     id: root
 
+    property alias fontCapitalization: buttonText.font.capitalization
     property alias source: root.icon.source
     property string toolTipText: ""
     property var color: "transparent"
     property var hoveredColor: undefined
     property var pressedColor: undefined
     property var outlined: false
+    property string animatedImageSource: ""
 
     property var preferredWidth: 400
     property var preferredHeight: 36
@@ -43,6 +45,7 @@ Button {
     icon.source: ""
     icon.height: 18
     icon.width: 18
+
     hoverEnabled: hoveredColor !== undefined
 
     contentItem: Item {
@@ -52,6 +55,21 @@ Button {
             RowLayout {
                 anchors.fill: parent
                 anchors.centerIn: parent
+
+                AnimatedImage {
+                    Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
+                    Layout.leftMargin: 8
+                    Layout.preferredHeight: root.icon.height
+                    Layout.preferredWidth: root.icon.width
+
+                    source: animatedImageSource
+                    playing: true
+                    paused: false
+                    fillMode: Image.PreserveAspectFit
+                    mipmap: true
+                    visible: animatedImageSource !== ""
+                }
+
                 Image {
                     source: root.icon.source
                     Layout.preferredWidth: root.icon.width
@@ -75,6 +93,8 @@ Button {
                     }
                 }
                 Text {
+                    id: buttonText
+
                     Layout.rightMargin: root.icon.width + JamiTheme.preferredMarginSize / 2
                     text: root.text
                     elide: root.elide
diff --git a/src/commoncomponents/MaterialLineEdit.qml b/src/commoncomponents/MaterialLineEdit.qml
index f7a43222e..a2829c119 100644
--- a/src/commoncomponents/MaterialLineEdit.qml
+++ b/src/commoncomponents/MaterialLineEdit.qml
@@ -1,7 +1,24 @@
+/*
+ * Copyright (C) 2020 by Savoir-faire Linux
+ * Author: Sébastien blin <sebastien.blin@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 <https://www.gnu.org/licenses/>.
+ */
+
 import QtQuick 2.14
 import QtQuick.Controls 2.14
 import QtQuick.Layouts 1.14
-import QtQuick.Controls.Styles 1.4
 import QtGraphicalEffects 1.15
 
 import "../constant"
@@ -9,6 +26,7 @@ import "../constant"
 TextField {
     enum BorderColorMode {
         NORMAL,
+        SEARCHING,
         RIGHT,
         ERROR
     }
@@ -17,37 +35,39 @@ TextField {
     property int fieldLayoutHeight: 48
     property bool layoutFillwidth: false
 
-    property int borderColorMode: InfoLineEdit.NORMAL
-    property var iconSource: {
-        if (readOnly) {
-            return ""
-        }
-        switch(borderColorMode){
-        case InfoLineEdit.RIGHT:
-            return "qrc:/images/icons/round-check_circle-24px.svg"
-        case InfoLineEdit.NORMAL:
-            return ""
-        case InfoLineEdit.ERROR:
-            return "qrc:/images/icons/round-error-24px.svg"
-        }
-    }
+    property int borderColorMode: MaterialLineEdit.NORMAL
+    property var iconSource: ""
     property var backgroundColor: JamiTheme.rgb256(240,240,240)
-    property var borderColor: {
-        if (!enabled) {
-            return "transparent"
-        }
+    property var borderColor: "#333"
+
+    signal imageClicked
+
+    onBorderColorModeChanged: {
+        if (!enabled)
+            borderColor = "transparent"
+        if (readOnly)
+            iconSource = ""
+
         switch(borderColorMode){
-        case InfoLineEdit.NORMAL:
-            return "#333"
-        case InfoLineEdit.RIGHT:
-            return "green"
-        case InfoLineEdit.ERROR:
-            return "red"
+        case MaterialLineEdit.SEARCHING:
+            iconSource = "qrc:/images/jami_rolling_spinner.gif"
+            borderColor = "#333"
+            break
+        case MaterialLineEdit.NORMAL:
+            iconSource = ""
+            borderColor = "#333"
+            break
+        case MaterialLineEdit.RIGHT:
+            iconSource = "qrc:/images/icons/round-check_circle-24px.svg"
+            borderColor = "green"
+            break
+        case MaterialLineEdit.ERROR:
+            iconSource = "qrc:/images/icons/round-error-24px.svg"
+            borderColor = "red"
+            break
         }
     }
 
-    signal imageClicked
-
     wrapMode: Text.Wrap
     readOnly: false
     selectByMouse: true
@@ -58,12 +78,17 @@ TextField {
     verticalAlignment: Text.AlignVCenter
 
     Image {
-        source: iconSource
-        width: 24
-        height: 24
+        id: lineEditImage
+
         anchors.verticalCenter: parent.verticalCenter
         anchors.right: parent.right
         anchors.rightMargin: 16
+
+        width: 24
+        height: 24
+
+        visible: borderColorMode !== MaterialLineEdit.SEARCHING
+        source: borderColorMode === MaterialLineEdit.SEARCHING ? "" : iconSource
         layer {
             enabled: true
             effect: ColorOverlay {
@@ -76,7 +101,7 @@ TextField {
             anchors.fill: parent
             hoverEnabled: true
             acceptedButtons: Qt.LeftButton
-            enabled: borderColorMode === InfoLineEdit.RIGHT
+            enabled: borderColorMode === MaterialLineEdit.RIGHT
 
             onReleased: {
                 imageClicked()
@@ -84,6 +109,21 @@ TextField {
         }
     }
 
+    AnimatedImage {
+        anchors.left: lineEditImage.left
+        anchors.verticalCenter: parent.verticalCenter
+
+        width: 24
+        height: 24
+
+        source: borderColorMode !== MaterialLineEdit.SEARCHING ? "" : iconSource
+        playing: true
+        paused: false
+        fillMode: Image.PreserveAspectFit
+        mipmap: true
+        visible: borderColorMode === MaterialLineEdit.SEARCHING
+    }
+
     background: Rectangle {
         anchors.fill: parent
         radius: 4
diff --git a/src/commoncomponents/SpinnerButton.qml b/src/commoncomponents/SpinnerButton.qml
new file mode 100644
index 000000000..44326d5a8
--- /dev/null
+++ b/src/commoncomponents/SpinnerButton.qml
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2020 by Savoir-faire Linux
+ * 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 <https://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.14
+import QtQuick.Controls 2.14
+import net.jami.Models 1.0
+
+MaterialButton {
+    id: root
+
+    property bool spinnerTriggered: false
+    property string spinnerTriggeredtext: value
+    property string normalText: value
+
+    animatedImageSource: spinnerTriggered ? "qrc:/images/jami_rolling_spinner.gif" : ""
+    text: spinnerTriggered ? spinnerTriggeredtext : normalText
+    color: !enabled ? JamiTheme.buttonTintedGreyInactive :
+                      JamiTheme.wizardBlueButtons
+
+    hoveredColor: JamiTheme.buttonTintedBlueHovered
+    pressedColor: JamiTheme.buttonTintedBluePressed
+}
diff --git a/src/settingsview/SettingsView.qml b/src/settingsview/SettingsView.qml
index d20929d5f..62cb2cb60 100644
--- a/src/settingsview/SettingsView.qml
+++ b/src/settingsview/SettingsView.qml
@@ -105,7 +105,6 @@ Rectangle {
 
         function onAccountListChanged(){
             slotAccountListChanged()
-            accountListChangedConnection.enabled = false
         }
     }
 
@@ -126,11 +125,10 @@ Rectangle {
 
     function slotAccountListChanged(){
         var accountList = ClientWrapper.accountModel.getAccountList()
-        if(accountList.length === 0) {
-            setSelected(SettingsView.Account)
-        } else {
-            currentAccountSettingsScrollWidget.disconnectAccountConnections()
-        }
+        if(accountList.length === 0)
+            return
+
+        currentAccountSettingsScrollWidget.disconnectAccountConnections()
         var device = ClientWrapper.avmodel.getDefaultDevice()
         if(device.length === 0){
             ClientWrapper.avmodel.setCurrentVideoCaptureDevice(device)
diff --git a/src/wizardview/WizardView.qml b/src/wizardview/WizardView.qml
index 6aea2ea93..7e0fd9aa7 100644
--- a/src/wizardview/WizardView.qml
+++ b/src/wizardview/WizardView.qml
@@ -48,6 +48,17 @@ Rectangle {
         SEARCHING
     }
 
+    enum WizardViewPageIndex {
+        WELCOMEPAGE = 0,
+        CREATEACCOUNTPAGE,
+        CREATESIPACCOUNTPAGE,
+        IMPORTFROMBACKUPPAGE,
+        BACKUPKEYSPAGE,
+        IMPORTFROMDEVICEPAGE,
+        CONNECTTOACCOUNTMANAGERPAGE,
+        PROFILEPAGE
+    }
+
     readonly property int layoutSpacing: 12
 
     property int textFontSize: 9
@@ -66,9 +77,10 @@ Rectangle {
     signal wizardViewIsClosed
 
     visible: true
+    color: JamiTheme.backgroundColor
 
     Component.onCompleted: {
-        changePageQML(controlPanelStackView.welcomePageStackId)
+        changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE)
     }
 
     Connections{
@@ -78,85 +90,77 @@ Rectangle {
             addedAccountIndex = index
             ClientWrapper.accountAdaptor.accountChanged(index)
             if (showProfile) {
-                changePageQML(controlPanelStackView.profilePageId)
-                profilePage.readyToSaveDetails = true
-            } else if (controlPanelStackView.currentIndex == controlPanelStackView.profilePageId) {
-                ClientWrapper.lrcInstance.accountListChanged()
-                profilePage.readyToSaveDetails = true
+                changePageQML(WizardView.WizardViewPageIndex.PROFILEPAGE)
+                profilePage.readyToSaveDetails()
+            } else if (controlPanelStackView.currentIndex === WizardView.WizardViewPageIndex.PROFILEPAGE) {
+                profilePage.readyToSaveDetails()
             } else if (showBackUp) {
-                changePageQML(controlPanelStackView.backupKeysPageId)
+                changePageQML(WizardView.WizardViewPageIndex.BACKUPKEYSPAGE)
             } else {
-                changePageQML(controlPanelStackView.welcomePageStackId)
+                changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE)
                 needToShowMainViewWindow(addedAccountIndex)
-                ClientWrapper.lrcInstance.accountListChanged()
             }
         }
 
         // reportFailure
         function onReportFailure() {
-            if (controlPanelStackView.currentIndex == controlPanelStackView.importFromDevicePageId) {
-                importFromDevicePage.errorText = qsTr("Error when creating your account. Check your credentials")
-            } else if (controlPanelStackView.currentIndex == controlPanelStackView.importFromBackupPageId) {
-                importFromBackupPage.errorText = qsTr("Error when creating your account. Check your credentials")
-            } else if (controlPanelStackView.currentIndex == controlPanelStackView.connectToAccountManagerPageId) {
-                connectToAccountManagerPage.errorText = qsTr("Error when creating your account. Check your credentials")
+            var errorMessage = qsTr("Error when creating your account. Check your credentials")
+
+            switch(controlPanelStackView.currentIndex) {
+            case WizardView.WizardViewPageIndex.IMPORTFROMDEVICEPAGE:
+                importFromDevicePage.errorOccured(errorMessage)
+                break
+            case WizardView.WizardViewPageIndex.IMPORTFROMBACKUPPAGE:
+                importFromBackupPage.errorOccured(errorMessage)
+                break
+            case WizardView.WizardViewPageIndex.CONNECTTOACCOUNTMANAGERPAGE:
+                connectToAccountManagerPage.errorOccured(errorMessage)
+                break
             }
         }
     }
 
     Connections {
         id: registeredNameFoundConnection
+
         target: ClientWrapper.nameDirectory
-        enabled: false
 
         function onRegisteredNameFound(status, address, name) {
-            slotRegisteredNameFound(status, address, name)
-        }
-    }
-
-    function slotRegisteredNameFound(status, address, name) {
-        if (name.length != 0 && name.length < 3) {
-            createAccountPage.nameRegistrationUIState = WizardView.INVALID
-        } else if (registeredName === name) {
-            switch (status) {
-            case NameDirectory.LookupStatus.NOT_FOUND:
-            case NameDirectory.LookupStatus.ERROR:
-                createAccountPage.nameRegistrationUIState = WizardView.FREE
-                break
-            case NameDirectory.LookupStatus.INVALID_NAME:
-            case NameDirectory.LookupStatus.INVALID:
-                createAccountPage.nameRegistrationUIState = WizardView.INVALID
-                break
-            case NameDirectory.LookupStatus.SUCCESS:
-                createAccountPage.nameRegistrationUIState = WizardView.TAKEN
-                break
+            if (registeredName === name) {
+                switch(status) {
+                case NameDirectory.LookupStatus.NOT_FOUND:
+                    createAccountPage.nameRegistrationUIState = WizardView.FREE
+                    break
+                case NameDirectory.LookupStatus.ERROR:
+                case NameDirectory.LookupStatus.INVALID_NAME:
+                case NameDirectory.LookupStatus.INVALID:
+                    createAccountPage.nameRegistrationUIState = WizardView.INVALID
+                    break
+                case NameDirectory.LookupStatus.SUCCESS:
+                    createAccountPage.nameRegistrationUIState = WizardView.TAKEN
+                    break
+                }
             }
         }
     }
 
     function changePageQML(pageIndex) {
         controlPanelStackView.currentIndex = pageIndex
-        if (pageIndex == controlPanelStackView.welcomePageStackId) {
+        if (pageIndex === WizardView.WizardViewPageIndex.WELCOMEPAGE) {
             fileToImport = ""
-            registeredNameFoundConnection.enabled = true
             createAccountPage.nameRegistrationUIState = WizardView.BLANK
-        } else if (pageIndex == controlPanelStackView.createAccountPageId) {
+        } else if (pageIndex === WizardView.WizardViewPageIndex.CREATEACCOUNTPAGE) {
             createAccountPage.initializeOnShowUp()
-            // connection between register name found and its slot
-            registeredNameFoundConnection.enabled = true
-        } else if (pageIndex == controlPanelStackView.createSIPAccountPageId) {
+        } else if (pageIndex === WizardView.WizardViewPageIndex.CREATESIPACCOUNTPAGE) {
             createSIPAccountPage.initializeOnShowUp()
-        } else if (pageIndex == controlPanelStackView.importFromDevicePageId) {
+        } else if (pageIndex === WizardView.WizardViewPageIndex.IMPORTFROMDEVICEPAGE) {
             importFromDevicePage.initializeOnShowUp()
-        } else if (pageIndex == controlPanelStackView.spinnerPageId) {
-            createAccountPage.nameRegistrationUIState = WizardView.BLANK
-            createAccountPage.isToSetPassword_checkState_choosePasswordCheckBox = false
-        } else if (pageIndex == controlPanelStackView.connectToAccountManagerPageId) {
+        } else if (pageIndex === WizardView.WizardViewPageIndex.CONNECTTOACCOUNTMANAGERPAGE) {
             connectToAccountManagerPage.initializeOnShowUp()
-        } else if (pageIndex == controlPanelStackView.importFromBackupPageId) {
+        } else if (pageIndex === WizardView.WizardViewPageIndex.IMPORTFROMBACKUPPAGE) {
             importFromBackupPage.clearAllTextFields()
             fileToImport = ""
-        } else if (pageIndex == controlPanelStackView.profilePageId) {
+        } else if (pageIndex === WizardView.WizardViewPageIndex.PROFILEPAGE) {
             profilePage.initializeOnShowUp()
             profilePage.showBottom = showBottom
         }
@@ -183,7 +187,6 @@ Rectangle {
                 if (success) {
                     console.log("Account Export Succeed")
                     needToShowMainViewWindow(addedAccountIndex)
-                    ClientWrapper.lrcInstance.accountListChanged()
                 }
             }
         }
@@ -199,20 +202,9 @@ Rectangle {
 
         anchors.fill: parent
 
-        currentIndex: welcomePageStackId
-
-        property int welcomePageStackId: 0
-        property int createAccountPageId: 1
-        property int createSIPAccountPageId: 2
-        property int importFromBackupPageId: 3
-        property int backupKeysPageId: 4
-        property int importFromDevicePageId: 5
-        property int connectToAccountManagerPageId: 6
-        property int spinnerPageId: 7
-        property int profilePageId: 8
+        currentIndex: WizardView.WizardViewPageIndex.WELCOMEPAGE
 
         WelcomePage {
-            // welcome page, index 0
             id: welcomePage
 
             onWelcomePageRedirectPage: {
@@ -225,7 +217,6 @@ Rectangle {
         }
 
         CreateAccountPage {
-            // create account page, index 1
             id: createAccountPage
 
             onCreateAccount: {
@@ -238,22 +229,19 @@ Rectangle {
                     true)
                 showBackUp = true
                 showBottom = true
-                changePageQML(controlPanelStackView.profilePageId)
+                changePageQML(WizardView.WizardViewPageIndex.PROFILEPAGE)
             }
 
-            onText_usernameEditAliasChanged: {
-                lookupTimer.restart()
-            }
+            onText_usernameEditAliasChanged: lookupTimer.restart()
 
             onLeavePage: {
-                changePageQML(controlPanelStackView.welcomePageStackId)
+                changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE)
             }
 
             Timer {
                 id: lookupTimer
 
                 repeat: false
-                triggeredOnStart: false
                 interval: 200
 
                 onTriggered: {
@@ -269,11 +257,10 @@ Rectangle {
         }
 
         CreateSIPAccountPage {
-            // create SIP account page, index 2
             id: createSIPAccountPage
 
             onLeavePage: {
-                changePageQML(controlPanelStackView.welcomePageStackId)
+                changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE)
             }
 
             onCreateAccount: {
@@ -287,24 +274,22 @@ Rectangle {
                 ClientWrapper.accountAdaptor.createSIPAccount(inputParaObject, "")
                 showBackUp = false
                 showBottom = false
-                changePageQML(controlPanelStackView.profilePageId)
-                controlPanelStackView.profilePage.readyToSaveDetails = true
+                changePageQML(WizardView.WizardViewPageIndex.PROFILEPAGE)
+                controlPanelStackView.profilePage.readyToSaveDetails()
             }
         }
 
         ImportFromBackupPage {
-            // import from backup page, index 3
             id: importFromBackupPage
 
             onLeavePage: {
-                changePageQML(controlPanelStackView.welcomePageStackId)
+                changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE)
             }
 
             onImportAccount: {
                 inputParaObject = {}
                 inputParaObject["archivePath"] = ClientWrapper.utilsAdaptor.getAbsPath(importFromBackupPage.filePath)
                 inputParaObject["password"] = importFromBackupPage.text_passwordFromBackupEditAlias
-                importFromBackupPage.clearAllTextFields()
                 showBackUp = false
                 showBottom = false
                 showProfile = true
@@ -314,7 +299,6 @@ Rectangle {
         }
 
         BackupKeyPage {
-            // backup keys page, index 4
             id: backupKeysPage
 
             onNeverShowAgainBoxClicked: {
@@ -337,24 +321,21 @@ Rectangle {
                     }
                 }
 
-                changePageQML(controlPanelStackView.welcomePageStackId)
+                changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE)
                 needToShowMainViewWindow(addedAccountIndex)
-                ClientWrapper.lrcInstance.accountListChanged()
             }
 
             onLeavePage: {
-                changePageQML(controlPanelStackView.welcomePageStackId)
+                changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE)
                 needToShowMainViewWindow(addedAccountIndex)
-                ClientWrapper.lrcInstance.accountListChanged()
             }
         }
 
         ImportFromDevicePage {
-            // import from device page, index 5
             id: importFromDevicePage
 
             onLeavePage: {
-                changePageQML(controlPanelStackView.welcomePageStackId)
+                changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE)
             }
 
             onImportAccount: {
@@ -371,7 +352,6 @@ Rectangle {
         }
 
         ConnectToAccountManagerPage {
-            // connect to account manager Page, index 6
             id: connectToAccountManagerPage
 
             onCreateAccount: {
@@ -386,26 +366,19 @@ Rectangle {
             }
 
             onLeavePage: {
-                changePageQML(controlPanelStackView.welcomePageStackId)
+                changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE)
             }
         }
 
-        SpinnerPage {
-            // spinner Page, index 7
-            id: spinnerPage
-        }
-
         ProfilePage {
-            // profile Page, index 8
             id: profilePage
 
             function leave() {
                 if (showBackUp)
-                    changePageQML(controlPanelStackView.backupKeysPageId)
+                    changePageQML(WizardView.WizardViewPageIndex.BACKUPKEYSPAGE)
                 else {
-                    changePageQML(controlPanelStackView.welcomePageStackId)
+                    changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE)
                     needToShowMainViewWindow(addedAccountIndex)
-                    ClientWrapper.lrcInstance.accountListChanged()
                 }
             }
 
@@ -420,6 +393,4 @@ Rectangle {
             }
         }
     }
-
-    color: JamiTheme.backgroundColor
 }
diff --git a/src/wizardview/components/ConnectToAccountManagerPage.qml b/src/wizardview/components/ConnectToAccountManagerPage.qml
index 7576b9322..afd988511 100644
--- a/src/wizardview/components/ConnectToAccountManagerPage.qml
+++ b/src/wizardview/components/ConnectToAccountManagerPage.qml
@@ -31,21 +31,32 @@ Rectangle {
     property alias text_accountManagerEditAlias: accountManagerEdit.text
     property string errorText: ""
 
+    signal leavePage
+    signal createAccount
+
     function initializeOnShowUp() {
         clearAllTextFields()
     }
 
     function clearAllTextFields() {
+        connectBtn.spinnerTriggered = false
         usernameManagerEdit.clear()
         passwordManagerEdit.clear()
         accountManagerEdit.clear()
         errorText = ""
     }
 
+    function errorOccured(errorMessage) {
+        connectBtn.spinnerTriggered = false
+        errorText = errorMessage
+    }
+
     color: JamiTheme.backgroundColor
 
-    signal leavePage
-    signal createAccount
+    onVisibleChanged: {
+        if (visible)
+            accountManagerEdit.focus = true
+    }
 
     ColumnLayout {
         spacing: layoutSpacing
@@ -92,6 +103,8 @@ Rectangle {
             font.kerning: true
 
             borderColorMode: MaterialLineEdit.NORMAL
+
+            onTextChanged: errorText = ""
         }
 
         Label {
@@ -114,6 +127,8 @@ Rectangle {
             font.kerning: true
 
             borderColorMode: MaterialLineEdit.NORMAL
+
+            onTextChanged: errorText = ""
         }
 
         MaterialLineEdit {
@@ -129,27 +144,28 @@ Rectangle {
             font.kerning: true
 
             echoMode: TextInput.Password
-
             borderColorMode: MaterialLineEdit.NORMAL
+
+            onTextChanged: errorText = ""
         }
 
-        MaterialButton {
+        SpinnerButton {
             id: connectBtn
 
             Layout.alignment: Qt.AlignCenter
             Layout.preferredWidth: preferredWidth
             Layout.preferredHeight: preferredHeight
 
-            text: qsTr("CONNECT")
+            spinnerTriggeredtext: qsTr("Generating account…")
+            normalText: qsTr("CONNECT")
+
             enabled: accountManagerEdit.text.length !== 0
-                && usernameManagerEdit.text.length !== 0
-                && passwordManagerEdit.text.length !== 0
-            color: enabled? JamiTheme.wizardBlueButtons : JamiTheme.buttonTintedGreyInactive
-            hoveredColor: JamiTheme.buttonTintedBlueHovered
-            pressedColor: JamiTheme.buttonTintedBluePressed
+                     && usernameManagerEdit.text.length !== 0
+                     && passwordManagerEdit.text.length !== 0
+                     && !spinnerTriggered
 
             onClicked: {
-                errorText = ""
+                spinnerTriggered = true
                 createAccount()
             }
         }
@@ -163,21 +179,26 @@ Rectangle {
             font.pointSize: JamiTheme.textFontSize
             color: "red"
         }
+    }
 
-        MaterialButton {
-            id: backButton
+    HoverableButton {
+        id: backButton
 
-            Layout.alignment: Qt.AlignCenter
-            Layout.preferredWidth: preferredWidth
-            Layout.preferredHeight: preferredHeight
+        anchors.left: parent.left
+        anchors.top: parent.top
+        anchors.margins: 20
 
-            text: qsTr("BACK")
-            color: JamiTheme.buttonTintedGrey
-            hoveredColor: JamiTheme.buttonTintedGreyHovered
-            pressedColor: JamiTheme.buttonTintedGreyPressed
-            outlined: true
+        width: 35
+        height: 35
 
-            onClicked: leavePage()
-        }
+        radius: 30
+
+        backgroundColor: root.color
+        onExitColor: root.color
+
+        source: "qrc:/images/icons/ic_arrow_back_24px.svg"
+        toolTipText: qsTr("Back to welcome page")
+
+        onClicked: leavePage()
     }
 }
diff --git a/src/wizardview/components/CreateAccountPage.qml b/src/wizardview/components/CreateAccountPage.qml
index 8e694da49..39ced2f30 100644
--- a/src/wizardview/components/CreateAccountPage.qml
+++ b/src/wizardview/components/CreateAccountPage.qml
@@ -57,6 +57,11 @@ Rectangle {
         onActivated: leavePage()
     }
 
+    onVisibleChanged: {
+        if (visible && createAccountStack.currentIndex === 0)
+            usernameEdit.focus = true
+    }
+
     // JamiFileDialog for exporting account
     JamiFileDialog {
         id: exportBtn_Dialog
@@ -127,7 +132,7 @@ Rectangle {
 
                 Layout.topMargin: 15
                 Layout.preferredHeight: fieldLayoutHeight
-                Layout.preferredWidth: fieldLayoutWidth
+                Layout.preferredWidth:  chooseUsernameButton.width
                 Layout.alignment: Qt.AlignHCenter
 
                 selectByMouse: true
@@ -136,14 +141,18 @@ Rectangle {
                 font.kerning: true
 
                 borderColorMode: {
-                    if (nameRegistrationUIState === WizardView.BLANK)
+                    switch (nameRegistrationUIState){
+                    case WizardView.BLANK:
                         return MaterialLineEdit.NORMAL
-                    else
-                        return nameRegistrationUIState >= WizardView.FREE ?
-                                    MaterialLineEdit.NORMAL : MaterialLineEdit.ERROR
+                    case WizardView.INVALID:
+                    case WizardView.TAKEN:
+                        return MaterialLineEdit.ERROR
+                    case WizardView.FREE:
+                        return MaterialLineEdit.RIGHT
+                    case WizardView.SEARCHING:
+                        return MaterialLineEdit.SEARCHING
+                    }
                 }
-
-                fieldLayoutWidth: chooseUsernameButton.width
             }
 
             Label {
@@ -175,11 +184,11 @@ Rectangle {
                 Layout.preferredHeight: preferredHeight
 
                 text: qsTr("CHOOSE USERNAME")
-                color: nameRegistrationUIState === WizardView.FREE?
-                        JamiTheme.buttonTintedGrey
-                        : JamiTheme.buttonTintedGreyInactive
-                hoveredColor: JamiTheme.buttonTintedGreyHovered
-                pressedColor: JamiTheme.buttonTintedGreyPressed
+                enabled: nameRegistrationUIState === WizardView.FREE
+                color: nameRegistrationUIState === WizardView.FREE ? JamiTheme.wizardBlueButtons :
+                                                                     JamiTheme.buttonTintedGreyInactive
+                hoveredColor: JamiTheme.buttonTintedBlueHovered
+                pressedColor: JamiTheme.buttonTintedBluePressed
 
                 onClicked: {
                     if (nameRegistrationUIState === WizardView.FREE)
@@ -187,38 +196,21 @@ Rectangle {
                 }
             }
 
-            Row {
-                id: skipAndBackButtonsRow
+            MaterialButton {
+                id: skipButton
 
                 Layout.alignment: Qt.AlignCenter
-                Layout.preferredWidth: chooseUsernameButton.preferredWidth
-                Layout.preferredHeight: chooseUsernameButton.preferredHeight
+                Layout.preferredWidth: preferredWidth
+                Layout.preferredHeight: preferredHeight
 
-                spacing: layoutSpacing
+                text: qsTr("SKIP")
+                color: JamiTheme.buttonTintedGrey
+                hoveredColor: JamiTheme.buttonTintedGreyHovered
+                pressedColor: JamiTheme.buttonTintedGreyPressed
+                outlined: true
 
-                Repeater {
-                    model: 2
-
-                    MaterialButton {
-                        width: (skipAndBackButtonsRow.width -
-                                skipAndBackButtonsRow.spacing) / 2
-                        height: skipAndBackButtonsRow.height
-
-                        text: modelData === 0 ? qsTr("BACK") : qsTr("SKIP")
-                        color: JamiTheme.buttonTintedGrey
-                        hoveredColor: JamiTheme.buttonTintedGreyHovered
-                        pressedColor: JamiTheme.buttonTintedGreyPressed
-                        outlined: true
-
-                        onClicked: {
-                            if (modelData === 0)
-                                leavePage()
-                            else
-                                createAccountStack.currentIndex =
-                                        createAccountStack.currentIndex + 1
-                        }
-                    }
-                }
+                onClicked: createAccountStack.currentIndex =
+                           createAccountStack.currentIndex + 1
             }
         }
 
@@ -328,22 +320,32 @@ Rectangle {
                     createAccountStack.currentIndex += 1
                 }
             }
+        }
+    }
 
-            MaterialButton {
-                id: backButton
+    HoverableButton {
+        id: backButton
 
-                Layout.alignment: Qt.AlignCenter
-                Layout.preferredWidth: preferredWidth
-                Layout.preferredHeight: preferredHeight
+        anchors.left: parent.left
+        anchors.top: parent.top
+        anchors.margins: 20
 
-                text: qsTr("BACK")
-                color: JamiTheme.buttonTintedGrey
-                hoveredColor: JamiTheme.buttonTintedGreyHovered
-                pressedColor: JamiTheme.buttonTintedGreyPressed
-                outlined: true
+        width: 35
+        height: 35
 
-                onClicked: createAccountStack.currentIndex -= 1
-            }
+        radius: 30
+
+        backgroundColor: root.color
+        onExitColor: root.color
+
+        source: "qrc:/images/icons/ic_arrow_back_24px.svg"
+        toolTipText: qsTr("Back")
+
+        onClicked: {
+            if (createAccountStack.currentIndex == 0)
+                leavePage()
+            else
+                createAccountStack.currentIndex -= 1
         }
     }
 
diff --git a/src/wizardview/components/CreateSIPAccountPage.qml b/src/wizardview/components/CreateSIPAccountPage.qml
index d0f02390a..899289bf2 100644
--- a/src/wizardview/components/CreateSIPAccountPage.qml
+++ b/src/wizardview/components/CreateSIPAccountPage.qml
@@ -33,6 +33,9 @@ Rectangle {
 
     property var boothImgBase64: null
 
+    signal createAccount
+    signal leavePage
+
     function initializeOnShowUp() {
         clearAllTextFields()
     }
@@ -45,11 +48,13 @@ Rectangle {
         sipUsernameEdit.clear()
     }
 
-    signal createAccount
-    signal leavePage
-
     color: JamiTheme.backgroundColor
 
+    onVisibleChanged: {
+        if (visible)
+            sipServernameEdit.focus = true
+    }
+
     ColumnLayout {
         spacing: layoutSpacing
 
@@ -150,21 +155,26 @@ Rectangle {
                 createAccount()
             }
         }
+    }
 
-        MaterialButton {
-            id: backButton
+    HoverableButton {
+        id: backButton
 
-            Layout.alignment: Qt.AlignCenter
-            Layout.preferredWidth: createAccountButton.width / 2
-            Layout.preferredHeight: preferredHeight
+        anchors.left: parent.left
+        anchors.top: parent.top
+        anchors.margins: 20
 
-            text: qsTr("BACK")
-            color: JamiTheme.buttonTintedGrey
-            hoveredColor: JamiTheme.buttonTintedGreyHovered
-            pressedColor: JamiTheme.buttonTintedGreyPressed
-            outlined: true
+        width: 35
+        height: 35
 
-            onClicked: leavePage()
-        }
+        radius: 30
+
+        backgroundColor: root.color
+        onExitColor: root.color
+
+        source: "qrc:/images/icons/ic_arrow_back_24px.svg"
+        toolTipText: qsTr("Back to welcome page")
+
+        onClicked: leavePage()
     }
 }
diff --git a/src/wizardview/components/ImportFromBackupPage.qml b/src/wizardview/components/ImportFromBackupPage.qml
index 98f582708..9d0907384 100644
--- a/src/wizardview/components/ImportFromBackupPage.qml
+++ b/src/wizardview/components/ImportFromBackupPage.qml
@@ -34,12 +34,23 @@ Rectangle {
     property string filePath: ""
     property string errorText: ""
 
+    signal leavePage
+    signal importAccount
+
     function clearAllTextFields() {
+        connectBtn.spinnerTriggered = false
         passwordFromBackupEdit.clear()
         errorText = ""
         fileImportBtnText = qsTr("Archive(none)")
     }
 
+    function errorOccured(errorMessage) {
+        errorText = errorMessage
+        connectBtn.spinnerTriggered = false
+    }
+
+    color: JamiTheme.backgroundColor
+
     JamiFileDialog {
         id: importFromFile_Dialog
 
@@ -59,11 +70,6 @@ Rectangle {
         }
     }
 
-    color: JamiTheme.backgroundColor
-
-    signal leavePage
-    signal importAccount
-
     ColumnLayout {
         spacing: layoutSpacing
 
@@ -91,7 +97,10 @@ Rectangle {
             hoveredColor: JamiTheme.buttonTintedGreyHovered
             pressedColor: JamiTheme.buttonTintedGreyPressed
 
-            onClicked: importFromFile_Dialog.open()
+            onClicked: {
+                errorText = ""
+                importFromFile_Dialog.open()
+            }
         }
 
         Text {
@@ -128,26 +137,31 @@ Rectangle {
             font.kerning: true
 
             echoMode: TextInput.Password
-
             borderColorMode: MaterialLineEdit.NORMAL
+
+            onTextChanged: errorText = ""
         }
 
-        MaterialButton {
+        SpinnerButton {
             id: connectBtn
 
             Layout.alignment: Qt.AlignCenter
             Layout.preferredWidth: preferredWidth
             Layout.preferredHeight: preferredHeight
 
-            text: qsTr("CONNECT FROM BACKUP")
-            color: filePath.length === 0 ?
-                JamiTheme.buttonTintedGreyInactive : JamiTheme.buttonTintedGrey
-            enabled: !(filePath.length === 0)
-            hoveredColor: JamiTheme.buttonTintedGreyHovered
-            pressedColor: JamiTheme.buttonTintedGreyPressed
+            spinnerTriggeredtext: qsTr("Generating account…")
+            normalText: qsTr("CONNECT FROM BACKUP")
+
+            enabled: {
+                if (spinnerTriggered)
+                    return false
+                if (!(filePath.length === 0) && errorText.length === 0)
+                    return true
+                return false
+            }
 
             onClicked: {
-                errorText = ""
+                spinnerTriggered = true
                 importAccount()
             }
         }
@@ -161,21 +175,26 @@ Rectangle {
             font.pointSize: JamiTheme.textFontSize
             color: "red"
         }
+    }
 
-        MaterialButton {
-            id: backButton
+    HoverableButton {
+        id: backButton
 
-            Layout.alignment: Qt.AlignCenter
-            Layout.preferredWidth: connectBtn.width / 2
-            Layout.preferredHeight: preferredHeight
+        anchors.left: parent.left
+        anchors.top: parent.top
+        anchors.margins: 20
 
-            text: qsTr("BACK")
-            color: JamiTheme.buttonTintedGrey
-            hoveredColor: JamiTheme.buttonTintedGreyHovered
-            pressedColor: JamiTheme.buttonTintedGreyPressed
-            outlined: true
+        width: 35
+        height: 35
 
-            onClicked: leavePage()
-        }
+        radius: 30
+
+        backgroundColor: root.color
+        onExitColor: root.color
+
+        source: "qrc:/images/icons/ic_arrow_back_24px.svg"
+        toolTipText: qsTr("Back to welcome page")
+
+        onClicked: leavePage()
     }
 }
diff --git a/src/wizardview/components/ImportFromDevicePage.qml b/src/wizardview/components/ImportFromDevicePage.qml
index d4d786e66..f3edcc3ce 100644
--- a/src/wizardview/components/ImportFromDevicePage.qml
+++ b/src/wizardview/components/ImportFromDevicePage.qml
@@ -30,19 +30,30 @@ Rectangle {
     property alias text_passwordFromDeviceAlias: passwordFromDevice.text
     property string errorText: ""
 
+    signal leavePage
+    signal importAccount
+
     function initializeOnShowUp() {
         clearAllTextFields()
     }
 
     function clearAllTextFields() {
+        connectBtn.spinnerTriggered = false
         pinFromDevice.clear()
         passwordFromDevice.clear()
     }
 
+    function errorOccured(errorMessage) {
+        errorText = errorMessage
+        connectBtn.spinnerTriggered = false
+    }
+
     color: JamiTheme.backgroundColor
 
-    signal leavePage
-    signal importAccount
+    onVisibleChanged: {
+        if (visible)
+            pinFromDevice.focus = true
+    }
 
     ColumnLayout {
         spacing: layoutSpacing
@@ -71,8 +82,9 @@ Rectangle {
             font.kerning: true
 
             echoMode: TextInput.Password
-
             borderColorMode: MaterialLineEdit.NORMAL
+
+            onTextChanged: errorText = ""
         }
 
         Text {
@@ -83,7 +95,7 @@ Rectangle {
             Layout.preferredHeight: preferredHeight
 
             text: qsTr("Enter the PIN from another configured Jami account. " +
-                       "Use the \"export Jami account\" feature to obtain a PIN")
+                       "Use the \"Link Another Device\" feature to obtain a PIN")
             wrapMode: Text.Wrap
 
             onTextChanged: {
@@ -106,23 +118,24 @@ Rectangle {
             font.kerning: true
 
             borderColorMode: MaterialLineEdit.NORMAL
+
+            onTextChanged: errorText = ""
         }
 
-        MaterialButton {
+        SpinnerButton {
             id: connectBtn
 
             Layout.alignment: Qt.AlignCenter
             Layout.preferredWidth: preferredWidth
             Layout.preferredHeight: preferredHeight
 
-            text: qsTr("CONNECT FROM ANOTHER DEVICE")
-            color: pinFromDevice.text.length === 0?
-                JamiTheme.buttonTintedGreyInactive : JamiTheme.buttonTintedGrey
-            hoveredColor: JamiTheme.buttonTintedGreyHovered
-            pressedColor: JamiTheme.buttonTintedGreyPressed
+            spinnerTriggeredtext: qsTr("Generating account…")
+            normalText: qsTr("CONNECT FROM ANOTHER DEVICE")
+
+            enabled: pinFromDevice.text.length !== 0 && !spinnerTriggered
 
             onClicked: {
-                errorText = ""
+                spinnerTriggered = true
                 importAccount()
             }
         }
@@ -137,21 +150,26 @@ Rectangle {
             font.pointSize: JamiTheme.textFontSize
             color: "red"
         }
+    }
 
-        MaterialButton {
-            id: backButton
+    HoverableButton {
+        id: backButton
 
-            Layout.alignment: Qt.AlignCenter
-            Layout.preferredWidth: connectBtn.width / 2
-            Layout.preferredHeight: preferredHeight
+        anchors.left: parent.left
+        anchors.top: parent.top
+        anchors.margins: 20
 
-            text: qsTr("BACK")
-            color: JamiTheme.buttonTintedGrey
-            hoveredColor: JamiTheme.buttonTintedGreyHovered
-            pressedColor: JamiTheme.buttonTintedGreyPressed
-            outlined: true
+        width: 35
+        height: 35
 
-            onClicked: leavePage()
-        }
+        radius: 30
+
+        backgroundColor: root.color
+        onExitColor: root.color
+
+        source: "qrc:/images/icons/ic_arrow_back_24px.svg"
+        toolTipText: qsTr("Back to welcome page")
+
+        onClicked: leavePage()
     }
 }
diff --git a/src/wizardview/components/ProfilePage.qml b/src/wizardview/components/ProfilePage.qml
index f1e64dda0..557d08242 100644
--- a/src/wizardview/components/ProfilePage.qml
+++ b/src/wizardview/components/ProfilePage.qml
@@ -29,19 +29,22 @@ Rectangle {
     function initializeOnShowUp() {
         clearAllTextFields()
         boothImgBase64 = ""
-        readyToSaveDetails = false
+        saveProfileBtn.spinnerTriggered = true
     }
 
     function clearAllTextFields() {
         aliasEdit.clear()
     }
 
+    function readyToSaveDetails() {
+        saveProfileBtn.spinnerTriggered = false
+    }
+
     color: JamiTheme.backgroundColor
 
     signal leavePage
     signal saveProfile
 
-    property var readyToSaveDetails: false
     property var showBottom: false
     property alias boothImgBase64: setAvatarWidget.imgBase64
     property alias displayName: aliasEdit.text
@@ -106,22 +109,18 @@ Rectangle {
             fieldLayoutWidth: saveProfileBtn.width
         }
 
-        MaterialButton {
+        SpinnerButton {
             id: saveProfileBtn
 
             Layout.alignment: Qt.AlignCenter
             Layout.preferredWidth: preferredWidth
             Layout.preferredHeight: preferredHeight
 
-            enabled: readyToSaveDetails
-            text: enabled? qsTr("Save Profile") : qsTr("Generating account…")
-            color: enabled? JamiTheme.wizardBlueButtons : JamiTheme.buttonTintedGreyInactive
-            hoveredColor: JamiTheme.buttonTintedBlueHovered
-            pressedColor: JamiTheme.buttonTintedBluePressed
+            enabled: !spinnerTriggered
+            normalText: qsTr("Save Profile")
+            spinnerTriggeredtext: qsTr("Generating account…")
 
-            onClicked: {
-                saveProfile()
-            }
+            onClicked: saveProfile()
         }
 
         MaterialButton {
diff --git a/src/wizardview/components/SpinnerPage.qml b/src/wizardview/components/SpinnerPage.qml
deleted file mode 100644
index 2fb3f8d09..000000000
--- a/src/wizardview/components/SpinnerPage.qml
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 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 <https://www.gnu.org/licenses/>.
- */
-
-import QtQuick 2.14
-import QtQuick.Layouts 1.3
-import QtQuick.Controls 2.14
-
-import "../../constant"
-
-ColumnLayout {
-    Layout.fillWidth: true
-    Layout.fillHeight: true
-    spacing: 6
-
-    property bool successState: true
-    property string progressLabelEditText: "Generating your Jami account"
-
-    Item {
-        Layout.alignment: Qt.AlignHCenter
-        Layout.preferredHeight: 40
-        Layout.fillWidth: true
-        Layout.fillHeight: true
-    }
-    Label {
-        id: spinnerLabel
-        Layout.alignment: Qt.AlignHCenter
-        Layout.minimumWidth: 200
-        Layout.minimumHeight: 200
-
-        Layout.maximumWidth: 16777215
-        Layout.maximumHeight: 16777215
-
-        property string spinnerDisplyState: successState ? "spinnerLabel_Regular" : "spinnerLabel_Failure"
-        onSpinnerDisplyStateChanged: {
-            switch (spinnerDisplyState) {
-            case "spinnerLabel_Regular":
-                background = Qt.createQmlObject("import QtQuick 2.14;
-AnimatedImage {
-source: \"qrc:/images/jami_eclipse_spinner.gif\"
-
-playing: true
-paused: false
-fillMode: Image.PreserveAspectFit
-mipmap: true
-}", spinnerLabel)
-                break
-            case "spinnerLabel_Failure":
-                background = Qt.createQmlObject("import QtQuick 2.14;
-import \"qrc:/src/constant/\";
-Image {
-anchors.fill: parent;
-source:\"image://tintedPixmap/\" + (\"qrc:/images/icons/baseline-error_outline-24px.svg\").replace(\"qrc:/images/icons/\", \"\") + \"+\" + JamiTheme.urgentOrange_;
-mipmap: true;}", spinnerLabel)
-                break
-            }
-        }
-    }
-    Item {
-        Layout.alignment: Qt.AlignHCenter
-        Layout.preferredHeight: 40
-        Layout.fillWidth: true
-        Layout.fillHeight: true
-    }
-    Label {
-        id: progressLabel
-        Layout.alignment: Qt.AlignHCenter
-        text: successState ? progressLabelEditText : "Error creating account"
-        font.pointSize: 11
-        font.kerning: true
-
-        property string progressLabelState: successState ? "color_success" : "color_fail"
-        onProgressLabelStateChanged: {
-            switch (progressLabelState) {
-            case "color_success":
-                background = Qt.createQmlObject(
-                            "import QtQuick 2.14; Rectangle { anchors.fill: parent; color: \"transparent\"; }",
-                            progressLabel)
-                break
-            case "color_fail":
-                background = Qt.createQmlObject(
-                            "import QtQuick 2.14; Rectangle { anchors.fill: parent; color: \"red\"; }",
-                            progressLabel)
-                break
-            }
-        }
-    }
-    Item {
-        Layout.alignment: Qt.AlignHCenter
-        Layout.minimumHeight: 20
-        Layout.maximumHeight: 20
-        Layout.preferredHeight: 20
-        Layout.fillWidth: true
-        Layout.fillHeight: false
-    }
-}
diff --git a/src/wizardview/components/WelcomePage.qml b/src/wizardview/components/WelcomePage.qml
index f1ea2787f..c15d66f97 100644
--- a/src/wizardview/components/WelcomePage.qml
+++ b/src/wizardview/components/WelcomePage.qml
@@ -37,6 +37,8 @@ Rectangle {
     ColumnLayout {
         anchors.centerIn: parent
 
+        spacing: layoutSpacing
+
         Text {
             id: welcomeLabel
 
@@ -71,11 +73,11 @@ Rectangle {
             id: newAccountButton
 
             Layout.alignment: Qt.AlignCenter
-            Layout.topMargin: 8
             Layout.preferredWidth: preferredWidth
             Layout.preferredHeight: preferredHeight
 
-            text: qsTr("CREATE A JAMI ACCOUNT")
+            text: qsTr("Create a jami account")
+            fontCapitalization: Font.AllUppercase
             toolTipText: qsTr("Create new Jami account")
             source: "qrc:/images/default_avatar_overlay.svg"
             color: JamiTheme.buttonTintedBlue
@@ -91,11 +93,11 @@ Rectangle {
             id: fromDeviceButton
 
             Layout.alignment: Qt.AlignCenter
-            Layout.topMargin: 8
             Layout.preferredWidth: preferredWidth
             Layout.preferredHeight: preferredHeight
 
-            text: qsTr("IMPORT FROM ANOTHER DEVICE")
+            text: qsTr("Import from another device")
+            fontCapitalization: Font.AllUppercase
             toolTipText: qsTr("Import account from other device")
             source: "qrc:/images/icons/devices-24px.svg"
             color: JamiTheme.buttonTintedBlue
@@ -111,11 +113,11 @@ Rectangle {
             id: fromBackupButton
 
             Layout.alignment: Qt.AlignCenter
-            Layout.topMargin: 8
             Layout.preferredWidth: preferredWidth
             Layout.preferredHeight: preferredHeight
 
-            text: qsTr("CONNECT FROM BACKUP")
+            text: qsTr("Connect from backup")
+            fontCapitalization: Font.AllUppercase
             toolTipText: qsTr("Import account from backup file")
             source: "qrc:/images/icons/backup-24px.svg"
             color: JamiTheme.buttonTintedBlue
@@ -131,11 +133,11 @@ Rectangle {
             id: showAdvancedButton
 
             Layout.alignment: Qt.AlignCenter
-            Layout.topMargin: 8
             Layout.preferredWidth: preferredWidth
             Layout.preferredHeight: preferredHeight
 
-            text: qsTr("SHOW ADVANCED")
+            text: qsTr("Show advanced")
+            fontCapitalization: Font.AllUppercase
             toolTipText: qsTr("Show advanced options")
             color: JamiTheme.buttonTintedBlue
             hoveredColor: JamiTheme.buttonTintedBlueHovered
@@ -158,13 +160,13 @@ Rectangle {
             id: connectAccountManagerButton
 
             Layout.alignment: Qt.AlignCenter
-            Layout.topMargin: 8
             Layout.preferredWidth: preferredWidth
             Layout.preferredHeight: preferredHeight
 
             visible: false
 
-            text: qsTr("CONNECT TO MANAGEMENT SERVER")
+            text: qsTr("Connect to management server")
+            fontCapitalization: Font.AllUppercase
             toolTipText: qsTr("Login to account manager")
             source: "qrc:/images/icons/router-24px.svg"
             color: JamiTheme.buttonTintedBlue
@@ -180,13 +182,13 @@ Rectangle {
             id: newSIPAccountButton
 
             Layout.alignment: Qt.AlignCenter
-            Layout.topMargin: 8
             Layout.preferredWidth: preferredWidth
             Layout.preferredHeight: preferredHeight
 
             visible: false
 
-            text: qsTr("CREATE A SIP ACCOUNT")
+            text: qsTr("Create a sip account")
+            fontCapitalization: Font.AllUppercase
             toolTipText: qsTr("Create new SIP account")
             source: "qrc:/images/default_avatar_overlay.svg"
             color: JamiTheme.buttonTintedBlue
@@ -198,4 +200,34 @@ Rectangle {
             }
         }
     }
+
+    HoverableButton {
+        id: backButton
+
+        anchors.left: parent.left
+        anchors.top: parent.top
+        anchors.margins: 20
+
+        Connections {
+            target: ClientWrapper.lrcInstance
+
+            function onAccountListChanged() {
+                backButton.visible = ClientWrapper.utilsAdaptor.getAccountListSize()
+            }
+        }
+
+        width: 35
+        height: 35
+
+        visible: ClientWrapper.utilsAdaptor.getAccountListSize()
+        radius: 30
+
+        backgroundColor: root.color
+        onExitColor: root.color
+
+        source: "qrc:/images/icons/ic_arrow_back_24px.svg"
+        toolTipText: qsTr("Back")
+
+        onClicked: leavePage()
+    }
 }
-- 
GitLab