From 234ee7a2e9da9b1f42e873e8e86bd2cba3c5154c Mon Sep 17 00:00:00 2001 From: Ming Rui Zhang <mingrui.zhang@savoirfairelinux.com> Date: Fri, 16 Jul 2021 10:34:50 -0400 Subject: [PATCH] wizardview: refactor account creation ui and enhance flow 1. Use MaterialToolTip in MaterialButton 2. Add BubbleLabel and BackButton 3. Add WizardViewStepModel 4. Focus re-visit Gitlab: #470 Change-Id: I818da76c4b97cb08d2b6df6b2c8e2752d7a522f2 --- CMakeLists.txt | 2 + qml.qrc | 2 + src/MainApplicationWindow.qml | 3 - src/accountadapter.cpp | 10 +- src/accountadapter.h | 2 +- src/appsettingsmanager.h | 4 +- src/commoncomponents/BackButton.qml | 32 ++ src/commoncomponents/BubbleLabel.qml | 36 ++ src/commoncomponents/MaterialButton.qml | 14 +- src/commoncomponents/PushButton.qml | 1 - src/constant/JamiQmlUtils.qml | 8 + src/constant/JamiStrings.qml | 27 +- src/constant/JamiTheme.qml | 10 + src/mainview/MainView.qml | 14 +- src/qmlregister.cpp | 11 +- src/wizardview/WizardView.qml | 326 +++--------------- src/wizardview/components/BackupKeyPage.qml | 89 +++-- .../ConnectToAccountManagerPage.qml | 81 +++-- .../components/CreateAccountPage.qml | 175 ++++------ .../components/CreateSIPAccountPage.qml | 81 ++--- .../components/ImportFromBackupPage.qml | 70 ++-- .../components/ImportFromDevicePage.qml | 67 ++-- src/wizardview/components/ProfilePage.qml | 91 ++--- src/wizardview/components/WelcomePage.qml | 93 +++-- src/wizardviewstepmodel.cpp | 144 ++++++++ src/wizardviewstepmodel.h | 83 +++++ 26 files changed, 791 insertions(+), 685 deletions(-) create mode 100644 src/commoncomponents/BackButton.qml create mode 100644 src/commoncomponents/BubbleLabel.qml create mode 100644 src/wizardviewstepmodel.cpp create mode 100644 src/wizardviewstepmodel.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c28717ab7..42449864e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,6 +86,7 @@ set(COMMON_SOURCES ${SRC_DIR}/searchresultslistmodel.cpp ${SRC_DIR}/calloverlaymodel.cpp ${SRC_DIR}/filestosendlistmodel.cpp + ${SRC_DIR}/wizardviewstepmodel.cpp ${SRC_DIR}/avatarregistry.cpp) set(COMMON_HEADERS @@ -143,6 +144,7 @@ set(COMMON_HEADERS ${SRC_DIR}/searchresultslistmodel.h ${SRC_DIR}/calloverlaymodel.h ${SRC_DIR}/filestosendlistmodel.h + ${SRC_DIR}/wizardviewstepmodel.h ${SRC_DIR}/avatarregistry.h) set(QML_LIBS diff --git a/qml.qrc b/qml.qrc index e4a1b61f8..297d67ee8 100644 --- a/qml.qrc +++ b/qml.qrc @@ -157,5 +157,7 @@ <file>src/mainview/components/InvitationView.qml</file> <file>src/commoncomponents/GeneralWebEngineView.qml</file> <file>src/constant/JamiResources.qml</file> + <file>src/commoncomponents/BubbleLabel.qml</file> + <file>src/commoncomponents/BackButton.qml</file> </qresource> </RCC> diff --git a/src/MainApplicationWindow.qml b/src/MainApplicationWindow.qml index 5da265bdf..0579e722d 100644 --- a/src/MainApplicationWindow.qml +++ b/src/MainApplicationWindow.qml @@ -106,9 +106,6 @@ ApplicationWindow { } function startClient(){ - setX(Screen.width / 2 - width / 2) - setY(Screen.height / 2 - height / 2) - if (UtilsAdapter.getAccountListSize() !== 0) { mainApplicationLoader.setSource(JamiQmlUtils.mainViewLoadPath) } else { diff --git a/src/accountadapter.cpp b/src/accountadapter.cpp index f65dd4c96..eb3f1395e 100644 --- a/src/accountadapter.cpp +++ b/src/accountadapter.cpp @@ -107,20 +107,15 @@ AccountAdapter::createJamiAccount(QString registeredName, confProps.isRendezVous = settings["isRendezVous"].toBool(); lrcInstance_->accountModel().setAccountConfig(accountId, confProps); - auto showBackup = isCreating - && !settingsManager_->getValue(Settings::Key::NeverShowMeAgain) - .toBool(); if (!registeredName.isEmpty()) { QObject::disconnect(registeredNameSavedConnection_); registeredNameSavedConnection_ = connect(&lrcInstance_->accountModel(), &lrc::api::NewAccountModel::profileUpdated, - [this, showBackup, addedAccountId = accountId]( - const QString& accountId) { + [this, addedAccountId = accountId](const QString& accountId) { if (addedAccountId == accountId) { Q_EMIT lrcInstance_->accountListChanged(); Q_EMIT accountAdded(accountId, - showBackup, lrcInstance_->accountModel() .getAccountList() .indexOf(accountId)); @@ -134,7 +129,6 @@ AccountAdapter::createJamiAccount(QString registeredName, } else { Q_EMIT lrcInstance_->accountListChanged(); Q_EMIT accountAdded(accountId, - showBackup, lrcInstance_->accountModel().getAccountList().indexOf( accountId)); } @@ -172,7 +166,6 @@ AccountAdapter::createSIPAccount(const QVariantMap& settings) Q_EMIT lrcInstance_->accountListChanged(); Q_EMIT accountAdded(accountId, - false, lrcInstance_->accountModel() .getAccountList() .indexOf(accountId)); @@ -208,7 +201,6 @@ AccountAdapter::createJAMSAccount(const QVariantMap& settings) lrcInstance_->accountModel().setAccountConfig(accountId, confProps); Q_EMIT accountAdded(accountId, - false, lrcInstance_->accountModel() .getAccountList() .indexOf(accountId)); diff --git a/src/accountadapter.h b/src/accountadapter.h index 7ffcbce76..f4f8e2280 100644 --- a/src/accountadapter.h +++ b/src/accountadapter.h @@ -95,7 +95,7 @@ Q_SIGNALS: // Send report failure to QML to make it show the right UI state . void reportFailure(); - void accountAdded(QString accountId, bool showBackUp, int index); + void accountAdded(QString accountId, int index); private: // Implement what to do when account creation fails. diff --git a/src/appsettingsmanager.h b/src/appsettingsmanager.h index 6ff083ff1..6c4f5d0dc 100644 --- a/src/appsettingsmanager.h +++ b/src/appsettingsmanager.h @@ -94,8 +94,8 @@ public: explicit AppSettingsManager(QObject* parent = nullptr); ~AppSettingsManager() = default; - QVariant getValue(const Settings::Key key); - void setValue(const Settings::Key key, const QVariant& value); + Q_INVOKABLE QVariant getValue(const Settings::Key key); + Q_INVOKABLE void setValue(const Settings::Key key, const QVariant& value); private: QSettings* settings_; diff --git a/src/commoncomponents/BackButton.qml b/src/commoncomponents/BackButton.qml new file mode 100644 index 000000000..9f523b009 --- /dev/null +++ b/src/commoncomponents/BackButton.qml @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2021 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.Constants 1.0 + +PushButton { + id: root + + normalColor: JamiTheme.backgroundColor + imageColor: JamiTheme.primaryForegroundColor + + source: JamiResources.ic_arrow_back_24dp_svg + toolTipText: JamiStrings.back +} diff --git a/src/commoncomponents/BubbleLabel.qml b/src/commoncomponents/BubbleLabel.qml new file mode 100644 index 000000000..1b81e5499 --- /dev/null +++ b/src/commoncomponents/BubbleLabel.qml @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2021 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.Constants 1.0 + +Label { + id: root + + property color textColor: JamiTheme.whiteColor + property color bubbleColor: JamiTheme.wizardGreenColor + + padding: 8 + + background: Rectangle { + color: bubbleColor + radius: 24 + } +} diff --git a/src/commoncomponents/MaterialButton.qml b/src/commoncomponents/MaterialButton.qml index 09c835bcd..578c9922b 100644 --- a/src/commoncomponents/MaterialButton.qml +++ b/src/commoncomponents/MaterialButton.qml @@ -28,7 +28,7 @@ Button { property alias fontCapitalization: buttonText.font.capitalization property alias source: buttonImage.source - property string toolTipText: "" + property alias toolTipText: toolTip.text property var color: "transparent" property var hoveredColor: undefined property var pressedColor: undefined @@ -50,6 +50,14 @@ Button { hoverEnabled: hoveredColor !== undefined + MaterialToolTip { + id: toolTip + + parent: root + visible: hovered && (toolTipText.length > 0) + delay: Qt.styleHints.mousePressAndHoldInterval + } + contentItem: Item { Rectangle { anchors.fill: parent @@ -131,10 +139,6 @@ Button { } } - ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval - ToolTip.visible: hovered && (toolTipText.length > 0) - ToolTip.text: toolTipText - background: Rectangle { id: backgroundRect anchors.fill: parent diff --git a/src/commoncomponents/PushButton.qml b/src/commoncomponents/PushButton.qml index 4bf762c74..ef9bbb011 100644 --- a/src/commoncomponents/PushButton.qml +++ b/src/commoncomponents/PushButton.qml @@ -80,7 +80,6 @@ AbstractButton { hoverEnabled: true focusPolicy: Qt.TabFocus - MaterialToolTip { id: toolTip diff --git a/src/constant/JamiQmlUtils.qml b/src/constant/JamiQmlUtils.qml index a7ebbf6f4..58395c029 100644 --- a/src/constant/JamiQmlUtils.qml +++ b/src/constant/JamiQmlUtils.qml @@ -35,6 +35,14 @@ Item { property bool callIsFullscreen: false signal fullScreenCallEnded + property var accountCreationInputParaObject: ({}) + + function setUpAccountCreationInputPara(inputPara) { + JamiQmlUtils.accountCreationInputParaObject = {} + Object.assign(JamiQmlUtils.accountCreationInputParaObject, inputPara) + return accountCreationInputParaObject + } + // MessageBar buttons in mainview points property var mainViewRectObj property var messageBarButtonsRowObj diff --git a/src/constant/JamiStrings.qml b/src/constant/JamiStrings.qml index e8319e3d9..f8876d7d0 100644 --- a/src/constant/JamiStrings.qml +++ b/src/constant/JamiStrings.qml @@ -177,8 +177,12 @@ Item { property string backupAccount: qsTr("Backup your account!") property string backupAccountBtn: qsTr("Backup account") property string skip: qsTr("Skip") + property string success: qsTr("Success") + property string error: qsTr("Error") property string neverShowAgain: qsTr("Never show me this again") property string recommended: qsTr("Recommended") + property string jamiArchiveFiles: qsTr("Jami archive files") + property string allFiles: qsTr("All files") // BannedItemDelegate property string reinstateContact: qsTr("Reinstate as contact") @@ -247,7 +251,7 @@ Item { property string jamiManagementServerURL: qsTr("Jami Account Management Server URL") property string jamsCredentials: qsTr("Enter your JAMS credentials") property string connect: qsTr("Connect") - property string generatingAccount: qsTr("Creating account…") + property string creatingAccount: qsTr("Creating account…") property string backToWelcome: qsTr("Back to welcome page") // CreateAccountPage @@ -259,7 +263,14 @@ Item { property string confirmPassword: qsTr("Confirm password") property string notePasswordRecovery: qsTr("Choose a password to encrypt your account on this device. Note that the password cannot be recovered.") property string optional: qsTr("Optional") - property string chooseNameRV: qsTr("Choose a name for your rendezvous point") + property string chooseUsernameForAccount: qsTr("Choose a username for your account") + property string chooseUsernameForRV: qsTr("Choose a name for your rendezvous point") + property string chooseAName: qsTr("Choose a name") + property string chooseYourUserName: qsTr("Choose your username") + property string invalidName: qsTr("Invalid name") + property string invalidUsername: qsTr("Invalid username") + property string nameAlreadyTaken: qsTr("Name already taken") + property string usernameAlreadyTaken: qsTr("Username already taken") // CreateSIPAccountPage property string proxy: qsTr("Proxy") @@ -375,12 +386,15 @@ Item { "in the account settings. " + "This will create a .gz file on your device.") property string connectFromBackup: qsTr("Restore an account from backup") + property string generatingAccount: qsTr("Generating account…") + property string importFromBackup: qsTr("Import from backup") // ImportFromDevicePage property string mainAccountPassword: qsTr("Enter Jami account password") property string enterPIN: qsTr("Enter the PIN from another configured Jami account. " + "Use the \"Link Another Device\" feature to obtain a PIN.") property string connectFromAnotherDevice: qsTr("Link device") + property string pin: qsTr("PIN") // LinkDevicesDialog property string pinTimerInfos: qsTr("The PIN and the account password should be entered in your device within 10 minutes.") @@ -423,7 +437,9 @@ Item { property string chooseImageFile: qsTr("Choose image file") // ProfilePage + property string profileSharedWithContacts: qsTr("Profile is only shared with contacts") property string saveProfile: qsTr("Save profile") + property string enterYourName: qsTr("Enter your name") property string enterRVName: qsTr("Enter the rendezvous point's name") property string generatingRV: qsTr("Creating rendezvous point…") property string information: qsTr("Information") @@ -443,6 +459,8 @@ Item { // WelcomePage property string shareInvite: qsTr("This is your Jami username.\nCopy and share it with your friends!") property string linkFromAnotherDevice: qsTr("Link this device to an existing account") + property string importAccountFromOtherDevice: qsTr("Import account from other device") + property string importAccountFromBackup: qsTr("Import account from backup file") property string advancedFeatures: qsTr("Advanced features") property string showAdvancedFeatures: qsTr("Show advanced features") property string connectJAMSServer: qsTr("Connect to a JAMS server") @@ -450,8 +468,11 @@ Item { property string addSIPAccount: qsTr("Add a SIP account") property string errorCreateAccount: qsTr("Error while creating your account. Check your credentials.") property string createNewRV: qsTr("Create new rendezvous point") - property string createNewJA: qsTr("Create a Jami account") + property string createAJamiAccount: qsTr("Create a Jami account") + property string createNewJamiAccount: qsTr("Create new Jami account") + property string createNewSipAccount: qsTr("Create new SIP account") property string aboutJami: qsTr("About Jami") + property string welcomeTo: qsTr("Welcome to") // SmartList property string clearText: qsTr("Clear Text") diff --git a/src/constant/JamiTheme.qml b/src/constant/JamiTheme.qml index ae77e712b..9958f963d 100644 --- a/src/constant/JamiTheme.qml +++ b/src/constant/JamiTheme.qml @@ -287,6 +287,16 @@ Item { property real invitationViewButtonIconSize: 24 property real invitationViewButtonsSpacing: 30 + // WizardView + property real wizardViewPageLayoutSpacing: 12 + property real wizardViewPageBackButtonMargins: 20 + property real wizardViewPageBackButtonSize: 35 + + // WizardView Welcome Page + property real welcomeLabelPointSize: 30 + property real welcomeLogoWidth: 330 + property real welcomeLogoHeight: 110 + // Main application spec property real mainViewMinWidth: 300 property real mainViewMinHeight: 500 diff --git a/src/mainview/MainView.qml b/src/mainview/MainView.qml index 68d9ec2eb..f468972c8 100644 --- a/src/mainview/MainView.qml +++ b/src/mainview/MainView.qml @@ -232,6 +232,15 @@ Rectangle { } } + Connections { + target: WizardViewStepModel + + function onCloseWizardView() { + mainViewStackLayout.currentIndex = 0 + backToMainView() + } + } + StackLayout { id: mainViewStackLayout @@ -329,11 +338,6 @@ Rectangle { mainViewStackLayout.currentIndex = 0 backToMainView() } - - onWizardViewIsClosed: { - mainViewStackLayout.currentIndex = 0 - backToMainView() - } } } diff --git a/src/qmlregister.cpp b/src/qmlregister.cpp index 1bb6ebfa7..891761daf 100644 --- a/src/qmlregister.cpp +++ b/src/qmlregister.cpp @@ -54,6 +54,7 @@ #include "videoformatfpsmodel.h" #include "videoformatresolutionmodel.h" #include "videoinputdevicemodel.h" +#include "wizardviewstepmodel.h" #include "api/peerdiscoverymodel.h" #include "api/newcodecmodel.h" @@ -125,9 +126,6 @@ registerTypes(QQmlEngine* engine, QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, settingsAdapter, "SettingsAdapter"); QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, pluginAdapter, "PluginAdapter"); - auto avatarRegistry = new AvatarRegistry(lrcInstance, parent); - QML_REGISTERSINGLETONTYPE_POBJECT(NS_HELPERS, avatarRegistry, "AvatarRegistry"); - // TODO: remove these QML_REGISTERSINGLETONTYPE_CUSTOM(NS_MODELS, AVModel, &lrcInstance->avModel()) QML_REGISTERSINGLETONTYPE_CUSTOM(NS_MODELS, PluginModel, &lrcInstance->pluginModel()) @@ -178,6 +176,12 @@ registerTypes(QQmlEngine* engine, QML_REGISTERSINGLETONTYPE_POBJECT(NS_CONSTANTS, screenInfo, "ScreenInfo") QML_REGISTERSINGLETONTYPE_POBJECT(NS_CONSTANTS, lrcInstance, "LRCInstance") + QML_REGISTERSINGLETONTYPE_POBJECT(NS_CONSTANTS, appSettingsManager, "AppSettingsManager") + + auto avatarRegistry = new AvatarRegistry(lrcInstance, parent); + auto wizardViewStepModel = new WizardViewStepModel(lrcInstance, accountAdapter, appSettingsManager, parent); + QML_REGISTERSINGLETONTYPE_POBJECT(NS_HELPERS, avatarRegistry, "AvatarRegistry"); + QML_REGISTERSINGLETONTYPE_POBJECT(NS_MODELS, wizardViewStepModel, "WizardViewStepModel") // C++ singletons // TODO: remove this @@ -207,6 +211,7 @@ registerTypes(QQmlEngine* engine, // Enums QML_REGISTERUNCREATABLE(NS_ENUMS, Settings); QML_REGISTERUNCREATABLE(NS_ENUMS, NetWorkManager); + QML_REGISTERUNCREATABLE(NS_ENUMS, WizardViewStepModel) engine->addImageProvider(QLatin1String("qrImage"), new QrImageProvider(lrcInstance)); engine->addImageProvider(QLatin1String("avatarImage"), diff --git a/src/wizardview/WizardView.qml b/src/wizardview/WizardView.qml index 029cfcbbd..ef726f044 100644 --- a/src/wizardview/WizardView.qml +++ b/src/wizardview/WizardView.qml @@ -1,6 +1,7 @@ /* - * Copyright (C) 2020 by Savoir-faire Linux + * Copyright (C) 2021 by Savoir-faire Linux * Author: Yang Wang <yang.wang@savoirfairelinux.com> + * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,6 +26,7 @@ import QtGraphicalEffects 1.14 import net.jami.Models 1.0 import net.jami.Adapters 1.0 import net.jami.Constants 1.0 +import net.jami.Enums 1.0 import "../" import "../commoncomponents" @@ -33,148 +35,40 @@ import "components" Rectangle { id: root - enum Mode { - CREATE, - IMPORT, - MIGRATE, - CREATESIP, - CONNECTMANAGER - } - - enum WizardViewPageIndex { - WELCOMEPAGE = 0, - CREATEACCOUNTPAGE, - CREATESIPACCOUNTPAGE, - IMPORTFROMBACKUPPAGE, - BACKUPKEYSPAGE, - IMPORTFROMDEVICEPAGE, - CONNECTTOACCOUNTMANAGERPAGE, - PROFILEPAGE, - CREATERENDEZVOUS - } - - readonly property int layoutSpacing: 12 - readonly property int backButtonMargins: 20 - - property int textFontSize: 9 - property int wizardMode: WizardView.CREATE - property int addedAccountIndex: -1 - property bool isRdv: false - property bool showBackUp: false - property bool showProfile: false - property bool showBottom: false - property string fileToImport: "" - property string registeredName: "" - - property var inputParaObject: ({}) - // signal to redirect the page to main view signal loaderSourceChangeRequested(int sourceToLoad) - signal wizardViewIsClosed - visible: true color: JamiTheme.backgroundColor - Component.onCompleted: { - changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE) - } - Connections{ target: AccountAdapter - enabled: controlPanelStackView.currentIndex !== WizardView.WizardViewPageIndex.WELCOMEPAGE - - function onAccountAdded(accountId, showBackUp, index) { - addedAccountIndex = index - AccountAdapter.changeAccount(index) - if (showProfile) { - changePageQML(WizardView.WizardViewPageIndex.PROFILEPAGE) - profilePage.readyToSaveDetails() - profilePage.isRdv = isRdv - profilePage.createdAccountId = accountId - } else if (controlPanelStackView.currentIndex === WizardView.WizardViewPageIndex.PROFILEPAGE) { - profilePage.readyToSaveDetails() - profilePage.isRdv = isRdv - profilePage.createdAccountId = accountId - } else if (showBackUp) { - changePageQML(WizardView.WizardViewPageIndex.BACKUPKEYSPAGE) - } else { - changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE) - loaderSourceChangeRequested(MainApplicationWindow.LoadedSource.MainView) - } - } - // reportFailure function onReportFailure() { var errorMessage = JamiStrings.errorCreateAccount switch(controlPanelStackView.currentIndex) { - case WizardView.WizardViewPageIndex.IMPORTFROMDEVICEPAGE: + case importFromDevicePage.stackLayoutIndex: importFromDevicePage.errorOccured(errorMessage) break - case WizardView.WizardViewPageIndex.IMPORTFROMBACKUPPAGE: + case importFromBackupPage.stackLayoutIndex: importFromBackupPage.errorOccured(errorMessage) break - case WizardView.WizardViewPageIndex.CONNECTTOACCOUNTMANAGERPAGE: + case connectToAccountManagerPage.stackLayoutIndex: connectToAccountManagerPage.errorOccured(errorMessage) break } } } - function changePageQML(pageIndex) { - controlPanelStackView.currentIndex = pageIndex - if (pageIndex === WizardView.WizardViewPageIndex.WELCOMEPAGE) { - fileToImport = "" - isRdv = false - createAccountPage.nameRegistrationUIState = UsernameLineEdit.NameRegistrationState.BLANK - } else if (pageIndex === WizardView.WizardViewPageIndex.CREATEACCOUNTPAGE) { - createAccountPage.initializeOnShowUp(false) - } else if (pageIndex === WizardView.WizardViewPageIndex.CREATESIPACCOUNTPAGE) { - createSIPAccountPage.initializeOnShowUp() - } else if (pageIndex === WizardView.WizardViewPageIndex.IMPORTFROMDEVICEPAGE) { - importFromDevicePage.initializeOnShowUp() - } else if (pageIndex === WizardView.WizardViewPageIndex.CONNECTTOACCOUNTMANAGERPAGE) { - connectToAccountManagerPage.initializeOnShowUp() - } else if (pageIndex === WizardView.WizardViewPageIndex.IMPORTFROMBACKUPPAGE) { - importFromBackupPage.clearAllTextFields() - fileToImport = "" - } else if (pageIndex === WizardView.WizardViewPageIndex.PROFILEPAGE) { - profilePage.initializeOnShowUp() - profilePage.showBottom = showBottom - } else if (pageIndex === WizardView.WizardViewPageIndex.CREATERENDEZVOUS) { - isRdv = true - controlPanelStackView.currentIndex = WizardView.WizardViewPageIndex.CREATEACCOUNTPAGE - createAccountPage.initializeOnShowUp(true) - } - } - - PasswordDialog { - id: passwordDialog - - visible: false - purpose: PasswordDialog.ExportAccount + Connections { + target: WizardViewStepModel - onDoneSignal: { - if (currentPurpose === passwordDialog.ExportAccount) { - var title = success ? qsTr("Success") : qsTr("Error") - var info = success ? JamiStrings.backupSuccessful : JamiStrings.backupFailed - - AccountAdapter.passwordSetStatusMessageBox(success, - title, info) - if (success) { - console.log("Account Export Succeed") - loaderSourceChangeRequested(MainApplicationWindow.LoadedSource.MainView) - } - } + function onCloseWizardView() { + loaderSourceChangeRequested(MainApplicationWindow.LoadedSource.MainView) } } - MouseArea { - anchors.fill: parent - onClicked: forceActiveFocus() - } - ScrollView { id: wizardViewScrollView @@ -191,36 +85,23 @@ Rectangle { StackLayout { id: controlPanelStackView + function setPage(obj) { + for (var i in this.children) { + if (this.children[i] === obj) { + currentIndex = i + return + } + } + } + anchors.centerIn: parent width: wizardViewScrollView.width - 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) - }) - } - WelcomePage { id: welcomePage - Layout.alignment: Qt.AlignCenter - - onWelcomePageRedirectPage: { - changePageQML(toPageIndex) - } - - onLeavePage: { - wizardViewIsClosed() - } + onShowThisPage: controlPanelStackView.setPage(this) onScrollToBottom: { if (welcomePage.preferredHeight > root.height) @@ -231,172 +112,55 @@ Rectangle { CreateAccountPage { id: createAccountPage - Layout.alignment: Qt.AlignCenter - - onCreateAccount: { - inputParaObject = {} - inputParaObject["isRendezVous"] = isRdv - inputParaObject["password"] = text_passwordEditAlias - AccountAdapter.createJamiAccount( - createAccountPage.text_usernameEditAlias, - inputParaObject, - true) - showBackUp = !isRdv - showBottom = true - changePageQML(WizardView.WizardViewPageIndex.PROFILEPAGE) - } - - onLeavePage: { - changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE) - } + onShowThisPage: controlPanelStackView.setPage(this) } - 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() - } - } - - ImportFromBackupPage { - id: importFromBackupPage - - Layout.alignment: Qt.AlignCenter - - onLeavePage: { - changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE) - } + ProfilePage { + id: profilePage - onImportAccount: { - inputParaObject = {} - inputParaObject["archivePath"] = UtilsAdapter.getAbsPath(importFromBackupPage.filePath) - inputParaObject["password"] = importFromBackupPage.text_passwordFromBackupEditAlias - showBackUp = false - showBottom = false - showProfile = false - AccountAdapter.createJamiAccount( - "", inputParaObject, "", false) - } + onShowThisPage: controlPanelStackView.setPage(this) } 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( - LRCInstance.currentAccountId, - UtilsAdapter.getAbsPath(folderDir)) - } - } - } - - changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE) - loaderSourceChangeRequested(MainApplicationWindow.LoadedSource.MainView) - } - - onLeavePage: { - changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE) - loaderSourceChangeRequested(MainApplicationWindow.LoadedSource.MainView) - } + onShowThisPage: controlPanelStackView.setPage(this) } ImportFromDevicePage { id: importFromDevicePage - Layout.alignment: Qt.AlignCenter - - onLeavePage: { - changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE) - } + onShowThisPage: controlPanelStackView.setPage(this) + } - onImportAccount: { - inputParaObject = {} - inputParaObject["archivePin"] = importFromDevicePage.text_pinFromDeviceAlias - inputParaObject["password"] = importFromDevicePage.text_passwordFromDeviceAlias + ImportFromBackupPage { + id: importFromBackupPage - showProfile = false - showBackUp = false - showBottom = false - AccountAdapter.createJamiAccount( - "", inputParaObject, "", false) - } + onShowThisPage: controlPanelStackView.setPage(this) } ConnectToAccountManagerPage { id: connectToAccountManagerPage - Layout.alignment: Qt.AlignCenter - - onCreateAccount: { - inputParaObject = {} - inputParaObject["username"] - = connectToAccountManagerPage.text_usernameManagerEditAlias - inputParaObject["password"] - = connectToAccountManagerPage.text_passwordManagerEditAlias - inputParaObject["manager"] - = connectToAccountManagerPage.text_accountManagerEditAlias - AccountAdapter.createJAMSAccount(inputParaObject) - } - - onLeavePage: { - changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE) - } + onShowThisPage: controlPanelStackView.setPage(this) } - ProfilePage { - id: profilePage - - Layout.alignment: Qt.AlignCenter - - function leave() { - if (showBackUp) - changePageQML(WizardView.WizardViewPageIndex.BACKUPKEYSPAGE) - else { - changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE) - loaderSourceChangeRequested(MainApplicationWindow.LoadedSource.MainView) - } - - profilePage.initializeOnShowUp() - } + CreateSIPAccountPage { + id: createSIPAccountPage - onSaveProfile: { - AccountAdapter.setCurrAccDisplayName(profilePage.displayName) - leave() - } + onShowThisPage: controlPanelStackView.setPage(this) + } - onLeavePage: leave() + Component.onCompleted: { + // avoid binding loop + height = Qt.binding(function (){ + var index = currentIndex + === WizardViewStepModel.MainSteps.CreateRendezVous ? + WizardViewStepModel.MainSteps.CreateJamiAccount : currentIndex + return Math.max( + controlPanelStackView.itemAt(index).preferredHeight, + wizardViewScrollView.height) + }) } } } diff --git a/src/wizardview/components/BackupKeyPage.qml b/src/wizardview/components/BackupKeyPage.qml index cf69527f3..49fde1695 100644 --- a/src/wizardview/components/BackupKeyPage.qml +++ b/src/wizardview/components/BackupKeyPage.qml @@ -1,6 +1,7 @@ /* - * Copyright (C) 2020 by Savoir-faire Linux + * Copyright (C) 2021 by Savoir-faire Linux * Author: Yang Wang <yang.wang@savoirfairelinux.com> + * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,7 +23,9 @@ import QtQuick.Controls 2.14 import Qt.labs.platform 1.1 import net.jami.Models 1.0 +import net.jami.Adapters 1.0 import net.jami.Constants 1.0 +import net.jami.Enums 1.0 import "../../commoncomponents" import "../../settingsview/components" @@ -32,28 +35,59 @@ Rectangle { property int preferredHeight: backupKeysPageColumnLayout.implicitHeight - signal neverShowAgainBoxClicked(bool isChecked) - signal leavePage - signal export_Btn_FileDialogAccepted(bool accepted, string folderDir) + signal showThisPage + + Connections { + target: WizardViewStepModel + + function onMainStepChanged() { + if (WizardViewStepModel.mainStep === WizardViewStepModel.MainSteps.BackupKeys) + root.showThisPage() + } + } + + PasswordDialog { + id: passwordDialog + + visible: false + purpose: PasswordDialog.ExportAccount + + onDoneSignal: { + var title = success ? JamiStrings.success : JamiStrings.error + var info = success ? JamiStrings.backupSuccessful : JamiStrings.backupFailed + + AccountAdapter.passwordSetStatusMessageBox(success, title, info) + if (success) + loaderSourceChangeRequested(MainApplicationWindow.LoadedSource.MainView) + } + } // JamiFileDialog for exporting account JamiFileDialog { - id: exportBtn_Dialog + id: exportDialog mode: JamiFileDialog.SaveFile title: JamiStrings.backupAccountHere folder: StandardPaths.writableLocation(StandardPaths.HomeLocation) + "/Desktop" - nameFilters: [qsTr("Jami archive files") + " (*.gz)", qsTr( - "All files") + " (*)"] + nameFilters: [JamiStrings.jamiArchiveFiles + " (*.gz)", JamiStrings.allFiles + " (*)"] onAccepted: { - export_Btn_FileDialogAccepted(true, file) - } + // Is there password? If so, go to password dialog, else, go to following directly + if (AccountAdapter.hasPassword()) { + passwordDialog.path = UtilsAdapter.getAbsPath(folder) + passwordDialog.open() + return + } else { + if (folder.length > 0) { + AccountAdapter.exportToFile( + LRCInstance.currentAccountId, + UtilsAdapter.getAbsPath(folder)) + } + } - onRejected: { - export_Btn_FileDialogAccepted(false, folder) + WizardViewStepModel.nextStep() } onVisibleChanged: { @@ -68,16 +102,16 @@ Rectangle { ColumnLayout { id: backupKeysPageColumnLayout - spacing: layoutSpacing + spacing: JamiTheme.wizardViewPageLayoutSpacing anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter RowLayout { - spacing: layoutSpacing + spacing: JamiTheme.wizardViewPageLayoutSpacing Layout.alignment: Qt.AlignCenter - Layout.topMargin: backButtonMargins + Layout.topMargin: JamiTheme.wizardViewPageBackButtonMargins Layout.preferredWidth: backupBtn.width Label { @@ -86,18 +120,10 @@ Rectangle { font.pointSize: JamiTheme.textFontSize + 3 } - Label { + BubbleLabel { Layout.alignment: Qt.AlignRight text: JamiStrings.recommended - color: "white" - padding: 8 - - background: Rectangle { - color: JamiTheme.wizardGreenColor - radius: 24 - anchors.fill: parent - } } } @@ -121,7 +147,7 @@ Rectangle { } RowLayout { - spacing: layoutSpacing + spacing: JamiTheme.wizardViewPageLayoutSpacing Layout.alignment: Qt.AlignCenter @@ -135,9 +161,7 @@ Rectangle { id: passwordSwitch Layout.alignment: Qt.AlignRight - onToggled: { - neverShowAgainBoxClicked(checked) - } + onToggled: AppSettingsManager.setValue(Settings.NeverShowMeAgain, checked) } } @@ -153,15 +177,12 @@ Rectangle { hoveredColor: JamiTheme.buttonTintedGreyHovered pressedColor: JamiTheme.buttonTintedGreyPressed - onClicked: { - exportBtn_Dialog.open() - leavePage() - } + onClicked: exportDialog.open() } MaterialButton { Layout.alignment: Qt.AlignCenter - Layout.bottomMargin: backButtonMargins + Layout.bottomMargin: JamiTheme.wizardViewPageBackButtonMargins Layout.preferredWidth: preferredWidth Layout.preferredHeight: preferredHeight @@ -171,9 +192,7 @@ Rectangle { pressedColor: JamiTheme.buttonTintedGreyPressed outlined: true - onClicked: { - leavePage() - } + onClicked: WizardViewStepModel.nextStep() } } } diff --git a/src/wizardview/components/ConnectToAccountManagerPage.qml b/src/wizardview/components/ConnectToAccountManagerPage.qml index 378821f86..d7dcd89e4 100644 --- a/src/wizardview/components/ConnectToAccountManagerPage.qml +++ b/src/wizardview/components/ConnectToAccountManagerPage.qml @@ -1,6 +1,7 @@ /* - * Copyright (C) 2020 by Savoir-faire Linux + * Copyright (C) 2021 by Savoir-faire Linux * Author: Yang Wang <yang.wang@savoirfairelinux.com> + * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,18 +29,10 @@ import "../../commoncomponents" Rectangle { id: root - property alias text_usernameManagerEditAlias: usernameManagerEdit.text - property alias text_passwordManagerEditAlias: passwordManagerEdit.text - property alias text_accountManagerEditAlias: accountManagerEdit.text - property string errorText: "" property int preferredHeight: connectToAccountManagerPageColumnLayout.implicitHeight + property string errorText: "" - signal leavePage - signal createAccount - - function initializeOnShowUp() { - clearAllTextFields() - } + signal showThisPage function clearAllTextFields() { connectBtn.spinnerTriggered = false @@ -54,6 +47,19 @@ Rectangle { errorText = errorMessage } + Connections { + target: WizardViewStepModel + + function onMainStepChanged() { + if (WizardViewStepModel.mainStep === WizardViewStepModel.MainSteps.AccountCreation && + WizardViewStepModel.accountCreationOption === + WizardViewStepModel.AccountCreationOption.ConnectToAccountManager) { + clearAllTextFields() + root.showThisPage() + } + } + } + color: JamiTheme.backgroundColor onVisibleChanged: { @@ -64,16 +70,16 @@ Rectangle { ColumnLayout { id: connectToAccountManagerPageColumnLayout - spacing: layoutSpacing + spacing: JamiTheme.wizardViewPageLayoutSpacing anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter RowLayout { - spacing: layoutSpacing + spacing: JamiTheme.wizardViewPageLayoutSpacing Layout.alignment: Qt.AlignCenter - Layout.topMargin: backButtonMargins + Layout.topMargin: JamiTheme.wizardViewPageBackButtonMargins Layout.preferredWidth: implicitWidth Label { @@ -82,18 +88,12 @@ Rectangle { font.pointSize: JamiTheme.textFontSize + 3 } - Label { + BubbleLabel { Layout.alignment: Qt.AlignRight text: JamiStrings.required - color: JamiTheme.requiredFieldColor - padding: 8 - - background: Rectangle { - color: JamiTheme.requiredFieldBackgroundColor - radius: 24 - anchors.fill: parent - } + textColor: JamiTheme.requiredFieldColor + bubbleColor: JamiTheme.requiredFieldBackgroundColor } } @@ -106,7 +106,7 @@ Rectangle { selectByMouse: true placeholderText: JamiStrings.jamiManagementServerURL - font.pointSize: 9 + font.pointSize: JamiTheme.textFontSize font.kerning: true borderColorMode: MaterialLineEdit.NORMAL @@ -135,7 +135,7 @@ Rectangle { selectByMouse: true placeholderText: JamiStrings.username - font.pointSize: 9 + font.pointSize: JamiTheme.textFontSize font.kerning: true borderColorMode: MaterialLineEdit.NORMAL @@ -152,7 +152,7 @@ Rectangle { selectByMouse: true placeholderText: JamiStrings.password - font.pointSize: 9 + font.pointSize: JamiTheme.textFontSize font.kerning: true echoMode: TextInput.Password @@ -165,11 +165,11 @@ Rectangle { id: connectBtn Layout.alignment: Qt.AlignCenter - Layout.bottomMargin: errorLabel.visible ? 0 : backButtonMargins + Layout.bottomMargin: errorLabel.visible ? 0 : JamiTheme.wizardViewPageBackButtonMargins Layout.preferredWidth: preferredWidth Layout.preferredHeight: preferredHeight - spinnerTriggeredtext: JamiStrings.generatingAccount + spinnerTriggeredtext: JamiStrings.creatingAccount normalText: JamiStrings.connect enabled: accountManagerEdit.text.length !== 0 @@ -179,7 +179,13 @@ Rectangle { onClicked: { spinnerTriggered = true - createAccount() + + WizardViewStepModel.accountCreationInfo = + JamiQmlUtils.setUpAccountCreationInputPara( + {username : usernameManagerEdit.text, + password : passwordManagerEdit.text, + manager : accountManagerEdit.text}) + WizardViewStepModel.nextStep() } } @@ -187,32 +193,25 @@ Rectangle { id: errorLabel Layout.alignment: Qt.AlignCenter - Layout.bottomMargin: backButtonMargins + Layout.bottomMargin: JamiTheme.wizardViewPageBackButtonMargins visible: errorText.length !== 0 text: errorText font.pointSize: JamiTheme.textFontSize - color: "red" + color: JamiTheme.redColor } } - PushButton { + BackButton { id: backButton anchors.left: parent.left anchors.top: parent.top anchors.margins: 20 - width: 35 - height: 35 - - normalColor: root.color - imageColor: JamiTheme.primaryForegroundColor - - source: JamiResources.ic_arrow_back_24dp_svg - toolTipText: JamiStrings.backToWelcome + preferredSize: JamiTheme.wizardViewPageBackButtonSize - onClicked: leavePage() + onClicked: WizardViewStepModel.previousStep() } } diff --git a/src/wizardview/components/CreateAccountPage.qml b/src/wizardview/components/CreateAccountPage.qml index 0329736b4..9156aceb4 100644 --- a/src/wizardview/components/CreateAccountPage.qml +++ b/src/wizardview/components/CreateAccountPage.qml @@ -1,6 +1,7 @@ /* - * Copyright (C) 2020 by Savoir-faire Linux + * Copyright (C) 2021 by Savoir-faire Linux * Author: Yang Wang <yang.wang@savoirfairelinux.com> + * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,6 +23,7 @@ import QtQuick.Controls 2.14 import Qt.labs.platform 1.1 import net.jami.Models 1.0 +import net.jami.Adapters 1.0 import net.jami.Constants 1.0 import "../" @@ -31,18 +33,14 @@ import "../../settingsview/components" Rectangle { id: root - property alias text_usernameEditAlias: usernameEdit.text - 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 + signal showThisPage function initializeOnShowUp(isRdv) { isRendezVous = isRdv @@ -59,34 +57,18 @@ Rectangle { color: JamiTheme.backgroundColor - onVisibleChanged: { - if (visible && createAccountStack.currentIndex === 0) - usernameEdit.focus = true - } - - // JamiFileDialog for exporting account - JamiFileDialog { - id: exportBtn_Dialog - - mode: JamiFileDialog.SaveFile - - title: JamiStrings.backupAccountHere - folder: StandardPaths.writableLocation(StandardPaths.HomeLocation) + "/Desktop" - - nameFilters: [qsTr("Jami archive files") + " (*.gz)", qsTr( - "All files") + " (*)"] - - onAccepted: { - export_Btn_FileDialogAccepted(true, file) - } - - onRejected: { - export_Btn_FileDialogAccepted(false, folder) - } - - onVisibleChanged: { - if (!visible) { - rejected() + Connections { + target: WizardViewStepModel + + function onMainStepChanged() { + var currentMainStep = WizardViewStepModel.mainStep + if (currentMainStep === WizardViewStepModel.MainSteps.NameRegistration) { + createAccountStack.currentIndex = nameRegistrationPage.stackIndex + initializeOnShowUp(WizardViewStepModel.accountCreationOption === + WizardViewStepModel.AccountCreationOption.CreateRendezVous) + root.showThisPage() + } else if (currentMainStep === WizardViewStepModel.MainSteps.SetPassword) { + createAccountStack.currentIndex = passwordSetupPage.stackIndex } } } @@ -96,45 +78,40 @@ Rectangle { anchors.fill: parent - currentIndex: 0 - Rectangle { + id: nameRegistrationPage + + property int stackIndex: 0 + color: JamiTheme.backgroundColor ColumnLayout { id: usernameColumnLayout - spacing: layoutSpacing + spacing: JamiTheme.wizardViewPageLayoutSpacing anchors.centerIn: parent width: root.width RowLayout { - spacing: layoutSpacing + spacing: JamiTheme.wizardViewPageLayoutSpacing Layout.alignment: Qt.AlignCenter - Layout.topMargin: backButtonMargins + Layout.topMargin: JamiTheme.wizardViewPageBackButtonMargins Layout.preferredWidth: usernameEdit.width Label { - text: isRendezVous ? JamiStrings.chooseNameRV : qsTr("Choose a username for your account") + text: isRendezVous ? JamiStrings.chooseUsernameForRV : + JamiStrings.chooseUsernameForAccount color: JamiTheme.textColor font.pointSize: JamiTheme.textFontSize + 3 } - Label { + BubbleLabel { Layout.alignment: Qt.AlignRight text: JamiStrings.recommended - color: JamiTheme.whiteColor - padding: 8 - - background: Rectangle { - color: JamiTheme.wizardGreenColor - radius: 24 - anchors.fill: parent - } } } @@ -146,7 +123,10 @@ Rectangle { Layout.preferredWidth: chooseUsernameButton.width Layout.alignment: Qt.AlignHCenter - placeholderText: isRendezVous ? qsTr("Choose a name") : qsTr("Choose your username") + focus: visible + + placeholderText: isRendezVous ? JamiStrings.chooseAName : + JamiStrings.chooseYourUserName } Label { @@ -155,19 +135,21 @@ Rectangle { visible: text.length !==0 text: { - switch(nameRegistrationUIState){ + switch(usernameEdit.nameRegistrationState){ 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") + return isRendezVous ? JamiStrings.invalidName : + JamiStrings.invalidUsername case UsernameLineEdit.NameRegistrationState.TAKEN: - return isRendezVous ? qsTr("Name already taken") : qsTr("Username already taken") + return isRendezVous ? JamiStrings.nameAlreadyTaken : + JamiStrings.usernameAlreadyTaken } } font.pointSize: JamiTheme.textFontSize - color: "red" + color: JamiTheme.redColor } MaterialButton { @@ -179,17 +161,14 @@ Rectangle { fontCapitalization: Font.AllUppercase text: isRendezVous ? JamiStrings.chooseName : JamiStrings.chooseUsername - enabled: nameRegistrationUIState === UsernameLineEdit.NameRegistrationState.FREE - color: nameRegistrationUIState === UsernameLineEdit.NameRegistrationState.FREE ? + enabled: usernameEdit.nameRegistrationState === UsernameLineEdit.NameRegistrationState.FREE + color: usernameEdit.nameRegistrationState === UsernameLineEdit.NameRegistrationState.FREE ? JamiTheme.wizardBlueButtons : JamiTheme.buttonTintedGreyInactive hoveredColor: JamiTheme.buttonTintedBlueHovered pressedColor: JamiTheme.buttonTintedBluePressed - onClicked: { - if (nameRegistrationUIState === UsernameLineEdit.NameRegistrationState.FREE) - createAccountStack.currentIndex = createAccountStack.currentIndex + 1 - } + onClicked: WizardViewStepModel.nextStep() } MaterialButton { @@ -207,39 +186,42 @@ Rectangle { onClicked: { usernameEdit.clear() - createAccountStack.currentIndex = - createAccountStack.currentIndex + 1 + WizardViewStepModel.nextStep() } } AccountCreationStepIndicator { - Layout.topMargin: backButtonMargins - Layout.bottomMargin: backButtonMargins + Layout.topMargin: JamiTheme.wizardViewPageBackButtonMargins + Layout.bottomMargin: JamiTheme.wizardViewPageBackButtonMargins Layout.alignment: Qt.AlignHCenter - spacing: layoutSpacing - steps: 3 + spacing: JamiTheme.wizardViewPageLayoutSpacing + steps: 2 currentStep: 1 } } } Rectangle { + id: passwordSetupPage + + property int stackIndex: 1 + color: JamiTheme.backgroundColor ColumnLayout { id: passwordColumnLayout - spacing: layoutSpacing + spacing: JamiTheme.wizardViewPageLayoutSpacing anchors.centerIn: parent width: root.width RowLayout { - spacing: layoutSpacing + spacing: JamiTheme.wizardViewPageLayoutSpacing Layout.alignment: Qt.AlignCenter - Layout.topMargin: backButtonMargins + Layout.topMargin: JamiTheme.wizardViewPageBackButtonMargins Layout.preferredWidth: usernameEdit.width Label { @@ -253,22 +235,15 @@ Rectangle { id: passwordSwitch Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter - Layout.leftMargin: -layoutSpacing + Layout.leftMargin: -JamiTheme.wizardViewPageLayoutSpacing Layout.topMargin: 5 } - Label { + BubbleLabel { Layout.alignment: Qt.AlignRight | Qt.AlignVCenter text: JamiStrings.optional - color: "white" - padding: 8 - - background: Rectangle { - color: JamiTheme.wizardBlueButtons - radius: 24 - anchors.fill: parent - } + bubbleColor: JamiTheme.wizardBlueButtons } } @@ -279,12 +254,13 @@ Rectangle { Layout.preferredWidth: createAccountButton.width Layout.alignment: Qt.AlignHCenter + focus: visible visible: passwordSwitch.checked selectByMouse: true echoMode: TextInput.Password placeholderText: JamiStrings.password - font.pointSize: 9 + font.pointSize: JamiTheme.textFontSize font.kerning: true } @@ -300,7 +276,7 @@ Rectangle { selectByMouse: true echoMode: TextInput.Password placeholderText: JamiStrings.confirmPassword - font.pointSize: 9 + font.pointSize: JamiTheme.textFontSize font.kerning: true } @@ -337,45 +313,38 @@ Rectangle { pressedColor: JamiTheme.buttonTintedBluePressed onClicked: { - createAccount() - createAccountStack.currentIndex += 1 + WizardViewStepModel.accountCreationInfo = + JamiQmlUtils.setUpAccountCreationInputPara( + {isRendezVous : WizardViewStepModel.accountCreationOption === + WizardViewStepModel.AccountCreationOption.CreateRendezVous, + password : passwordEdit.text, + registeredName : usernameEdit.text}) + WizardViewStepModel.nextStep() } } AccountCreationStepIndicator { - Layout.topMargin: backButtonMargins - Layout.bottomMargin: backButtonMargins + Layout.topMargin: JamiTheme.wizardViewPageBackButtonMargins + Layout.bottomMargin: JamiTheme.wizardViewPageBackButtonMargins Layout.alignment: Qt.AlignHCenter - spacing: layoutSpacing - steps: 3 + spacing: JamiTheme.wizardViewPageLayoutSpacing + steps: 2 currentStep: 2 } } } } - PushButton { + BackButton { id: backButton anchors.left: parent.left anchors.top: parent.top - anchors.margins: backButtonMargins + anchors.margins: JamiTheme.wizardViewPageBackButtonMargins - width: 35 - height: 35 + preferredSize: JamiTheme.wizardViewPageBackButtonSize - normalColor: root.color - imageColor: JamiTheme.primaryForegroundColor - - source: JamiResources.ic_arrow_back_24dp_svg - toolTipText: JamiStrings.back - - onClicked: { - if (createAccountStack.currentIndex == 0) - leavePage() - else - createAccountStack.currentIndex -= 1 - } + onClicked: WizardViewStepModel.previousStep() } } diff --git a/src/wizardview/components/CreateSIPAccountPage.qml b/src/wizardview/components/CreateSIPAccountPage.qml index bb3ed416a..c8bdb197d 100644 --- a/src/wizardview/components/CreateSIPAccountPage.qml +++ b/src/wizardview/components/CreateSIPAccountPage.qml @@ -1,6 +1,7 @@ /* - * Copyright (C) 2020 by Savoir-faire Linux + * Copyright (C) 2021 by Savoir-faire Linux * Author: Yang Wang <yang.wang@savoirfairelinux.com> + * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,6 +21,7 @@ import QtQuick 2.14 import QtQuick.Layouts 1.14 import QtQuick.Controls 2.14 +import net.jami.Models 1.0 import net.jami.Constants 1.0 import "../../commoncomponents" @@ -27,18 +29,9 @@ import "../../commoncomponents" Rectangle { id: root - property alias text_sipServernameEditAlias: sipServernameEdit.text - property alias text_sipProxyEditAlias: sipProxyEdit.text - property alias text_sipUsernameEditAlias: sipUsernameEdit.text - property alias text_sipPasswordEditAlias: sipPasswordEdit.text property int preferredHeight: createSIPAccountPageColumnLayout.implicitHeight - signal createAccount - signal leavePage - - function initializeOnShowUp() { - clearAllTextFields() - } + signal showThisPage function clearAllTextFields() { sipUsernameEdit.clear() @@ -48,25 +41,33 @@ Rectangle { sipUsernameEdit.clear() } - color: JamiTheme.backgroundColor + Connections { + target: WizardViewStepModel - onVisibleChanged: { - if (visible) - sipServernameEdit.focus = true + function onMainStepChanged() { + if (WizardViewStepModel.mainStep === WizardViewStepModel.MainSteps.AccountCreation && + WizardViewStepModel.accountCreationOption === + WizardViewStepModel.AccountCreationOption.CreateSipAccount) { + clearAllTextFields() + root.showThisPage() + } + } } + color: JamiTheme.backgroundColor + ColumnLayout { id: createSIPAccountPageColumnLayout - spacing: layoutSpacing + spacing: JamiTheme.wizardViewPageLayoutSpacing anchors.centerIn: parent RowLayout { - spacing: layoutSpacing + spacing: JamiTheme.wizardViewPageLayoutSpacing Layout.alignment: Qt.AlignCenter - Layout.topMargin: backButtonMargins + Layout.topMargin: JamiTheme.wizardViewPageBackButtonMargins Layout.preferredWidth: createAccountButton.width Label { @@ -75,18 +76,11 @@ Rectangle { font.pointSize: JamiTheme.textFontSize + 3 } - Label { + BubbleLabel { Layout.alignment: Qt.AlignRight text: JamiStrings.optional - color: JamiTheme.whiteColor - padding: 8 - - background: Rectangle { - color: JamiTheme.wizardBlueButtons - radius: 24 - anchors.fill: parent - } + bubbleColor: JamiTheme.wizardBlueButtons } } @@ -97,9 +91,11 @@ Rectangle { Layout.preferredHeight: fieldLayoutHeight Layout.preferredWidth: createAccountButton.width + focus: visible + selectByMouse: true placeholderText: JamiStrings.server - font.pointSize: 9 + font.pointSize: JamiTheme.textFontSize font.kerning: true } @@ -112,7 +108,7 @@ Rectangle { selectByMouse: true placeholderText: JamiStrings.proxy - font.pointSize: 9 + font.pointSize: JamiTheme.textFontSize font.kerning: true } @@ -125,7 +121,7 @@ Rectangle { selectByMouse: true placeholderText: JamiStrings.username - font.pointSize: 9 + font.pointSize: JamiTheme.textFontSize font.kerning: true } @@ -139,7 +135,7 @@ Rectangle { selectByMouse: true echoMode: TextInput.Password placeholderText: JamiStrings.password - font.pointSize: 9 + font.pointSize: JamiTheme.textFontSize font.kerning: true } @@ -147,7 +143,7 @@ Rectangle { id: createAccountButton Layout.alignment: Qt.AlignCenter - Layout.bottomMargin: backButtonMargins + Layout.bottomMargin: JamiTheme.wizardViewPageBackButtonMargins Layout.preferredWidth: preferredWidth Layout.preferredHeight: preferredHeight @@ -157,27 +153,26 @@ Rectangle { pressedColor: JamiTheme.buttonTintedBluePressed onClicked: { - createAccount() + WizardViewStepModel.accountCreationInfo = + JamiQmlUtils.setUpAccountCreationInputPara( + {hostname : sipServernameEdit.text, + username : sipUsernameEdit.text, + password : sipPasswordEdit.text, + proxy : sipProxyEdit.text}) + WizardViewStepModel.nextStep() } } } - PushButton { + BackButton { id: backButton anchors.left: parent.left anchors.top: parent.top anchors.margins: 20 - width: 35 - height: 35 - - normalColor: root.color - imageColor: JamiTheme.primaryForegroundColor - - source: JamiResources.ic_arrow_back_24dp_svg - toolTipText: JamiStrings.backToWelcome + preferredSize: JamiTheme.wizardViewPageBackButtonSize - onClicked: leavePage() + onClicked: WizardViewStepModel.previousStep() } } diff --git a/src/wizardview/components/ImportFromBackupPage.qml b/src/wizardview/components/ImportFromBackupPage.qml index a7e5f67e3..d53d50809 100644 --- a/src/wizardview/components/ImportFromBackupPage.qml +++ b/src/wizardview/components/ImportFromBackupPage.qml @@ -1,6 +1,7 @@ /* - * Copyright (C) 2020 by Savoir-faire Linux + * Copyright (C) 2021 by Savoir-faire Linux * Author: Yang Wang <yang.wang@savoirfairelinux.com> + * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,15 +31,13 @@ import "../../commoncomponents" Rectangle { id: root - property alias text_passwordFromBackupEditAlias: passwordFromBackupEdit.text - property string fileImportBtnText: JamiStrings.archive property int preferredHeight: importFromBackupPageColumnLayout.implicitHeight + property string fileImportBtnText: JamiStrings.archive property string filePath: "" property string errorText: "" - signal leavePage - signal importAccount + signal showThisPage function clearAllTextFields() { connectBtn.spinnerTriggered = false @@ -52,16 +51,29 @@ Rectangle { connectBtn.spinnerTriggered = false } + Connections { + target: WizardViewStepModel + + function onMainStepChanged() { + if (WizardViewStepModel.mainStep === WizardViewStepModel.MainSteps.AccountCreation && + WizardViewStepModel.accountCreationOption === + WizardViewStepModel.AccountCreationOption.ImportFromBackup) { + clearAllTextFields() + root.showThisPage() + } + } + } + color: JamiTheme.backgroundColor JamiFileDialog { - id: importFromFile_Dialog + id: importFromFileDialog mode: JamiFileDialog.OpenFile title: JamiStrings.openFile folder: StandardPaths.writableLocation(StandardPaths.HomeLocation) + "/Desktop" - nameFilters: [qsTr("Jami archive files") + " (*.gz)", qsTr("All files") + " (*)"] + nameFilters: [JamiStrings.jamiArchiveFiles + " (*.gz)", JamiStrings.allFiles + " (*)"] onAccepted: { filePath = file @@ -76,16 +88,16 @@ Rectangle { ColumnLayout { id: importFromBackupPageColumnLayout - spacing: layoutSpacing + spacing: JamiTheme.wizardViewPageLayoutSpacing anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter Text { Layout.alignment: Qt.AlignCenter - Layout.topMargin: backButtonMargins + Layout.topMargin: JamiTheme.wizardViewPageBackButtonMargins - text: qsTr("Import from backup") + text: JamiStrings.importFromBackup color: JamiTheme.textColor font.pointSize: JamiTheme.menuFontSize } @@ -106,14 +118,14 @@ Rectangle { onClicked: { errorText = "" - importFromFile_Dialog.open() + importFromFileDialog.open() } } Text { // For multiline text, recursive rearrange warning will show up when // directly assigning contentHeight to Layout.preferredHeight - property int preferredHeight: layoutSpacing + property int preferredHeight: JamiTheme.wizardViewPageLayoutSpacing Layout.alignment: Qt.AlignCenter Layout.preferredWidth: fileImportBtn.width @@ -137,9 +149,11 @@ Rectangle { Layout.preferredWidth: connectBtn.width Layout.alignment: Qt.AlignCenter + focus: visible + selectByMouse: true - placeholderText: qsTr("Password") - font.pointSize: 9 + placeholderText: JamiStrings.password + font.pointSize: JamiTheme.textFontSize font.kerning: true echoMode: TextInput.Password @@ -152,11 +166,11 @@ Rectangle { id: connectBtn Layout.alignment: Qt.AlignCenter - Layout.bottomMargin: errorLabel.visible ? 0 : backButtonMargins + Layout.bottomMargin: errorLabel.visible ? 0 : JamiTheme.wizardViewPageBackButtonMargins Layout.preferredWidth: preferredWidth Layout.preferredHeight: preferredHeight - spinnerTriggeredtext: qsTr("Generating account…") + spinnerTriggeredtext: JamiStrings.generatingAccount normalText: JamiStrings.connectFromBackup enabled: { @@ -169,7 +183,12 @@ Rectangle { onClicked: { spinnerTriggered = true - importAccount() + + WizardViewStepModel.accountCreationInfo = + JamiQmlUtils.setUpAccountCreationInputPara( + {archivePath : UtilsAdapter.getAbsPath(filePath), + password : passwordFromBackupEdit.text}) + WizardViewStepModel.nextStep() } } @@ -177,32 +196,25 @@ Rectangle { id: errorLabel Layout.alignment: Qt.AlignCenter - Layout.bottomMargin: backButtonMargins + Layout.bottomMargin: JamiTheme.wizardViewPageBackButtonMargins visible: errorText.length !== 0 text: errorText font.pointSize: JamiTheme.textFontSize - color: "red" + color: JamiTheme.redColor } } - PushButton { + BackButton { id: backButton anchors.left: parent.left anchors.top: parent.top anchors.margins: 20 - width: 35 - height: 35 - - normalColor: root.color - imageColor: JamiTheme.primaryForegroundColor - - source: JamiResources.ic_arrow_back_24dp_svg - toolTipText: qsTr("Back to welcome page") + preferredSize: JamiTheme.wizardViewPageBackButtonSize - onClicked: leavePage() + onClicked: WizardViewStepModel.previousStep() } } diff --git a/src/wizardview/components/ImportFromDevicePage.qml b/src/wizardview/components/ImportFromDevicePage.qml index 2c26e271d..c6feb9f31 100644 --- a/src/wizardview/components/ImportFromDevicePage.qml +++ b/src/wizardview/components/ImportFromDevicePage.qml @@ -1,6 +1,7 @@ /* - * Copyright (C) 2020 by Savoir-faire Linux + * Copyright (C) 2021 by Savoir-faire Linux * Author: Yang Wang <yang.wang@savoirfairelinux.com> + * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,13 +29,10 @@ import "../../commoncomponents" Rectangle { id: root - property alias text_pinFromDeviceAlias: pinFromDevice.text - property alias text_passwordFromDeviceAlias: passwordFromDevice.text property string errorText: "" property int preferredHeight: importFromDevicePageColumnLayout.implicitHeight - signal leavePage - signal importAccount + signal showThisPage function initializeOnShowUp() { clearAllTextFields() @@ -51,17 +49,23 @@ Rectangle { connectBtn.spinnerTriggered = false } - color: JamiTheme.backgroundColor + Connections { + target: WizardViewStepModel - onVisibleChanged: { - if (visible) - pinFromDevice.focus = true + function onMainStepChanged() { + if (WizardViewStepModel.mainStep === WizardViewStepModel.MainSteps.AccountCreation && + WizardViewStepModel.accountCreationOption === + WizardViewStepModel.AccountCreationOption.ImportFromDevice) + root.showThisPage() + } } + color: JamiTheme.backgroundColor + ColumnLayout { id: importFromDevicePageColumnLayout - spacing: layoutSpacing + spacing: JamiTheme.wizardViewPageLayoutSpacing // Prevent possible anchor loop detected on centerIn. anchors.horizontalCenter: parent.horizontalCenter @@ -69,7 +73,7 @@ Rectangle { Text { Layout.alignment: Qt.AlignCenter - Layout.topMargin: backButtonMargins + Layout.topMargin: JamiTheme.wizardViewPageBackButtonMargins text: JamiStrings.mainAccountPassword color: JamiTheme.textColor @@ -84,8 +88,8 @@ Rectangle { Layout.alignment: Qt.AlignCenter selectByMouse: true - placeholderText: qsTr("Password") - font.pointSize: 9 + placeholderText: JamiStrings.password + font.pointSize: JamiTheme.textFontSize font.kerning: true echoMode: TextInput.Password @@ -95,7 +99,8 @@ Rectangle { } Text { - property int preferredHeight: layoutSpacing + property int preferredHeight: JamiTheme.wizardViewPageLayoutSpacing + Layout.alignment: Qt.AlignCenter Layout.preferredWidth: connectBtn.width @@ -119,9 +124,11 @@ Rectangle { Layout.preferredWidth: connectBtn.width Layout.alignment: Qt.AlignCenter + focus: visible + selectByMouse: true - placeholderText: qsTr("PIN") - font.pointSize: 9 + placeholderText: JamiStrings.pin + font.pointSize: JamiTheme.textFontSize font.kerning: true borderColorMode: MaterialLineEdit.NORMAL @@ -133,18 +140,23 @@ Rectangle { id: connectBtn Layout.alignment: Qt.AlignCenter - Layout.bottomMargin: errorLabel.visible ? 0 : backButtonMargins + Layout.bottomMargin: errorLabel.visible ? 0 : JamiTheme.wizardViewPageBackButtonMargins Layout.preferredWidth: preferredWidth Layout.preferredHeight: preferredHeight - spinnerTriggeredtext: qsTr("Generating account…") + spinnerTriggeredtext: JamiStrings.generatingAccount normalText: JamiStrings.connectFromAnotherDevice enabled: pinFromDevice.text.length !== 0 && !spinnerTriggered onClicked: { spinnerTriggered = true - importAccount() + + WizardViewStepModel.accountCreationInfo = + JamiQmlUtils.setUpAccountCreationInputPara( + {archivePin : pinFromDevice.text, + password : passwordFromDevice.text}) + WizardViewStepModel.nextStep() } } @@ -152,33 +164,26 @@ Rectangle { id: errorLabel Layout.alignment: Qt.AlignCenter - Layout.bottomMargin: backButtonMargins + Layout.bottomMargin: JamiTheme.wizardViewPageBackButtonMargins visible: errorText.length !== 0 text: errorText font.pointSize: JamiTheme.textFontSize - color: "red" + color: JamiTheme.redColor } } - PushButton { + BackButton { id: backButton anchors.left: parent.left anchors.top: parent.top anchors.margins: 20 - width: 35 - height: 35 - - normalColor: root.color - imageColor: JamiTheme.primaryForegroundColor - - source: JamiResources.ic_arrow_back_24dp_svg - toolTipText: qsTr("Back to welcome page") + preferredSize: JamiTheme.wizardViewPageBackButtonSize - onClicked: leavePage() + onClicked: WizardViewStepModel.previousStep() } } diff --git a/src/wizardview/components/ProfilePage.qml b/src/wizardview/components/ProfilePage.qml index a92c16f83..e02be77d3 100644 --- a/src/wizardview/components/ProfilePage.qml +++ b/src/wizardview/components/ProfilePage.qml @@ -1,6 +1,7 @@ /* - * Copyright (C) 2020 by Savoir-faire Linux + * Copyright (C) 2021 by Savoir-faire Linux * Author: Yang Wang <yang.wang@savoirfairelinux.com> + * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,6 +24,7 @@ import QtQuick.Controls 2.14 import net.jami.Adapters 1.0 import net.jami.Constants 1.0 import net.jami.Helpers 1.0 +import net.jami.Models 1.0 import "../../commoncomponents" @@ -32,13 +34,8 @@ Rectangle { // trigger a default avatar prior to account generation property string createdAccountId: "dummy" property int preferredHeight: profilePageColumnLayout.implicitHeight - property bool showBottom: false - property alias displayName: aliasEdit.text - property bool isRdv: false - property alias avatarBooth: setAvatarWidget - signal leavePage - signal saveProfile + signal showThisPage function initializeOnShowUp() { createdAccountId = "dummy" @@ -50,46 +47,52 @@ Rectangle { aliasEdit.clear() } - function readyToSaveDetails() { - saveProfileBtn.spinnerTriggered = false - } - color: JamiTheme.backgroundColor + Connections { + target: WizardViewStepModel + + function onMainStepChanged() { + if (WizardViewStepModel.mainStep === WizardViewStepModel.MainSteps.Profile) { + initializeOnShowUp() + root.showThisPage() + } + } + + function onAccountIsReady(accountId) { + saveProfileBtn.spinnerTriggered = false + createdAccountId = accountId + aliasEdit.forceActiveFocus() + } + } + ColumnLayout { id: profilePageColumnLayout - spacing: layoutSpacing + spacing: JamiTheme.wizardViewPageLayoutSpacing width: parent.width anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter RowLayout { - spacing: layoutSpacing + spacing: JamiTheme.wizardViewPageLayoutSpacing - Layout.topMargin: backButtonMargins + Layout.topMargin: JamiTheme.wizardViewPageBackButtonMargins Layout.preferredWidth: saveProfileBtn.width Layout.alignment: Qt.AlignCenter Label { - text: qsTr("Profile is only shared with contacts") + text: JamiStrings.profileSharedWithContacts color: JamiTheme.textColor font.pointSize: JamiTheme.textFontSize + 3 } - Label { + BubbleLabel { Layout.alignment: Qt.AlignRight - text: qsTr("Optional") - color: JamiTheme.whiteColor - padding: 8 - - background: Rectangle { - color: JamiTheme.wizardBlueButtons - radius: 24 - anchors.fill: parent - } + text: JamiStrings.optional + bubbleColor: JamiTheme.wizardBlueButtons } } @@ -116,9 +119,17 @@ Rectangle { Layout.preferredWidth: fieldLayoutWidth Layout.alignment: Qt.AlignCenter + focus: visible + selectByMouse: true - placeholderText: isRdv ? JamiStrings.enterRVName : qsTr("Enter your name") - font.pointSize: 9 + placeholderText: { + if (WizardViewStepModel.accountCreationOption !== + WizardViewStepModel.AccountCreationOption.CreateRendezVous) + return JamiStrings.enterYourName + else + return JamiStrings.enterRVName + } + font.pointSize: JamiTheme.textFontSize font.kerning: true borderColorMode: MaterialLineEdit.NORMAL @@ -147,8 +158,18 @@ Rectangle { enabled: !spinnerTriggered normalText: JamiStrings.saveProfile - spinnerTriggeredtext: root.isRdv ? JamiStrings.generatingRV : qsTr("Generating account…") - onClicked: saveProfile() + spinnerTriggeredtext: { + if (WizardViewStepModel.accountCreationOption === + WizardViewStepModel.AccountCreationOption.CreateRendezVous) + return JamiStrings.generatingRV + else + return JamiStrings.creatingAccount + } + + onClicked: { + AccountAdapter.setCurrAccDisplayName(aliasEdit.text) + WizardViewStepModel.nextStep() + } } MaterialButton { @@ -166,18 +187,8 @@ Rectangle { onClicked: { AccountAdapter.setCurrentAccountAvatarBase64() aliasEdit.clear() - saveProfile() + WizardViewStepModel.nextStep() } } - - AccountCreationStepIndicator { - Layout.topMargin: backButtonMargins - Layout.bottomMargin: backButtonMargins - Layout.alignment: Qt.AlignHCenter - - spacing: layoutSpacing - steps: 3 - currentStep: 3 - } } } diff --git a/src/wizardview/components/WelcomePage.qml b/src/wizardview/components/WelcomePage.qml index 7338c77d4..197efdeb9 100644 --- a/src/wizardview/components/WelcomePage.qml +++ b/src/wizardview/components/WelcomePage.qml @@ -1,7 +1,8 @@ /* - * Copyright (C) 2020 by Savoir-faire Linux + * Copyright (C) 2021 by Savoir-faire Linux * Author: Yang Wang <yang.wang@savoirfairelinux.com> * Author: Sébastien blin <sebastien.blin@savoirfairelinux.com> + * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,32 +34,40 @@ Rectangle { property int preferredHeight: welcomePageColumnLayout.implicitHeight - signal welcomePageRedirectPage(int toPageIndex) - signal leavePage signal scrollToBottom + signal showThisPage - color: "transparent" + color: JamiTheme.transparentColor + + Connections { + target: WizardViewStepModel + + function onMainStepChanged() { + if (WizardViewStepModel.mainStep === WizardViewStepModel.MainSteps.Initial) + root.showThisPage() + } + } ColumnLayout { id: welcomePageColumnLayout anchors.centerIn: parent - spacing: layoutSpacing + spacing: JamiTheme.wizardViewPageLayoutSpacing Text { id: welcomeLabel Layout.alignment: Qt.AlignCenter - Layout.topMargin: backButtonMargins + Layout.topMargin: JamiTheme.wizardViewPageBackButtonMargins Layout.preferredHeight: contentHeight - text: qsTr("Welcome to") + text: JamiStrings.welcomeTo color: JamiTheme.textColor horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter - font.pointSize: 30 + font.pointSize: JamiTheme.welcomeLabelPointSize font.kerning: true } @@ -66,8 +75,8 @@ Rectangle { id: welcomeLogo Layout.alignment: Qt.AlignCenter - Layout.preferredWidth: 330 - Layout.preferredHeight: 110 + Layout.preferredWidth: JamiTheme.welcomeLogoWidth + Layout.preferredHeight: JamiTheme.welcomeLogoHeight source: JamiTheme.darkTheme ? JamiResources.logo_jami_standard_coul_white_svg : @@ -81,17 +90,16 @@ Rectangle { Layout.preferredWidth: preferredWidth Layout.preferredHeight: preferredHeight - text: JamiStrings.createNewJA + text: JamiStrings.createAJamiAccount fontCapitalization: Font.AllUppercase - toolTipText: qsTr("Create new Jami account") + toolTipText: JamiStrings.createNewJamiAccount source: JamiResources.default_avatar_overlay_svg color: JamiTheme.buttonTintedBlue hoveredColor: JamiTheme.buttonTintedBlueHovered pressedColor: JamiTheme.buttonTintedBluePressed - onClicked: { - welcomePageRedirectPage(1) - } + onClicked: WizardViewStepModel.startAccountCreationFlow( + WizardViewStepModel.AccountCreationOption.CreateJamiAccount) } MaterialButton { @@ -109,9 +117,8 @@ Rectangle { hoveredColor: JamiTheme.buttonTintedBlueHovered pressedColor: JamiTheme.buttonTintedBluePressed - onClicked: { - welcomePageRedirectPage(8) - } + onClicked: WizardViewStepModel.startAccountCreationFlow( + WizardViewStepModel.AccountCreationOption.CreateRendezVous) } MaterialButton { @@ -123,15 +130,14 @@ Rectangle { text: JamiStrings.linkFromAnotherDevice fontCapitalization: Font.AllUppercase - toolTipText: qsTr("Import account from other device") + toolTipText: JamiStrings.importAccountFromOtherDevice source: JamiResources.devices_24dp_svg color: JamiTheme.buttonTintedBlue hoveredColor: JamiTheme.buttonTintedBlueHovered pressedColor: JamiTheme.buttonTintedBluePressed - onClicked: { - welcomePageRedirectPage(5) - } + onClicked: WizardViewStepModel.startAccountCreationFlow( + WizardViewStepModel.AccountCreationOption.ImportFromDevice) } MaterialButton { @@ -143,22 +149,22 @@ Rectangle { text: JamiStrings.connectFromBackup fontCapitalization: Font.AllUppercase - toolTipText: qsTr("Import account from backup file") + toolTipText: JamiStrings.importAccountFromBackup source: JamiResources.backup_24dp_svg color: JamiTheme.buttonTintedBlue hoveredColor: JamiTheme.buttonTintedBlueHovered pressedColor: JamiTheme.buttonTintedBluePressed - onClicked: { - welcomePageRedirectPage(3) - } + onClicked: WizardViewStepModel.startAccountCreationFlow( + WizardViewStepModel.AccountCreationOption.ImportFromBackup) } MaterialButton { id: showAdvancedButton Layout.alignment: Qt.AlignCenter - Layout.bottomMargin: newSIPAccountButton.visible ? 0 : backButtonMargins + Layout.bottomMargin: newSIPAccountButton.visible ? + 0 : JamiTheme.wizardViewPageBackButtonMargins Layout.preferredWidth: preferredWidth Layout.preferredHeight: preferredHeight @@ -172,10 +178,6 @@ Rectangle { hoverEnabled: true - ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval - ToolTip.visible: hovered - ToolTip.text: JamiStrings.showAdvancedFeatures - onClicked: { connectAccountManagerButton.visible = !connectAccountManagerButton.visible newSIPAccountButton.visible = !newSIPAccountButton.visible @@ -199,16 +201,15 @@ Rectangle { hoveredColor: JamiTheme.buttonTintedBlueHovered pressedColor: JamiTheme.buttonTintedBluePressed - onClicked: { - welcomePageRedirectPage(6) - } + onClicked: WizardViewStepModel.startAccountCreationFlow( + WizardViewStepModel.AccountCreationOption.ConnectToAccountManager) } MaterialButton { id: newSIPAccountButton Layout.alignment: Qt.AlignCenter - Layout.bottomMargin: backButtonMargins + Layout.bottomMargin: JamiTheme.wizardViewPageBackButtonMargins Layout.preferredWidth: preferredWidth Layout.preferredHeight: preferredHeight @@ -216,26 +217,25 @@ Rectangle { text: JamiStrings.addSIPAccount fontCapitalization: Font.AllUppercase - toolTipText: qsTr("Create new SIP account") + toolTipText: JamiStrings.createNewSipAccount source: JamiResources.default_avatar_overlay_svg color: JamiTheme.buttonTintedBlue hoveredColor: JamiTheme.buttonTintedBlueHovered pressedColor: JamiTheme.buttonTintedBluePressed - onClicked: { - welcomePageRedirectPage(2) - } + onClicked: WizardViewStepModel.startAccountCreationFlow( + WizardViewStepModel.AccountCreationOption.CreateSipAccount) } onHeightChanged: scrollToBottom() } - PushButton { + BackButton { id: backButton anchors.left: parent.left anchors.top: parent.top - anchors.margins: backButtonMargins + anchors.margins: JamiTheme.wizardViewPageBackButtonMargins Connections { target: LRCInstance @@ -245,17 +245,10 @@ Rectangle { } } - width: 35 - height: 35 + preferredSize: JamiTheme.wizardViewPageBackButtonSize visible: UtilsAdapter.getAccountListSize() - normalColor: root.color - imageColor: JamiTheme.primaryForegroundColor - - source: JamiResources.ic_arrow_back_24dp_svg - toolTipText: JamiStrings.back - - onClicked: leavePage() + onClicked: WizardViewStepModel.previousStep() } } diff --git a/src/wizardviewstepmodel.cpp b/src/wizardviewstepmodel.cpp new file mode 100644 index 000000000..7efe12e59 --- /dev/null +++ b/src/wizardviewstepmodel.cpp @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2021 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 <http://www.gnu.org/licenses/>. + */ + +#include "wizardviewstepmodel.h" + +#include "accountadapter.h" +#include "appsettingsmanager.h" + +WizardViewStepModel::WizardViewStepModel(LRCInstance* lrcInstance, + AccountAdapter* accountAdapter, + AppSettingsManager* appSettingsManager, + QObject* parent) + : QObject(parent) + , lrcInstance_(lrcInstance) + , accountAdapter_(accountAdapter) + , appSettingsManager_(appSettingsManager) +{ + reset(); + + connect(accountAdapter_, &AccountAdapter::accountAdded, [this](QString accountId, int index) { + accountAdapter_->changeAccount(index); + + auto accountCreationOption = get_accountCreationOption(); + if (accountCreationOption == AccountCreationOption::ConnectToAccountManager + || accountCreationOption == AccountCreationOption::ImportFromBackup + || accountCreationOption == AccountCreationOption::ImportFromDevice) + set_mainStep(MainSteps::Profile); + + Q_EMIT accountIsReady(accountId); + }); +} + +void +WizardViewStepModel::startAccountCreationFlow(AccountCreationOption accountCreationOption) +{ + set_accountCreationOption(accountCreationOption); + if (accountCreationOption == AccountCreationOption::CreateJamiAccount + || accountCreationOption == AccountCreationOption::CreateRendezVous) + set_mainStep(MainSteps::NameRegistration); + else + set_mainStep(MainSteps::AccountCreation); +} + +void +WizardViewStepModel::nextStep() +{ + auto accountCreationOption = get_accountCreationOption(); + if (accountCreationOption == AccountCreationOption::None) + return; + + switch (get_mainStep()) { + case MainSteps::AccountCreation: { + switch (get_accountCreationOption()) { + case AccountCreationOption::ImportFromBackup: + case AccountCreationOption::ImportFromDevice: { + accountAdapter_->createJamiAccount("", get_accountCreationInfo(), false); + break; + } + case AccountCreationOption::ConnectToAccountManager: { + accountAdapter_->createJAMSAccount(get_accountCreationInfo()); + break; + } + case AccountCreationOption::CreateSipAccount: { + set_mainStep(MainSteps::Profile); + accountAdapter_->createSIPAccount(get_accountCreationInfo()); + break; + } + } + break; + } + case MainSteps::NameRegistration: { + set_mainStep(MainSteps::SetPassword); + break; + } + case MainSteps::SetPassword: { + set_mainStep(MainSteps::Profile); + + auto accountCreationInfo = get_accountCreationInfo(); + accountAdapter_->createJamiAccount(accountCreationInfo["registeredName"].toString(), + accountCreationInfo, + true); + break; + } + case MainSteps::Profile: { + auto showBackup = (accountCreationOption == AccountCreationOption::CreateJamiAccount + || accountCreationOption == AccountCreationOption::CreateRendezVous) + && !appSettingsManager_->getValue(Settings::Key::NeverShowMeAgain).toBool(); + if (showBackup) + set_mainStep(MainSteps::BackupKeys); + else { + Q_EMIT closeWizardView(); + reset(); + } + break; + } + case MainSteps::BackupKeys: { + Q_EMIT closeWizardView(); + reset(); + break; + } + } +} + +void +WizardViewStepModel::previousStep() +{ + switch (get_mainStep()) { + case MainSteps::Initial: { + Q_EMIT closeWizardView(); + break; + } + case MainSteps::AccountCreation: + case MainSteps::NameRegistration: { + reset(); + break; + } + case MainSteps::SetPassword: { + set_mainStep(MainSteps::NameRegistration); + break; + } + } +} + +void +WizardViewStepModel::reset() +{ + set_accountCreationOption(AccountCreationOption::None); + set_mainStep(MainSteps::Initial); +} diff --git a/src/wizardviewstepmodel.h b/src/wizardviewstepmodel.h new file mode 100644 index 000000000..54765057c --- /dev/null +++ b/src/wizardviewstepmodel.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2021 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 <http://www.gnu.org/licenses/>. + */ + +#pragma once + +#include <QObject> +#include <QVariant> +#include <QMap> + +#include "qtutils.h" + +class AccountAdapter; +class LRCInstance; +class AppSettingsManager; + +class WizardViewStepModel : public QObject +{ + Q_OBJECT + Q_CLASSINFO("RegisterEnumClassesUnscoped", "false") + +public: + enum class MainSteps { + Initial, // Initial welcome step. + AccountCreation, // General account creation step. + NameRegistration, // Name registration step : CreateJamiAccount, CreateRendezVous + SetPassword, // Password set up step: CreateJamiAccount, CreateRendezVous + Profile, // Profile set up. + BackupKeys // Backup set up. + }; + Q_ENUM(MainSteps) + + enum class AccountCreationOption { + None, + CreateJamiAccount, // Jami account creation. + CreateRendezVous, // Jami rendezvous account creation. + ImportFromDevice, // Jami account creation from device. + ImportFromBackup, // Jami account creation from backup. + ConnectToAccountManager, // Account manager creation. + CreateSipAccount // SIP account creation. + }; + Q_ENUM(AccountCreationOption) + + QML_PROPERTY(MainSteps, mainStep) + QML_PROPERTY(AccountCreationOption, accountCreationOption) + + QML_PROPERTY(QVariantMap, accountCreationInfo) + +public: + explicit WizardViewStepModel(LRCInstance* lrcInstance, + AccountAdapter* accountAdapter, + AppSettingsManager* appSettingsManager, + QObject* parent = nullptr); + + Q_INVOKABLE void startAccountCreationFlow(AccountCreationOption accountCreationOption); + Q_INVOKABLE void nextStep(); + Q_INVOKABLE void previousStep(); + +Q_SIGNALS: + void accountIsReady(QString accountId); + void closeWizardView(); + +private: + void reset(); + + LRCInstance* lrcInstance_; + AccountAdapter* accountAdapter_; + AppSettingsManager* appSettingsManager_; +}; -- GitLab