From 47fd631d182a611be555d0991696b63e96175129 Mon Sep 17 00:00:00 2001
From: Ming Rui Zhang <mingrui.zhang@savoirfairelinux.com>
Date: Thu, 17 Sep 2020 16:09:06 -0400
Subject: [PATCH] wizardView: add scroll view in every page

Also fix the view layout that is affected by client string update

Gitlab: #85
Change-Id: I0f34496325ebe15cc651204130a3a89e12b37d14
---
 src/wizardview/WizardView.qml                 | 318 ++++++++-------
 src/wizardview/components/BackupKeyPage.qml   |   6 +
 .../ConnectToAccountManagerPage.qml           |  16 +-
 .../components/CreateAccountPage.qml          | 370 ++++++++++--------
 .../components/CreateSIPAccountPage.qml       |   5 +
 .../components/ImportFromBackupPage.qml       |   8 +
 .../components/ImportFromDevicePage.qml       |   8 +
 src/wizardview/components/ProfilePage.qml     |  21 +-
 src/wizardview/components/WelcomePage.qml     |  12 +-
 9 files changed, 452 insertions(+), 312 deletions(-)

diff --git a/src/wizardview/WizardView.qml b/src/wizardview/WizardView.qml
index 7d3cf5cd7..5ac0298b9 100644
--- a/src/wizardview/WizardView.qml
+++ b/src/wizardview/WizardView.qml
@@ -53,6 +53,7 @@ Rectangle {
     }
 
     readonly property int layoutSpacing: 12
+    readonly property int backButtonMargins: 20
 
     property int textFontSize: 9
     property int wizardMode: WizardView.CREATE
@@ -123,7 +124,7 @@ Rectangle {
             isRdv = false
             createAccountPage.nameRegistrationUIState = UsernameLineEdit.NameRegistrationState.BLANK
         } else if (pageIndex === WizardView.WizardViewPageIndex.CREATEACCOUNTPAGE) {
-            createAccountPage.initializeOnShowUp()
+            createAccountPage.initializeOnShowUp(false)
         } else if (pageIndex === WizardView.WizardViewPageIndex.CREATESIPACCOUNTPAGE) {
             createSIPAccountPage.initializeOnShowUp()
         } else if (pageIndex === WizardView.WizardViewPageIndex.IMPORTFROMDEVICEPAGE) {
@@ -169,181 +170,230 @@ Rectangle {
         onClicked: forceActiveFocus()
     }
 
-    StackLayout {
-        id: controlPanelStackView
+    ScrollView {
+        id: wizardViewScrollView
+
+        property ScrollBar vScrollBar: ScrollBar.vertical
 
         anchors.fill: parent
 
-        currentIndex: WizardView.WizardViewPageIndex.WELCOMEPAGE
+        ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
+        ScrollBar.vertical.policy: ScrollBar.AsNeeded
 
-        WelcomePage {
-            id: welcomePage
+        clip: true
+        contentHeight: controlPanelStackView.height
 
-            onWelcomePageRedirectPage: {
-                changePageQML(toPageIndex)
-            }
+        StackLayout {
+            id: controlPanelStackView
 
-            onLeavePage: {
-                wizardViewIsClosed()
-            }
-        }
+            anchors.centerIn: parent
 
-        CreateAccountPage {
-            id: createAccountPage
-
-            onCreateAccount: {
-                inputParaObject = {}
-                inputParaObject["isRendezVous"] = isRdv
-                inputParaObject["password"] = text_passwordEditAlias
-                AccountAdapter.createJamiAccount(
-                    createAccountPage.text_usernameEditAlias,
-                    inputParaObject,
-                    createAccountPage.boothImgBase64,
-                    true)
-                showBackUp = !isRdv
-                showBottom = true
-                changePageQML(WizardView.WizardViewPageIndex.PROFILEPAGE)
-            }
+            width: wizardViewScrollView.width
 
-            onLeavePage: {
-                changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE)
+            currentIndex: WizardView.WizardViewPageIndex.WELCOMEPAGE
+
+            Component.onCompleted: {
+                // avoid binding loop
+                height = Qt.binding(function (){
+                    var index = currentIndex
+                            === WizardView.WizardViewPageIndex.CREATERENDEZVOUS ?
+                                WizardView.WizardViewPageIndex.CREATEACCOUNTPAGE : currentIndex
+                    return Math.max(
+                                controlPanelStackView.itemAt(index).preferredHeight,
+                                wizardViewScrollView.height)
+                })
             }
-        }
 
-        CreateSIPAccountPage {
-            id: createSIPAccountPage
+            WelcomePage {
+                id: welcomePage
 
-            onLeavePage: {
-                changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE)
-            }
+                Layout.alignment: Qt.AlignCenter
 
-            onCreateAccount: {
-                inputParaObject = {}
-                inputParaObject["hostname"] = createSIPAccountPage.text_sipServernameEditAlias
-                inputParaObject["username"] = createSIPAccountPage.text_sipUsernameEditAlias
-                inputParaObject["password"] = createSIPAccountPage.text_sipPasswordEditAlias
-                inputParaObject["proxy"] = createSIPAccountPage.text_sipProxyEditAlias
-                createSIPAccountPage.clearAllTextFields()
-
-                AccountAdapter.createSIPAccount(inputParaObject, "")
-                showBackUp = false
-                showBottom = false
-                changePageQML(WizardView.WizardViewPageIndex.PROFILEPAGE)
-                controlPanelStackView.profilePage.readyToSaveDetails()
+                onWelcomePageRedirectPage: {
+                    changePageQML(toPageIndex)
+                }
+
+                onLeavePage: {
+                    wizardViewIsClosed()
+                }
+
+                onScrollToBottom: {
+                    if (welcomePage.preferredHeight > root.height)
+                        wizardViewScrollView.vScrollBar.position = 1
+                }
             }
-        }
 
-        ImportFromBackupPage {
-            id: importFromBackupPage
+            CreateAccountPage {
+                id: createAccountPage
+
+                Layout.alignment: Qt.AlignCenter
+
+                onCreateAccount: {
+                    inputParaObject = {}
+                    inputParaObject["isRendezVous"] = isRdv
+                    inputParaObject["password"] = text_passwordEditAlias
+                    AccountAdapter.createJamiAccount(
+                        createAccountPage.text_usernameEditAlias,
+                        inputParaObject,
+                        createAccountPage.boothImgBase64,
+                        true)
+                    showBackUp = !isRdv
+                    showBottom = true
+                    changePageQML(WizardView.WizardViewPageIndex.PROFILEPAGE)
+                }
 
-            onLeavePage: {
-                changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE)
+                onLeavePage: {
+                    changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE)
+                }
             }
 
-            onImportAccount: {
-                inputParaObject = {}
-                inputParaObject["archivePath"] = UtilsAdapter.getAbsPath(importFromBackupPage.filePath)
-                inputParaObject["password"] = importFromBackupPage.text_passwordFromBackupEditAlias
-                showBackUp = false
-                showBottom = false
-                showProfile = true
-                AccountAdapter.createJamiAccount(
-                    "", inputParaObject, "", false)
+            CreateSIPAccountPage {
+                id: createSIPAccountPage
+
+                Layout.alignment: Qt.AlignCenter
+
+                onLeavePage: {
+                    changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE)
+                }
+
+                onCreateAccount: {
+                    inputParaObject = {}
+                    inputParaObject["hostname"] = createSIPAccountPage.text_sipServernameEditAlias
+                    inputParaObject["username"] = createSIPAccountPage.text_sipUsernameEditAlias
+                    inputParaObject["password"] = createSIPAccountPage.text_sipPasswordEditAlias
+                    inputParaObject["proxy"] = createSIPAccountPage.text_sipProxyEditAlias
+                    createSIPAccountPage.clearAllTextFields()
+
+                    AccountAdapter.createSIPAccount(inputParaObject, "")
+                    showBackUp = false
+                    showBottom = false
+                    changePageQML(WizardView.WizardViewPageIndex.PROFILEPAGE)
+                    controlPanelStackView.profilePage.readyToSaveDetails()
+                }
             }
-        }
 
-        BackupKeyPage {
-            id: backupKeysPage
+            ImportFromBackupPage {
+                id: importFromBackupPage
+
+                Layout.alignment: Qt.AlignCenter
+
+                onLeavePage: {
+                    changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE)
+                }
 
-            onNeverShowAgainBoxClicked: {
-                SettingsAdapter.setValue(Settings.NeverShowMeAgain, isChecked)
+                onImportAccount: {
+                    inputParaObject = {}
+                    inputParaObject["archivePath"] = UtilsAdapter.getAbsPath(importFromBackupPage.filePath)
+                    inputParaObject["password"] = importFromBackupPage.text_passwordFromBackupEditAlias
+                    showBackUp = false
+                    showBottom = false
+                    showProfile = true
+                    AccountAdapter.createJamiAccount(
+                        "", inputParaObject, "", false)
+                }
             }
 
-            onExport_Btn_FileDialogAccepted: {
-                if (accepted) {
-                    // is there password? If so, go to password dialog, else, go to following directly
-                    if (AccountAdapter.hasPassword()) {
-                        passwordDialog.path = UtilsAdapter.getAbsPath(folderDir)
-                        passwordDialog.open()
-                        return
-                    } else {
-                        if (folderDir.length > 0) {
-                            AccountAdapter.exportToFile(
-                                        AccountAdapter.currentAccountId,
-                                        UtilsAdapter.getAbsPath(folderDir))
+            BackupKeyPage {
+                id: backupKeysPage
+
+                Layout.alignment: Qt.AlignCenter
+
+                onNeverShowAgainBoxClicked: {
+                    SettingsAdapter.setValue(Settings.NeverShowMeAgain, isChecked)
+                }
+
+                onExport_Btn_FileDialogAccepted: {
+                    if (accepted) {
+                        // is there password? If so, go to password dialog, else, go to following directly
+                        if (AccountAdapter.hasPassword()) {
+                            passwordDialog.path = UtilsAdapter.getAbsPath(folderDir)
+                            passwordDialog.open()
+                            return
+                        } else {
+                            if (folderDir.length > 0) {
+                                AccountAdapter.exportToFile(
+                                            AccountAdapter.currentAccountId,
+                                            UtilsAdapter.getAbsPath(folderDir))
+                            }
                         }
                     }
+
+                    changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE)
+                    needToShowMainViewWindow(addedAccountIndex)
                 }
 
-                changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE)
-                needToShowMainViewWindow(addedAccountIndex)
+                onLeavePage: {
+                    changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE)
+                    needToShowMainViewWindow(addedAccountIndex)
+                }
             }
 
-            onLeavePage: {
-                changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE)
-                needToShowMainViewWindow(addedAccountIndex)
-            }
-        }
+            ImportFromDevicePage {
+                id: importFromDevicePage
 
-        ImportFromDevicePage {
-            id: importFromDevicePage
+                Layout.alignment: Qt.AlignCenter
 
-            onLeavePage: {
-                changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE)
-            }
+                onLeavePage: {
+                    changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE)
+                }
 
-            onImportAccount: {
-                inputParaObject = {}
-                inputParaObject["archivePin"] = importFromDevicePage.text_pinFromDeviceAlias
-                inputParaObject["password"] = importFromDevicePage.text_passwordFromDeviceAlias
+                onImportAccount: {
+                    inputParaObject = {}
+                    inputParaObject["archivePin"] = importFromDevicePage.text_pinFromDeviceAlias
+                    inputParaObject["password"] = importFromDevicePage.text_passwordFromDeviceAlias
 
-                showProfile = true
-                showBackUp = false
-                showBottom = false
-                AccountAdapter.createJamiAccount(
-                    "", inputParaObject, "", false)
+                    showProfile = true
+                    showBackUp = false
+                    showBottom = false
+                    AccountAdapter.createJamiAccount(
+                        "", inputParaObject, "", false)
+                }
             }
-        }
 
-        ConnectToAccountManagerPage {
-            id: connectToAccountManagerPage
-
-            onCreateAccount: {
-                inputParaObject = {}
-                inputParaObject["username"]
-                        = connectToAccountManagerPage.text_usernameManagerEditAlias
-                inputParaObject["password"]
-                        = connectToAccountManagerPage.text_passwordManagerEditAlias
-                inputParaObject["manager"]
-                        = connectToAccountManagerPage.text_accountManagerEditAlias
-                AccountAdapter.createJAMSAccount(inputParaObject)
-            }
+            ConnectToAccountManagerPage {
+                id: connectToAccountManagerPage
 
-            onLeavePage: {
-                changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE)
-            }
-        }
+                Layout.alignment: Qt.AlignCenter
 
-        ProfilePage {
-            id: profilePage
+                onCreateAccount: {
+                    inputParaObject = {}
+                    inputParaObject["username"]
+                            = connectToAccountManagerPage.text_usernameManagerEditAlias
+                    inputParaObject["password"]
+                            = connectToAccountManagerPage.text_passwordManagerEditAlias
+                    inputParaObject["manager"]
+                            = connectToAccountManagerPage.text_accountManagerEditAlias
+                    AccountAdapter.createJAMSAccount(inputParaObject)
+                }
 
-            function leave() {
-                if (showBackUp)
-                    changePageQML(WizardView.WizardViewPageIndex.BACKUPKEYSPAGE)
-                else {
+                onLeavePage: {
                     changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE)
-                    needToShowMainViewWindow(addedAccountIndex)
                 }
             }
 
-            onSaveProfile: {
-                SettingsAdapter.setCurrAccAvatar(profilePage.boothImgBase64)
-                AccountAdapter.setCurrAccDisplayName(profilePage.displayName)
-                leave()
-            }
+            ProfilePage {
+                id: profilePage
+
+                Layout.alignment: Qt.AlignCenter
+
+                function leave() {
+                    if (showBackUp)
+                        changePageQML(WizardView.WizardViewPageIndex.BACKUPKEYSPAGE)
+                    else {
+                        changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE)
+                        needToShowMainViewWindow(addedAccountIndex)
+                    }
+                }
+
+                onSaveProfile: {
+                    SettingsAdapter.setCurrAccAvatar(profilePage.boothImgBase64)
+                    AccountAdapter.setCurrAccDisplayName(profilePage.displayName)
+                    leave()
+                }
 
-            onLeavePage: {
-                leave()
+                onLeavePage: {
+                    leave()
+                }
             }
         }
     }
diff --git a/src/wizardview/components/BackupKeyPage.qml b/src/wizardview/components/BackupKeyPage.qml
index 806333128..f5d9ee7a7 100644
--- a/src/wizardview/components/BackupKeyPage.qml
+++ b/src/wizardview/components/BackupKeyPage.qml
@@ -28,6 +28,8 @@ import "../../settingsview/components"
 Rectangle {
     id: root
 
+    property int preferredHeight: backupKeysPageColumnLayout.implicitHeight
+
     signal neverShowAgainBoxClicked(bool isChecked)
     signal leavePage
     signal export_Btn_FileDialogAccepted(bool accepted, string folderDir)
@@ -62,6 +64,8 @@ Rectangle {
     color: JamiTheme.backgroundColor
 
     ColumnLayout {
+        id: backupKeysPageColumnLayout
+
         spacing: layoutSpacing
 
         anchors.horizontalCenter: parent.horizontalCenter
@@ -71,6 +75,7 @@ Rectangle {
             spacing: layoutSpacing
 
             Layout.alignment: Qt.AlignCenter
+            Layout.topMargin: backButtonMargins
             Layout.preferredWidth: backupBtn.width
 
             Label {
@@ -151,6 +156,7 @@ Rectangle {
 
         MaterialButton {
             Layout.alignment: Qt.AlignCenter
+            Layout.bottomMargin: backButtonMargins
             Layout.preferredWidth: preferredWidth
             Layout.preferredHeight: preferredHeight
 
diff --git a/src/wizardview/components/ConnectToAccountManagerPage.qml b/src/wizardview/components/ConnectToAccountManagerPage.qml
index d4d8ce0f6..3d7e3fc62 100644
--- a/src/wizardview/components/ConnectToAccountManagerPage.qml
+++ b/src/wizardview/components/ConnectToAccountManagerPage.qml
@@ -30,6 +30,7 @@ Rectangle {
     property alias text_passwordManagerEditAlias: passwordManagerEdit.text
     property alias text_accountManagerEditAlias: accountManagerEdit.text
     property string errorText: ""
+    property int preferredHeight: connectToAccountManagerPageColumnLayout.implicitHeight
 
     signal leavePage
     signal createAccount
@@ -59,6 +60,8 @@ Rectangle {
     }
 
     ColumnLayout {
+        id: connectToAccountManagerPageColumnLayout
+
         spacing: layoutSpacing
 
         anchors.horizontalCenter: parent.horizontalCenter
@@ -68,7 +71,8 @@ Rectangle {
             spacing: layoutSpacing
 
             Layout.alignment: Qt.AlignCenter
-            Layout.preferredWidth: connectBtn.width
+            Layout.topMargin: backButtonMargins
+            Layout.preferredWidth: implicitWidth
 
             Label {
                 text: JamiStrings.enterJAMSURL
@@ -108,10 +112,14 @@ Rectangle {
         }
 
         Label {
-            Layout.alignment: Qt.AlignLeft
+            Layout.alignment: Qt.AlignCenter
+            Layout.preferredWidth: connectBtn.width
 
             text: JamiStrings.jamsCredentials
             wrapMode: Text.Wrap
+
+            onTextChanged: Layout.preferredHeight =
+                           JamiQmlUtils.getTextBoundingRect(font, text).height
         }
 
         MaterialLineEdit {
@@ -153,6 +161,7 @@ Rectangle {
             id: connectBtn
 
             Layout.alignment: Qt.AlignCenter
+            Layout.bottomMargin: errorLabel.visible ? 0 : backButtonMargins
             Layout.preferredWidth: preferredWidth
             Layout.preferredHeight: preferredHeight
 
@@ -171,7 +180,10 @@ Rectangle {
         }
 
         Label {
+            id: errorLabel
+
             Layout.alignment: Qt.AlignCenter
+            Layout.bottomMargin: backButtonMargins
 
             visible: errorText.length !== 0
             text: errorText
diff --git a/src/wizardview/components/CreateAccountPage.qml b/src/wizardview/components/CreateAccountPage.qml
index b10e9177b..8a6737062 100644
--- a/src/wizardview/components/CreateAccountPage.qml
+++ b/src/wizardview/components/CreateAccountPage.qml
@@ -33,6 +33,11 @@ Rectangle {
     property alias nameRegistrationUIState: usernameEdit.nameRegistrationState
     property bool isRendezVous: false
     property alias text_passwordEditAlias: passwordEdit.text
+    property int preferredHeight: {
+        if (createAccountStack.currentIndex === 0)
+            return usernameColumnLayout.implicitHeight
+        return passwordColumnLayout.implicitHeight
+    }
 
     signal createAccount
     signal leavePage
@@ -94,218 +99,259 @@ Rectangle {
     StackLayout {
         id: createAccountStack
 
-        anchors.verticalCenter: root.verticalCenter
-        anchors.horizontalCenter: root.horizontalCenter
+        anchors.fill: parent
+
+        currentIndex: 0
 
-        ColumnLayout {
-            spacing: layoutSpacing
+        Rectangle {
+            color: JamiTheme.backgroundColor
 
-            Layout.preferredWidth: root.width
-            Layout.alignment: Qt.AlignCenter
+            ColumnLayout {
+                id: usernameColumnLayout
 
-            RowLayout {
                 spacing: layoutSpacing
 
-                Layout.alignment: Qt.AlignCenter
-                Layout.preferredWidth: usernameEdit.width
+                anchors.centerIn: parent
 
-                Label {
-                    text: isRendezVous ? JamiStrings.chooseNameRV : qsTr("Choose a username for your account")
-                    font.pointSize: JamiTheme.textFontSize + 3
-                }
+                width: root.width
 
-                Label {
-                    Layout.alignment: Qt.AlignRight
+                RowLayout {
+                    spacing: layoutSpacing
 
-                    text: JamiStrings.recommended
-                    color: "white"
-                    padding: 8
+                    Layout.alignment: Qt.AlignCenter
+                    Layout.topMargin: backButtonMargins
+                    Layout.preferredWidth: usernameEdit.width
 
-                    background: Rectangle {
-                        color: "#aed581"
-                        radius: 24
-                        anchors.fill: parent
+                    Label {
+                        text: isRendezVous ? JamiStrings.chooseNameRV : qsTr("Choose a username for your account")
+                        font.pointSize: JamiTheme.textFontSize + 3
+                    }
+
+                    Label {
+                        Layout.alignment: Qt.AlignRight
+
+                        text: JamiStrings.recommended
+                        color: "white"
+                        padding: 8
+
+                        background: Rectangle {
+                            color: "#aed581"
+                            radius: 24
+                            anchors.fill: parent
+                        }
                     }
                 }
-            }
 
-            UsernameLineEdit {
-                id: usernameEdit
+                UsernameLineEdit {
+                    id: usernameEdit
 
-                Layout.topMargin: 15
-                Layout.preferredHeight: fieldLayoutHeight
-                Layout.preferredWidth:  chooseUsernameButton.width
-                Layout.alignment: Qt.AlignHCenter
+                    Layout.topMargin: 15
+                    Layout.preferredHeight: fieldLayoutHeight
+                    Layout.preferredWidth:  chooseUsernameButton.width
+                    Layout.alignment: Qt.AlignHCenter
 
-                placeholderText: isRendezVous ? qsTr("Choose a name") : qsTr("Choose your username")
-            }
+                    placeholderText: isRendezVous ? qsTr("Choose a name") : qsTr("Choose your username")
+                }
 
-            Label {
-                Layout.alignment: Qt.AlignHCenter
-
-                visible: text.length !==0
-
-                text: {
-                    switch(nameRegistrationUIState){
-                    case UsernameLineEdit.NameRegistrationState.BLANK:
-                    case UsernameLineEdit.NameRegistrationState.SEARCHING:
-                    case UsernameLineEdit.NameRegistrationState.FREE:
-                        return ""
-                    case UsernameLineEdit.NameRegistrationState.INVALID:
-                        return isRendezVous ? qsTr("Invalid name") : qsTr("Invalid username")
-                    case UsernameLineEdit.NameRegistrationState.TAKEN:
-                        return isRendezVous ? qsTr("Name already taken") : qsTr("Username already taken")
+                Label {
+                    Layout.alignment: Qt.AlignHCenter
+
+                    visible: text.length !==0
+
+                    text: {
+                        switch(nameRegistrationUIState){
+                        case UsernameLineEdit.NameRegistrationState.BLANK:
+                        case UsernameLineEdit.NameRegistrationState.SEARCHING:
+                        case UsernameLineEdit.NameRegistrationState.FREE:
+                            return ""
+                        case UsernameLineEdit.NameRegistrationState.INVALID:
+                            return isRendezVous ? qsTr("Invalid name") : qsTr("Invalid username")
+                        case UsernameLineEdit.NameRegistrationState.TAKEN:
+                            return isRendezVous ? qsTr("Name already taken") : qsTr("Username already taken")
+                        }
                     }
+                    font.pointSize: JamiTheme.textFontSize
+                    color: "red"
                 }
-                font.pointSize: JamiTheme.textFontSize
-                color: "red"
-            }
 
-            MaterialButton {
-                id: chooseUsernameButton
-
-                Layout.alignment: Qt.AlignCenter
-                Layout.preferredWidth: preferredWidth
-                Layout.preferredHeight: preferredHeight
-
-                fontCapitalization: Font.AllUppercase
-                text: isRendezVous ? JamiStrings.chooseName : JamiStrings.chooseUsername
-                enabled: nameRegistrationUIState === UsernameLineEdit.NameRegistrationState.FREE
-                color: nameRegistrationUIState === UsernameLineEdit.NameRegistrationState.FREE ?
-                           JamiTheme.wizardBlueButtons :
-                           JamiTheme.buttonTintedGreyInactive
-                hoveredColor: JamiTheme.buttonTintedBlueHovered
-                pressedColor: JamiTheme.buttonTintedBluePressed
-
-                onClicked: {
-                    if (nameRegistrationUIState === UsernameLineEdit.NameRegistrationState.FREE)
-                        createAccountStack.currentIndex = createAccountStack.currentIndex + 1
+                MaterialButton {
+                    id: chooseUsernameButton
+
+                    Layout.alignment: Qt.AlignCenter
+                    Layout.preferredWidth: preferredWidth
+                    Layout.preferredHeight: preferredHeight
+
+                    fontCapitalization: Font.AllUppercase
+                    text: isRendezVous ? JamiStrings.chooseName : JamiStrings.chooseUsername
+                    enabled: nameRegistrationUIState === UsernameLineEdit.NameRegistrationState.FREE
+                    color: nameRegistrationUIState === UsernameLineEdit.NameRegistrationState.FREE ?
+                               JamiTheme.wizardBlueButtons :
+                               JamiTheme.buttonTintedGreyInactive
+                    hoveredColor: JamiTheme.buttonTintedBlueHovered
+                    pressedColor: JamiTheme.buttonTintedBluePressed
+
+                    onClicked: {
+                        if (nameRegistrationUIState === UsernameLineEdit.NameRegistrationState.FREE)
+                            createAccountStack.currentIndex = createAccountStack.currentIndex + 1
+                    }
                 }
-            }
 
-            MaterialButton {
-                id: skipButton
+                MaterialButton {
+                    id: skipButton
 
-                Layout.alignment: Qt.AlignCenter
-                Layout.preferredWidth: preferredWidth
-                Layout.preferredHeight: preferredHeight
+                    Layout.alignment: Qt.AlignCenter
+                    Layout.preferredWidth: preferredWidth
+                    Layout.preferredHeight: preferredHeight
 
-                text: JamiStrings.skip
-                color: JamiTheme.buttonTintedGrey
-                hoveredColor: JamiTheme.buttonTintedGreyHovered
-                pressedColor: JamiTheme.buttonTintedGreyPressed
-                outlined: true
+                    text: JamiStrings.skip
+                    color: JamiTheme.buttonTintedGrey
+                    hoveredColor: JamiTheme.buttonTintedGreyHovered
+                    pressedColor: JamiTheme.buttonTintedGreyPressed
+                    outlined: true
 
-                onClicked: createAccountStack.currentIndex =
-                           createAccountStack.currentIndex + 1
+                    onClicked: createAccountStack.currentIndex =
+                               createAccountStack.currentIndex + 1
+                }
+
+                AccountCreationStepIndicator {
+                    Layout.topMargin: backButtonMargins
+                    Layout.bottomMargin: backButtonMargins
+                    Layout.alignment: Qt.AlignHCenter
+
+                    spacing: layoutSpacing
+                    steps: 3
+                    currentStep: 1
+                }
             }
         }
 
-        ColumnLayout {
-            spacing: layoutSpacing
+        Rectangle {
+            color: JamiTheme.backgroundColor
 
-            Layout.preferredWidth: root.width
-            Layout.alignment: Qt.AlignCenter
+            ColumnLayout {
+                id: passwordColumnLayout
 
-            RowLayout {
                 spacing: layoutSpacing
 
-                Layout.alignment: Qt.AlignCenter
-                Layout.preferredWidth: usernameEdit.width
+                anchors.centerIn: parent
+                width: root.width
 
-                Label {
-                    text: JamiStrings.createPassword
-                    font.pointSize: JamiTheme.textFontSize + 3
+                RowLayout {
+                    spacing: layoutSpacing
+
+                    Layout.alignment: Qt.AlignCenter
+                    Layout.topMargin: backButtonMargins
+                    Layout.preferredWidth: usernameEdit.width
+
+                    Label {
+                        Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
+                        text: JamiStrings.createPassword
+                        font.pointSize: JamiTheme.textFontSize + 3
+                    }
 
                     Switch {
                         id: passwordSwitch
 
-                        anchors.left: parent.right
-                        anchors.verticalCenter: parent.verticalCenter
+                        Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
+                        Layout.leftMargin:  -layoutSpacing
+                        Layout.topMargin: 5
                     }
-                }
 
-                Label {
-                    Layout.alignment: Qt.AlignRight
+                    Label {
+                        Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
 
-                    text: JamiStrings.optional
-                    color: "white"
-                    padding: 8
+                        text: JamiStrings.optional
+                        color: "white"
+                        padding: 8
 
-                    background: Rectangle {
-                        color: "#28b1ed"
-                        radius: 24
-                        anchors.fill: parent
+                        background: Rectangle {
+                            color: "#28b1ed"
+                            radius: 24
+                            anchors.fill: parent
+                        }
                     }
                 }
-            }
 
-            MaterialLineEdit {
-                id: passwordEdit
+                MaterialLineEdit {
+                    id: passwordEdit
 
-                Layout.preferredHeight: fieldLayoutHeight
-                Layout.preferredWidth: createAccountButton.width
-                Layout.alignment: Qt.AlignHCenter
+                    Layout.preferredHeight: fieldLayoutHeight
+                    Layout.preferredWidth: createAccountButton.width
+                    Layout.alignment: Qt.AlignHCenter
 
-                visible: passwordSwitch.checked
+                    visible: passwordSwitch.checked
 
-                selectByMouse: true
-                echoMode: TextInput.Password
-                placeholderText: JamiStrings.password
-                font.pointSize: 9
-                font.kerning: true
-            }
+                    selectByMouse: true
+                    echoMode: TextInput.Password
+                    placeholderText: JamiStrings.password
+                    font.pointSize: 9
+                    font.kerning: true
+                }
 
-            MaterialLineEdit {
-                id: passwordConfirmEdit
+                MaterialLineEdit {
+                    id: passwordConfirmEdit
 
-                Layout.preferredHeight: fieldLayoutHeight
-                Layout.preferredWidth: createAccountButton.width
-                Layout.alignment: Qt.AlignHCenter
+                    Layout.preferredHeight: fieldLayoutHeight
+                    Layout.preferredWidth: createAccountButton.width
+                    Layout.alignment: Qt.AlignHCenter
 
-                visible: passwordSwitch.checked
+                    visible: passwordSwitch.checked
 
-                selectByMouse: true
-                echoMode: TextInput.Password
-                placeholderText: JamiStrings.confirmPassword
-                font.pointSize: 9
-                font.kerning: true
-            }
+                    selectByMouse: true
+                    echoMode: TextInput.Password
+                    placeholderText: JamiStrings.confirmPassword
+                    font.pointSize: 9
+                    font.kerning: true
+                }
 
-            Label {
-                Layout.alignment: Qt.AlignLeft
-                Layout.topMargin: 10
-                Layout.leftMargin: (root.width - createAccountButton.width) / 2
+                Label {
+                    Layout.alignment: Qt.AlignLeft
+                    Layout.preferredWidth: createAccountButton.width - 10
+                    Layout.leftMargin: (root.width - createAccountButton.width) / 2
 
-                text: JamiStrings.notePasswordRecovery
-                font.pointSize: JamiTheme.textFontSize
-            }
+                    text: JamiStrings.notePasswordRecovery
+                    wrapMode: Text.WordWrap
+                    font.pointSize: JamiTheme.textFontSize
+
+                    onFontChanged: Layout.preferredHeight =
+                                   JamiQmlUtils.getTextBoundingRect(font, text).height * 2
+                }
 
-            MaterialButton {
-                id: createAccountButton
+                MaterialButton {
+                    id: createAccountButton
 
-                Layout.alignment: Qt.AlignCenter
-                Layout.topMargin: 10
-                Layout.preferredWidth: preferredWidth
-                Layout.preferredHeight: preferredHeight
+                    Layout.alignment: Qt.AlignCenter
+                    Layout.preferredWidth: preferredWidth
+                    Layout.preferredHeight: preferredHeight
+
+                    function checkEnable() {
+                        return !passwordSwitch.checked ||
+                                (passwordEdit.text === passwordConfirmEdit.text
+                                 && passwordEdit.text.length !== 0)
+                    }
 
-                function checkEnable() {
-                    return !passwordSwitch.checked ||
-                            (passwordEdit.text === passwordConfirmEdit.text
-                             && passwordEdit.text.length !== 0)
+                    fontCapitalization: Font.AllUppercase
+                    text: isRendezVous ? JamiStrings.createRV : JamiStrings.createAccount
+                    enabled: checkEnable()
+                    color: checkEnable() ? JamiTheme.wizardBlueButtons :
+                                           JamiTheme.buttonTintedGreyInactive
+                    hoveredColor: JamiTheme.buttonTintedBlueHovered
+                    pressedColor: JamiTheme.buttonTintedBluePressed
+
+                    onClicked: {
+                        createAccount()
+                        createAccountStack.currentIndex += 1
+                    }
                 }
 
-                fontCapitalization: Font.AllUppercase
-                text: isRendezVous ? JamiStrings.createRV : JamiStrings.createAccount
-                enabled: checkEnable()
-                color: checkEnable() ? JamiTheme.wizardBlueButtons :
-                                       JamiTheme.buttonTintedGreyInactive
-                hoveredColor: JamiTheme.buttonTintedBlueHovered
-                pressedColor: JamiTheme.buttonTintedBluePressed
-
-                onClicked: {
-                    createAccount()
-                    createAccountStack.currentIndex += 1
+                AccountCreationStepIndicator {
+                    Layout.topMargin: backButtonMargins
+                    Layout.bottomMargin: backButtonMargins
+                    Layout.alignment: Qt.AlignHCenter
+
+                    spacing: layoutSpacing
+                    steps: 3
+                    currentStep: 2
                 }
             }
         }
@@ -316,7 +362,7 @@ Rectangle {
 
         anchors.left: parent.left
         anchors.top: parent.top
-        anchors.margins: 20
+        anchors.margins: backButtonMargins
 
         width: 35
         height: 35
@@ -336,14 +382,4 @@ Rectangle {
                 createAccountStack.currentIndex -= 1
         }
     }
-
-    AccountCreationStepIndicator {
-        anchors.bottom: root.bottom
-        anchors.bottomMargin: 30
-        anchors.horizontalCenter: root.horizontalCenter
-
-        spacing: layoutSpacing
-        steps: 3
-        currentStep: usernameEdit.visible ? 1 : 2
-    }
 }
diff --git a/src/wizardview/components/CreateSIPAccountPage.qml b/src/wizardview/components/CreateSIPAccountPage.qml
index 0ad21be69..1ee25d958 100644
--- a/src/wizardview/components/CreateSIPAccountPage.qml
+++ b/src/wizardview/components/CreateSIPAccountPage.qml
@@ -30,6 +30,7 @@ Rectangle {
     property alias text_sipProxyEditAlias: sipProxyEdit.text
     property alias text_sipUsernameEditAlias: sipUsernameEdit.text
     property alias text_sipPasswordEditAlias: sipPasswordEdit.text
+    property int preferredHeight: createSIPAccountPageColumnLayout.implicitHeight
 
     property var boothImgBase64: null
 
@@ -56,6 +57,8 @@ Rectangle {
     }
 
     ColumnLayout {
+        id: createSIPAccountPageColumnLayout
+
         spacing: layoutSpacing
 
         anchors.centerIn: parent
@@ -64,6 +67,7 @@ Rectangle {
             spacing: layoutSpacing
 
             Layout.alignment: Qt.AlignCenter
+            Layout.topMargin: backButtonMargins
             Layout.preferredWidth: createAccountButton.width
 
             Label {
@@ -143,6 +147,7 @@ Rectangle {
             id: createAccountButton
 
             Layout.alignment: Qt.AlignCenter
+            Layout.bottomMargin: backButtonMargins
             Layout.preferredWidth: preferredWidth
             Layout.preferredHeight: preferredHeight
 
diff --git a/src/wizardview/components/ImportFromBackupPage.qml b/src/wizardview/components/ImportFromBackupPage.qml
index 787a3c3ed..2edc0303d 100644
--- a/src/wizardview/components/ImportFromBackupPage.qml
+++ b/src/wizardview/components/ImportFromBackupPage.qml
@@ -31,6 +31,7 @@ Rectangle {
 
     property alias text_passwordFromBackupEditAlias: passwordFromBackupEdit.text
     property string fileImportBtnText: JamiStrings.archive
+    property int preferredHeight: importFromBackupPageColumnLayout.implicitHeight
 
     property string filePath: ""
     property string errorText: ""
@@ -72,6 +73,8 @@ Rectangle {
     }
 
     ColumnLayout {
+        id: importFromBackupPageColumnLayout
+
         spacing: layoutSpacing
 
         anchors.horizontalCenter: parent.horizontalCenter
@@ -79,6 +82,7 @@ Rectangle {
 
         Text {
             Layout.alignment: Qt.AlignCenter
+            Layout.topMargin: backButtonMargins
 
             text: qsTr("Import from backup")
             font.pointSize: JamiTheme.menuFontSize
@@ -145,6 +149,7 @@ Rectangle {
             id: connectBtn
 
             Layout.alignment: Qt.AlignCenter
+            Layout.bottomMargin: errorLabel.visible ? 0 : backButtonMargins
             Layout.preferredWidth: preferredWidth
             Layout.preferredHeight: preferredHeight
 
@@ -166,7 +171,10 @@ Rectangle {
         }
 
         Label {
+            id: errorLabel
+
             Layout.alignment: Qt.AlignCenter
+            Layout.bottomMargin: backButtonMargins
 
             visible: errorText.length !== 0
 
diff --git a/src/wizardview/components/ImportFromDevicePage.qml b/src/wizardview/components/ImportFromDevicePage.qml
index dd42208f8..afcddc2b5 100644
--- a/src/wizardview/components/ImportFromDevicePage.qml
+++ b/src/wizardview/components/ImportFromDevicePage.qml
@@ -29,6 +29,7 @@ Rectangle {
     property alias text_pinFromDeviceAlias: pinFromDevice.text
     property alias text_passwordFromDeviceAlias: passwordFromDevice.text
     property string errorText: ""
+    property int preferredHeight: importFromDevicePageColumnLayout.implicitHeight
 
     signal leavePage
     signal importAccount
@@ -56,6 +57,8 @@ Rectangle {
     }
 
     ColumnLayout {
+        id: importFromDevicePageColumnLayout
+
         spacing: layoutSpacing
 
         // Prevent possible anchor loop detected on centerIn.
@@ -64,6 +67,7 @@ Rectangle {
 
         Text {
             Layout.alignment: Qt.AlignCenter
+            Layout.topMargin: backButtonMargins
 
             text: JamiStrings.mainAccountPassword
             font.pointSize: JamiTheme.menuFontSize
@@ -125,6 +129,7 @@ Rectangle {
             id: connectBtn
 
             Layout.alignment: Qt.AlignCenter
+            Layout.bottomMargin: errorLabel.visible ? 0 : backButtonMargins
             Layout.preferredWidth: preferredWidth
             Layout.preferredHeight: preferredHeight
 
@@ -140,7 +145,10 @@ Rectangle {
         }
 
         Label {
+            id: errorLabel
+
             Layout.alignment: Qt.AlignCenter
+            Layout.bottomMargin: backButtonMargins
 
             visible: errorText.length !== 0
 
diff --git a/src/wizardview/components/ProfilePage.qml b/src/wizardview/components/ProfilePage.qml
index 2f9dc5430..4f092844b 100644
--- a/src/wizardview/components/ProfilePage.qml
+++ b/src/wizardview/components/ProfilePage.qml
@@ -26,6 +26,8 @@ import "../../commoncomponents"
 Rectangle {
     id: root
 
+    property int preferredHeight: profilePageColumnLayout.implicitHeight
+
     function initializeOnShowUp() {
         clearAllTextFields()
         boothImgBase64 = ""
@@ -51,6 +53,8 @@ Rectangle {
     property bool isRdv: false
 
     ColumnLayout {
+        id: profilePageColumnLayout
+
         spacing: layoutSpacing
 
         width: parent.width
@@ -60,6 +64,7 @@ Rectangle {
         RowLayout {
             spacing: layoutSpacing
 
+            Layout.topMargin: backButtonMargins
             Layout.preferredWidth: saveProfileBtn.width
             Layout.alignment: Qt.AlignCenter
 
@@ -139,15 +144,15 @@ Rectangle {
                 leavePage()
             }
         }
-    }
 
-    AccountCreationStepIndicator {
-        anchors.bottom: root.bottom
-        anchors.bottomMargin: 30
-        anchors.horizontalCenter: root.horizontalCenter
+        AccountCreationStepIndicator {
+            Layout.topMargin: backButtonMargins
+            Layout.bottomMargin: backButtonMargins
+            Layout.alignment: Qt.AlignHCenter
 
-        spacing: layoutSpacing
-        steps: 3
-        currentStep: 3
+            spacing: layoutSpacing
+            steps: 3
+            currentStep: 3
+        }
     }
 }
diff --git a/src/wizardview/components/WelcomePage.qml b/src/wizardview/components/WelcomePage.qml
index 00d597194..1debe547a 100644
--- a/src/wizardview/components/WelcomePage.qml
+++ b/src/wizardview/components/WelcomePage.qml
@@ -30,12 +30,17 @@ import "../../commoncomponents"
 Rectangle {
     id: root
 
+    property int preferredHeight: welcomePageColumnLayout.implicitHeight
+
     signal welcomePageRedirectPage(int toPageIndex)
     signal leavePage
+    signal scrollToBottom
 
     color: JamiTheme.backgroundColor
 
     ColumnLayout {
+        id: welcomePageColumnLayout
+
         anchors.centerIn: parent
 
         spacing: layoutSpacing
@@ -44,6 +49,7 @@ Rectangle {
             id: welcomeLabel
 
             Layout.alignment: Qt.AlignCenter
+            Layout.topMargin: backButtonMargins
             Layout.preferredHeight: contentHeight
 
             text: qsTr("Welcome to")
@@ -154,6 +160,7 @@ Rectangle {
             id: showAdvancedButton
 
             Layout.alignment: Qt.AlignCenter
+            Layout.bottomMargin: newSIPAccountButton.visible ? 0 : backButtonMargins
             Layout.preferredWidth: preferredWidth
             Layout.preferredHeight: preferredHeight
 
@@ -203,6 +210,7 @@ Rectangle {
             id: newSIPAccountButton
 
             Layout.alignment: Qt.AlignCenter
+            Layout.bottomMargin: backButtonMargins
             Layout.preferredWidth: preferredWidth
             Layout.preferredHeight: preferredHeight
 
@@ -220,6 +228,8 @@ Rectangle {
                 welcomePageRedirectPage(2)
             }
         }
+
+        onHeightChanged: scrollToBottom()
     }
 
     HoverableButton {
@@ -227,7 +237,7 @@ Rectangle {
 
         anchors.left: parent.left
         anchors.top: parent.top
-        anchors.margins: 20
+        anchors.margins: backButtonMargins
 
         Connections {
             target: LRCInstance
-- 
GitLab