From 2e0e250a2c53b7e307ba9a3caa89ef76b6d19e22 Mon Sep 17 00:00:00 2001 From: Ming Rui Zhang Date: Fri, 4 Sep 2020 14:57:36 -0400 Subject: [PATCH] wizardview: logic refinement for account creation and minor UI changes 1. Add spinner button and logic when waitting for account created to prevent reclicking the buttons 2. Add back button when creating accounts in main view. 3. Fix the look up username bug 4. Change some buttons to blue styled 5. Change back button to back arrow 6. Add autofocus when entering certain page Gitlab: #59 Change-Id: I3cada8c07a6605f091001db75a2913cde379c41b --- qml.qrc | 2 +- src/accountadapter.cpp | 6 +- src/commoncomponents/MaterialButton.qml | 20 +++ src/commoncomponents/MaterialLineEdit.qml | 104 +++++++---- src/commoncomponents/SpinnerButton.qml | 37 ++++ src/settingsview/SettingsView.qml | 10 +- src/wizardview/WizardView.qml | 163 +++++++----------- .../ConnectToAccountManagerPage.qml | 67 ++++--- .../components/CreateAccountPage.qml | 106 ++++++------ .../components/CreateSIPAccountPage.qml | 40 +++-- .../components/ImportFromBackupPage.qml | 73 +++++--- .../components/ImportFromDevicePage.qml | 64 ++++--- src/wizardview/components/ProfilePage.qml | 21 ++- src/wizardview/components/SpinnerPage.qml | 110 ------------ src/wizardview/components/WelcomePage.qml | 56 ++++-- 15 files changed, 469 insertions(+), 410 deletions(-) create mode 100644 src/commoncomponents/SpinnerButton.qml delete mode 100644 src/wizardview/components/SpinnerPage.qml diff --git a/qml.qrc b/qml.qrc index 6a45fb22..fcc6b2d3 100644 --- a/qml.qrc +++ b/qml.qrc @@ -45,7 +45,6 @@ src/wizardview/components/BackupKeyPage.qml src/wizardview/components/ImportFromDevicePage.qml src/wizardview/components/ConnectToAccountManagerPage.qml - src/wizardview/components/SpinnerPage.qml src/wizardview/components/ProfilePage.qml src/wizardview/components/CollapsiblePasswordWidget.qml src/MainApplicationWindow.qml @@ -111,5 +110,6 @@ src/commoncomponents/Scaffold.qml src/constant/JamiQmlUtils.qml src/wizardview/components/AccountCreationStepIndicator.qml + src/commoncomponents/SpinnerButton.qml diff --git a/src/accountadapter.cpp b/src/accountadapter.cpp index d924bff9..723db1e9 100644 --- a/src/accountadapter.cpp +++ b/src/accountadapter.cpp @@ -86,6 +86,7 @@ AccountAdapter::createJamiAccount(QString registeredName, Utils::oneShotConnect(&LRCInstance::accountModel(), &lrc::api::NewAccountModel::nameRegistrationEnded, [this, showBackup](const QString &accountId) { + emit LRCInstance::instance().accountListChanged(); emit accountAdded(showBackup, LRCInstance::accountModel() .getAccountList() @@ -95,6 +96,7 @@ AccountAdapter::createJamiAccount(QString registeredName, settings["password"].toString(), registeredName); } else { + emit LRCInstance::instance().accountListChanged(); emit accountAdded(showBackup, LRCInstance::accountModel().getAccountList().indexOf(accountId)); } @@ -152,6 +154,7 @@ AccountAdapter::createSIPAccount(const QVariantMap &settings, QString photoBooth accountId); } + emit LRCInstance::instance().accountListChanged(); emit accountAdded(false, LRCInstance::accountModel().getAccountList().indexOf( accountId)); @@ -171,8 +174,6 @@ AccountAdapter::createSIPAccount(const QVariantMap &settings, QString photoBooth "", settings["username"].toString(), additionalAccountConfig); - QThread::sleep(2); - emit LRCInstance::instance().accountListChanged(); }); } @@ -209,6 +210,7 @@ void AccountAdapter::deleteCurrentAccount() { LRCInstance::accountModel().removeAccount(LRCInstance::getCurrAccId()); + emit LRCInstance::instance().accountListChanged(); } bool diff --git a/src/commoncomponents/MaterialButton.qml b/src/commoncomponents/MaterialButton.qml index 2129873f..969a3c54 100644 --- a/src/commoncomponents/MaterialButton.qml +++ b/src/commoncomponents/MaterialButton.qml @@ -26,12 +26,14 @@ import "../constant" Button { id: root + property alias fontCapitalization: buttonText.font.capitalization property alias source: root.icon.source property string toolTipText: "" property var color: "transparent" property var hoveredColor: undefined property var pressedColor: undefined property var outlined: false + property string animatedImageSource: "" property var preferredWidth: 400 property var preferredHeight: 36 @@ -43,6 +45,7 @@ Button { icon.source: "" icon.height: 18 icon.width: 18 + hoverEnabled: hoveredColor !== undefined contentItem: Item { @@ -52,6 +55,21 @@ Button { RowLayout { anchors.fill: parent anchors.centerIn: parent + + AnimatedImage { + Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft + Layout.leftMargin: 8 + Layout.preferredHeight: root.icon.height + Layout.preferredWidth: root.icon.width + + source: animatedImageSource + playing: true + paused: false + fillMode: Image.PreserveAspectFit + mipmap: true + visible: animatedImageSource !== "" + } + Image { source: root.icon.source Layout.preferredWidth: root.icon.width @@ -75,6 +93,8 @@ Button { } } Text { + id: buttonText + Layout.rightMargin: root.icon.width + JamiTheme.preferredMarginSize / 2 text: root.text elide: root.elide diff --git a/src/commoncomponents/MaterialLineEdit.qml b/src/commoncomponents/MaterialLineEdit.qml index f7a43222..a2829c11 100644 --- a/src/commoncomponents/MaterialLineEdit.qml +++ b/src/commoncomponents/MaterialLineEdit.qml @@ -1,7 +1,24 @@ +/* + * Copyright (C) 2020 by Savoir-faire Linux + * Author: Sébastien blin + * + * 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 . + */ + import QtQuick 2.14 import QtQuick.Controls 2.14 import QtQuick.Layouts 1.14 -import QtQuick.Controls.Styles 1.4 import QtGraphicalEffects 1.15 import "../constant" @@ -9,6 +26,7 @@ import "../constant" TextField { enum BorderColorMode { NORMAL, + SEARCHING, RIGHT, ERROR } @@ -17,37 +35,39 @@ TextField { property int fieldLayoutHeight: 48 property bool layoutFillwidth: false - property int borderColorMode: InfoLineEdit.NORMAL - property var iconSource: { - if (readOnly) { - return "" - } - switch(borderColorMode){ - case InfoLineEdit.RIGHT: - return "qrc:/images/icons/round-check_circle-24px.svg" - case InfoLineEdit.NORMAL: - return "" - case InfoLineEdit.ERROR: - return "qrc:/images/icons/round-error-24px.svg" - } - } + property int borderColorMode: MaterialLineEdit.NORMAL + property var iconSource: "" property var backgroundColor: JamiTheme.rgb256(240,240,240) - property var borderColor: { - if (!enabled) { - return "transparent" - } - switch(borderColorMode){ - case InfoLineEdit.NORMAL: - return "#333" - case InfoLineEdit.RIGHT: - return "green" - case InfoLineEdit.ERROR: - return "red" - } - } + property var borderColor: "#333" signal imageClicked + onBorderColorModeChanged: { + if (!enabled) + borderColor = "transparent" + if (readOnly) + iconSource = "" + + switch(borderColorMode){ + case MaterialLineEdit.SEARCHING: + iconSource = "qrc:/images/jami_rolling_spinner.gif" + borderColor = "#333" + break + case MaterialLineEdit.NORMAL: + iconSource = "" + borderColor = "#333" + break + case MaterialLineEdit.RIGHT: + iconSource = "qrc:/images/icons/round-check_circle-24px.svg" + borderColor = "green" + break + case MaterialLineEdit.ERROR: + iconSource = "qrc:/images/icons/round-error-24px.svg" + borderColor = "red" + break + } + } + wrapMode: Text.Wrap readOnly: false selectByMouse: true @@ -58,12 +78,17 @@ TextField { verticalAlignment: Text.AlignVCenter Image { - source: iconSource - width: 24 - height: 24 + id: lineEditImage + anchors.verticalCenter: parent.verticalCenter anchors.right: parent.right anchors.rightMargin: 16 + + width: 24 + height: 24 + + visible: borderColorMode !== MaterialLineEdit.SEARCHING + source: borderColorMode === MaterialLineEdit.SEARCHING ? "" : iconSource layer { enabled: true effect: ColorOverlay { @@ -76,7 +101,7 @@ TextField { anchors.fill: parent hoverEnabled: true acceptedButtons: Qt.LeftButton - enabled: borderColorMode === InfoLineEdit.RIGHT + enabled: borderColorMode === MaterialLineEdit.RIGHT onReleased: { imageClicked() @@ -84,6 +109,21 @@ TextField { } } + AnimatedImage { + anchors.left: lineEditImage.left + anchors.verticalCenter: parent.verticalCenter + + width: 24 + height: 24 + + source: borderColorMode !== MaterialLineEdit.SEARCHING ? "" : iconSource + playing: true + paused: false + fillMode: Image.PreserveAspectFit + mipmap: true + visible: borderColorMode === MaterialLineEdit.SEARCHING + } + background: Rectangle { anchors.fill: parent radius: 4 diff --git a/src/commoncomponents/SpinnerButton.qml b/src/commoncomponents/SpinnerButton.qml new file mode 100644 index 00000000..44326d5a --- /dev/null +++ b/src/commoncomponents/SpinnerButton.qml @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2020 by Savoir-faire Linux + * Author: Mingrui Zhang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import QtQuick 2.14 +import QtQuick.Controls 2.14 +import net.jami.Models 1.0 + +MaterialButton { + id: root + + property bool spinnerTriggered: false + property string spinnerTriggeredtext: value + property string normalText: value + + animatedImageSource: spinnerTriggered ? "qrc:/images/jami_rolling_spinner.gif" : "" + text: spinnerTriggered ? spinnerTriggeredtext : normalText + color: !enabled ? JamiTheme.buttonTintedGreyInactive : + JamiTheme.wizardBlueButtons + + hoveredColor: JamiTheme.buttonTintedBlueHovered + pressedColor: JamiTheme.buttonTintedBluePressed +} diff --git a/src/settingsview/SettingsView.qml b/src/settingsview/SettingsView.qml index d20929d5..62cb2cb6 100644 --- a/src/settingsview/SettingsView.qml +++ b/src/settingsview/SettingsView.qml @@ -105,7 +105,6 @@ Rectangle { function onAccountListChanged(){ slotAccountListChanged() - accountListChangedConnection.enabled = false } } @@ -126,11 +125,10 @@ Rectangle { function slotAccountListChanged(){ var accountList = ClientWrapper.accountModel.getAccountList() - if(accountList.length === 0) { - setSelected(SettingsView.Account) - } else { - currentAccountSettingsScrollWidget.disconnectAccountConnections() - } + if(accountList.length === 0) + return + + currentAccountSettingsScrollWidget.disconnectAccountConnections() var device = ClientWrapper.avmodel.getDefaultDevice() if(device.length === 0){ ClientWrapper.avmodel.setCurrentVideoCaptureDevice(device) diff --git a/src/wizardview/WizardView.qml b/src/wizardview/WizardView.qml index 6aea2ea9..7e0fd9aa 100644 --- a/src/wizardview/WizardView.qml +++ b/src/wizardview/WizardView.qml @@ -48,6 +48,17 @@ Rectangle { SEARCHING } + enum WizardViewPageIndex { + WELCOMEPAGE = 0, + CREATEACCOUNTPAGE, + CREATESIPACCOUNTPAGE, + IMPORTFROMBACKUPPAGE, + BACKUPKEYSPAGE, + IMPORTFROMDEVICEPAGE, + CONNECTTOACCOUNTMANAGERPAGE, + PROFILEPAGE + } + readonly property int layoutSpacing: 12 property int textFontSize: 9 @@ -66,9 +77,10 @@ Rectangle { signal wizardViewIsClosed visible: true + color: JamiTheme.backgroundColor Component.onCompleted: { - changePageQML(controlPanelStackView.welcomePageStackId) + changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE) } Connections{ @@ -78,85 +90,77 @@ Rectangle { addedAccountIndex = index ClientWrapper.accountAdaptor.accountChanged(index) if (showProfile) { - changePageQML(controlPanelStackView.profilePageId) - profilePage.readyToSaveDetails = true - } else if (controlPanelStackView.currentIndex == controlPanelStackView.profilePageId) { - ClientWrapper.lrcInstance.accountListChanged() - profilePage.readyToSaveDetails = true + changePageQML(WizardView.WizardViewPageIndex.PROFILEPAGE) + profilePage.readyToSaveDetails() + } else if (controlPanelStackView.currentIndex === WizardView.WizardViewPageIndex.PROFILEPAGE) { + profilePage.readyToSaveDetails() } else if (showBackUp) { - changePageQML(controlPanelStackView.backupKeysPageId) + changePageQML(WizardView.WizardViewPageIndex.BACKUPKEYSPAGE) } else { - changePageQML(controlPanelStackView.welcomePageStackId) + changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE) needToShowMainViewWindow(addedAccountIndex) - ClientWrapper.lrcInstance.accountListChanged() } } // reportFailure function onReportFailure() { - if (controlPanelStackView.currentIndex == controlPanelStackView.importFromDevicePageId) { - importFromDevicePage.errorText = qsTr("Error when creating your account. Check your credentials") - } else if (controlPanelStackView.currentIndex == controlPanelStackView.importFromBackupPageId) { - importFromBackupPage.errorText = qsTr("Error when creating your account. Check your credentials") - } else if (controlPanelStackView.currentIndex == controlPanelStackView.connectToAccountManagerPageId) { - connectToAccountManagerPage.errorText = qsTr("Error when creating your account. Check your credentials") + var errorMessage = qsTr("Error when creating your account. Check your credentials") + + switch(controlPanelStackView.currentIndex) { + case WizardView.WizardViewPageIndex.IMPORTFROMDEVICEPAGE: + importFromDevicePage.errorOccured(errorMessage) + break + case WizardView.WizardViewPageIndex.IMPORTFROMBACKUPPAGE: + importFromBackupPage.errorOccured(errorMessage) + break + case WizardView.WizardViewPageIndex.CONNECTTOACCOUNTMANAGERPAGE: + connectToAccountManagerPage.errorOccured(errorMessage) + break } } } Connections { id: registeredNameFoundConnection + target: ClientWrapper.nameDirectory - enabled: false function onRegisteredNameFound(status, address, name) { - slotRegisteredNameFound(status, address, name) - } - } - - function slotRegisteredNameFound(status, address, name) { - if (name.length != 0 && name.length < 3) { - createAccountPage.nameRegistrationUIState = WizardView.INVALID - } else if (registeredName === name) { - switch (status) { - case NameDirectory.LookupStatus.NOT_FOUND: - case NameDirectory.LookupStatus.ERROR: - createAccountPage.nameRegistrationUIState = WizardView.FREE - break - case NameDirectory.LookupStatus.INVALID_NAME: - case NameDirectory.LookupStatus.INVALID: - createAccountPage.nameRegistrationUIState = WizardView.INVALID - break - case NameDirectory.LookupStatus.SUCCESS: - createAccountPage.nameRegistrationUIState = WizardView.TAKEN - break + if (registeredName === name) { + switch(status) { + case NameDirectory.LookupStatus.NOT_FOUND: + createAccountPage.nameRegistrationUIState = WizardView.FREE + break + case NameDirectory.LookupStatus.ERROR: + case NameDirectory.LookupStatus.INVALID_NAME: + case NameDirectory.LookupStatus.INVALID: + createAccountPage.nameRegistrationUIState = WizardView.INVALID + break + case NameDirectory.LookupStatus.SUCCESS: + createAccountPage.nameRegistrationUIState = WizardView.TAKEN + break + } } } } function changePageQML(pageIndex) { controlPanelStackView.currentIndex = pageIndex - if (pageIndex == controlPanelStackView.welcomePageStackId) { + if (pageIndex === WizardView.WizardViewPageIndex.WELCOMEPAGE) { fileToImport = "" - registeredNameFoundConnection.enabled = true createAccountPage.nameRegistrationUIState = WizardView.BLANK - } else if (pageIndex == controlPanelStackView.createAccountPageId) { + } else if (pageIndex === WizardView.WizardViewPageIndex.CREATEACCOUNTPAGE) { createAccountPage.initializeOnShowUp() - // connection between register name found and its slot - registeredNameFoundConnection.enabled = true - } else if (pageIndex == controlPanelStackView.createSIPAccountPageId) { + } else if (pageIndex === WizardView.WizardViewPageIndex.CREATESIPACCOUNTPAGE) { createSIPAccountPage.initializeOnShowUp() - } else if (pageIndex == controlPanelStackView.importFromDevicePageId) { + } else if (pageIndex === WizardView.WizardViewPageIndex.IMPORTFROMDEVICEPAGE) { importFromDevicePage.initializeOnShowUp() - } else if (pageIndex == controlPanelStackView.spinnerPageId) { - createAccountPage.nameRegistrationUIState = WizardView.BLANK - createAccountPage.isToSetPassword_checkState_choosePasswordCheckBox = false - } else if (pageIndex == controlPanelStackView.connectToAccountManagerPageId) { + } else if (pageIndex === WizardView.WizardViewPageIndex.CONNECTTOACCOUNTMANAGERPAGE) { connectToAccountManagerPage.initializeOnShowUp() - } else if (pageIndex == controlPanelStackView.importFromBackupPageId) { + } else if (pageIndex === WizardView.WizardViewPageIndex.IMPORTFROMBACKUPPAGE) { importFromBackupPage.clearAllTextFields() fileToImport = "" - } else if (pageIndex == controlPanelStackView.profilePageId) { + } else if (pageIndex === WizardView.WizardViewPageIndex.PROFILEPAGE) { profilePage.initializeOnShowUp() profilePage.showBottom = showBottom } @@ -183,7 +187,6 @@ Rectangle { if (success) { console.log("Account Export Succeed") needToShowMainViewWindow(addedAccountIndex) - ClientWrapper.lrcInstance.accountListChanged() } } } @@ -199,20 +202,9 @@ Rectangle { anchors.fill: parent - currentIndex: welcomePageStackId - - property int welcomePageStackId: 0 - property int createAccountPageId: 1 - property int createSIPAccountPageId: 2 - property int importFromBackupPageId: 3 - property int backupKeysPageId: 4 - property int importFromDevicePageId: 5 - property int connectToAccountManagerPageId: 6 - property int spinnerPageId: 7 - property int profilePageId: 8 + currentIndex: WizardView.WizardViewPageIndex.WELCOMEPAGE WelcomePage { - // welcome page, index 0 id: welcomePage onWelcomePageRedirectPage: { @@ -225,7 +217,6 @@ Rectangle { } CreateAccountPage { - // create account page, index 1 id: createAccountPage onCreateAccount: { @@ -238,22 +229,19 @@ Rectangle { true) showBackUp = true showBottom = true - changePageQML(controlPanelStackView.profilePageId) + changePageQML(WizardView.WizardViewPageIndex.PROFILEPAGE) } - onText_usernameEditAliasChanged: { - lookupTimer.restart() - } + onText_usernameEditAliasChanged: lookupTimer.restart() onLeavePage: { - changePageQML(controlPanelStackView.welcomePageStackId) + changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE) } Timer { id: lookupTimer repeat: false - triggeredOnStart: false interval: 200 onTriggered: { @@ -269,11 +257,10 @@ Rectangle { } CreateSIPAccountPage { - // create SIP account page, index 2 id: createSIPAccountPage onLeavePage: { - changePageQML(controlPanelStackView.welcomePageStackId) + changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE) } onCreateAccount: { @@ -287,24 +274,22 @@ Rectangle { ClientWrapper.accountAdaptor.createSIPAccount(inputParaObject, "") showBackUp = false showBottom = false - changePageQML(controlPanelStackView.profilePageId) - controlPanelStackView.profilePage.readyToSaveDetails = true + changePageQML(WizardView.WizardViewPageIndex.PROFILEPAGE) + controlPanelStackView.profilePage.readyToSaveDetails() } } ImportFromBackupPage { - // import from backup page, index 3 id: importFromBackupPage onLeavePage: { - changePageQML(controlPanelStackView.welcomePageStackId) + changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE) } onImportAccount: { inputParaObject = {} inputParaObject["archivePath"] = ClientWrapper.utilsAdaptor.getAbsPath(importFromBackupPage.filePath) inputParaObject["password"] = importFromBackupPage.text_passwordFromBackupEditAlias - importFromBackupPage.clearAllTextFields() showBackUp = false showBottom = false showProfile = true @@ -314,7 +299,6 @@ Rectangle { } BackupKeyPage { - // backup keys page, index 4 id: backupKeysPage onNeverShowAgainBoxClicked: { @@ -337,24 +321,21 @@ Rectangle { } } - changePageQML(controlPanelStackView.welcomePageStackId) + changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE) needToShowMainViewWindow(addedAccountIndex) - ClientWrapper.lrcInstance.accountListChanged() } onLeavePage: { - changePageQML(controlPanelStackView.welcomePageStackId) + changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE) needToShowMainViewWindow(addedAccountIndex) - ClientWrapper.lrcInstance.accountListChanged() } } ImportFromDevicePage { - // import from device page, index 5 id: importFromDevicePage onLeavePage: { - changePageQML(controlPanelStackView.welcomePageStackId) + changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE) } onImportAccount: { @@ -371,7 +352,6 @@ Rectangle { } ConnectToAccountManagerPage { - // connect to account manager Page, index 6 id: connectToAccountManagerPage onCreateAccount: { @@ -386,26 +366,19 @@ Rectangle { } onLeavePage: { - changePageQML(controlPanelStackView.welcomePageStackId) + changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE) } } - SpinnerPage { - // spinner Page, index 7 - id: spinnerPage - } - ProfilePage { - // profile Page, index 8 id: profilePage function leave() { if (showBackUp) - changePageQML(controlPanelStackView.backupKeysPageId) + changePageQML(WizardView.WizardViewPageIndex.BACKUPKEYSPAGE) else { - changePageQML(controlPanelStackView.welcomePageStackId) + changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE) needToShowMainViewWindow(addedAccountIndex) - ClientWrapper.lrcInstance.accountListChanged() } } @@ -420,6 +393,4 @@ Rectangle { } } } - - color: JamiTheme.backgroundColor } diff --git a/src/wizardview/components/ConnectToAccountManagerPage.qml b/src/wizardview/components/ConnectToAccountManagerPage.qml index 7576b932..afd98851 100644 --- a/src/wizardview/components/ConnectToAccountManagerPage.qml +++ b/src/wizardview/components/ConnectToAccountManagerPage.qml @@ -31,21 +31,32 @@ Rectangle { property alias text_accountManagerEditAlias: accountManagerEdit.text property string errorText: "" + signal leavePage + signal createAccount + function initializeOnShowUp() { clearAllTextFields() } function clearAllTextFields() { + connectBtn.spinnerTriggered = false usernameManagerEdit.clear() passwordManagerEdit.clear() accountManagerEdit.clear() errorText = "" } + function errorOccured(errorMessage) { + connectBtn.spinnerTriggered = false + errorText = errorMessage + } + color: JamiTheme.backgroundColor - signal leavePage - signal createAccount + onVisibleChanged: { + if (visible) + accountManagerEdit.focus = true + } ColumnLayout { spacing: layoutSpacing @@ -92,6 +103,8 @@ Rectangle { font.kerning: true borderColorMode: MaterialLineEdit.NORMAL + + onTextChanged: errorText = "" } Label { @@ -114,6 +127,8 @@ Rectangle { font.kerning: true borderColorMode: MaterialLineEdit.NORMAL + + onTextChanged: errorText = "" } MaterialLineEdit { @@ -129,27 +144,28 @@ Rectangle { font.kerning: true echoMode: TextInput.Password - borderColorMode: MaterialLineEdit.NORMAL + + onTextChanged: errorText = "" } - MaterialButton { + SpinnerButton { id: connectBtn Layout.alignment: Qt.AlignCenter Layout.preferredWidth: preferredWidth Layout.preferredHeight: preferredHeight - text: qsTr("CONNECT") + spinnerTriggeredtext: qsTr("Generating account…") + normalText: qsTr("CONNECT") + enabled: accountManagerEdit.text.length !== 0 - && usernameManagerEdit.text.length !== 0 - && passwordManagerEdit.text.length !== 0 - color: enabled? JamiTheme.wizardBlueButtons : JamiTheme.buttonTintedGreyInactive - hoveredColor: JamiTheme.buttonTintedBlueHovered - pressedColor: JamiTheme.buttonTintedBluePressed + && usernameManagerEdit.text.length !== 0 + && passwordManagerEdit.text.length !== 0 + && !spinnerTriggered onClicked: { - errorText = "" + spinnerTriggered = true createAccount() } } @@ -163,21 +179,26 @@ Rectangle { font.pointSize: JamiTheme.textFontSize color: "red" } + } - MaterialButton { - id: backButton + HoverableButton { + id: backButton - Layout.alignment: Qt.AlignCenter - Layout.preferredWidth: preferredWidth - Layout.preferredHeight: preferredHeight + anchors.left: parent.left + anchors.top: parent.top + anchors.margins: 20 - text: qsTr("BACK") - color: JamiTheme.buttonTintedGrey - hoveredColor: JamiTheme.buttonTintedGreyHovered - pressedColor: JamiTheme.buttonTintedGreyPressed - outlined: true + width: 35 + height: 35 - onClicked: leavePage() - } + radius: 30 + + backgroundColor: root.color + onExitColor: root.color + + source: "qrc:/images/icons/ic_arrow_back_24px.svg" + toolTipText: qsTr("Back to welcome page") + + onClicked: leavePage() } } diff --git a/src/wizardview/components/CreateAccountPage.qml b/src/wizardview/components/CreateAccountPage.qml index 8e694da4..39ced2f3 100644 --- a/src/wizardview/components/CreateAccountPage.qml +++ b/src/wizardview/components/CreateAccountPage.qml @@ -57,6 +57,11 @@ Rectangle { onActivated: leavePage() } + onVisibleChanged: { + if (visible && createAccountStack.currentIndex === 0) + usernameEdit.focus = true + } + // JamiFileDialog for exporting account JamiFileDialog { id: exportBtn_Dialog @@ -127,7 +132,7 @@ Rectangle { Layout.topMargin: 15 Layout.preferredHeight: fieldLayoutHeight - Layout.preferredWidth: fieldLayoutWidth + Layout.preferredWidth: chooseUsernameButton.width Layout.alignment: Qt.AlignHCenter selectByMouse: true @@ -136,14 +141,18 @@ Rectangle { font.kerning: true borderColorMode: { - if (nameRegistrationUIState === WizardView.BLANK) + switch (nameRegistrationUIState){ + case WizardView.BLANK: return MaterialLineEdit.NORMAL - else - return nameRegistrationUIState >= WizardView.FREE ? - MaterialLineEdit.NORMAL : MaterialLineEdit.ERROR + case WizardView.INVALID: + case WizardView.TAKEN: + return MaterialLineEdit.ERROR + case WizardView.FREE: + return MaterialLineEdit.RIGHT + case WizardView.SEARCHING: + return MaterialLineEdit.SEARCHING + } } - - fieldLayoutWidth: chooseUsernameButton.width } Label { @@ -175,11 +184,11 @@ Rectangle { Layout.preferredHeight: preferredHeight text: qsTr("CHOOSE USERNAME") - color: nameRegistrationUIState === WizardView.FREE? - JamiTheme.buttonTintedGrey - : JamiTheme.buttonTintedGreyInactive - hoveredColor: JamiTheme.buttonTintedGreyHovered - pressedColor: JamiTheme.buttonTintedGreyPressed + enabled: nameRegistrationUIState === WizardView.FREE + color: nameRegistrationUIState === WizardView.FREE ? JamiTheme.wizardBlueButtons : + JamiTheme.buttonTintedGreyInactive + hoveredColor: JamiTheme.buttonTintedBlueHovered + pressedColor: JamiTheme.buttonTintedBluePressed onClicked: { if (nameRegistrationUIState === WizardView.FREE) @@ -187,38 +196,21 @@ Rectangle { } } - Row { - id: skipAndBackButtonsRow + MaterialButton { + id: skipButton Layout.alignment: Qt.AlignCenter - Layout.preferredWidth: chooseUsernameButton.preferredWidth - Layout.preferredHeight: chooseUsernameButton.preferredHeight + Layout.preferredWidth: preferredWidth + Layout.preferredHeight: preferredHeight - spacing: layoutSpacing + text: qsTr("SKIP") + color: JamiTheme.buttonTintedGrey + hoveredColor: JamiTheme.buttonTintedGreyHovered + pressedColor: JamiTheme.buttonTintedGreyPressed + outlined: true - Repeater { - model: 2 - - MaterialButton { - width: (skipAndBackButtonsRow.width - - skipAndBackButtonsRow.spacing) / 2 - height: skipAndBackButtonsRow.height - - text: modelData === 0 ? qsTr("BACK") : qsTr("SKIP") - color: JamiTheme.buttonTintedGrey - hoveredColor: JamiTheme.buttonTintedGreyHovered - pressedColor: JamiTheme.buttonTintedGreyPressed - outlined: true - - onClicked: { - if (modelData === 0) - leavePage() - else - createAccountStack.currentIndex = - createAccountStack.currentIndex + 1 - } - } - } + onClicked: createAccountStack.currentIndex = + createAccountStack.currentIndex + 1 } } @@ -328,22 +320,32 @@ Rectangle { createAccountStack.currentIndex += 1 } } + } + } - MaterialButton { - id: backButton + HoverableButton { + id: backButton - Layout.alignment: Qt.AlignCenter - Layout.preferredWidth: preferredWidth - Layout.preferredHeight: preferredHeight + anchors.left: parent.left + anchors.top: parent.top + anchors.margins: 20 - text: qsTr("BACK") - color: JamiTheme.buttonTintedGrey - hoveredColor: JamiTheme.buttonTintedGreyHovered - pressedColor: JamiTheme.buttonTintedGreyPressed - outlined: true + width: 35 + height: 35 - onClicked: createAccountStack.currentIndex -= 1 - } + radius: 30 + + backgroundColor: root.color + onExitColor: root.color + + source: "qrc:/images/icons/ic_arrow_back_24px.svg" + toolTipText: qsTr("Back") + + onClicked: { + if (createAccountStack.currentIndex == 0) + leavePage() + else + createAccountStack.currentIndex -= 1 } } diff --git a/src/wizardview/components/CreateSIPAccountPage.qml b/src/wizardview/components/CreateSIPAccountPage.qml index d0f02390..899289bf 100644 --- a/src/wizardview/components/CreateSIPAccountPage.qml +++ b/src/wizardview/components/CreateSIPAccountPage.qml @@ -33,6 +33,9 @@ Rectangle { property var boothImgBase64: null + signal createAccount + signal leavePage + function initializeOnShowUp() { clearAllTextFields() } @@ -45,11 +48,13 @@ Rectangle { sipUsernameEdit.clear() } - signal createAccount - signal leavePage - color: JamiTheme.backgroundColor + onVisibleChanged: { + if (visible) + sipServernameEdit.focus = true + } + ColumnLayout { spacing: layoutSpacing @@ -150,21 +155,26 @@ Rectangle { createAccount() } } + } - MaterialButton { - id: backButton + HoverableButton { + id: backButton - Layout.alignment: Qt.AlignCenter - Layout.preferredWidth: createAccountButton.width / 2 - Layout.preferredHeight: preferredHeight + anchors.left: parent.left + anchors.top: parent.top + anchors.margins: 20 - text: qsTr("BACK") - color: JamiTheme.buttonTintedGrey - hoveredColor: JamiTheme.buttonTintedGreyHovered - pressedColor: JamiTheme.buttonTintedGreyPressed - outlined: true + width: 35 + height: 35 - onClicked: leavePage() - } + radius: 30 + + backgroundColor: root.color + onExitColor: root.color + + source: "qrc:/images/icons/ic_arrow_back_24px.svg" + toolTipText: qsTr("Back to welcome page") + + onClicked: leavePage() } } diff --git a/src/wizardview/components/ImportFromBackupPage.qml b/src/wizardview/components/ImportFromBackupPage.qml index 98f58270..9d090738 100644 --- a/src/wizardview/components/ImportFromBackupPage.qml +++ b/src/wizardview/components/ImportFromBackupPage.qml @@ -34,12 +34,23 @@ Rectangle { property string filePath: "" property string errorText: "" + signal leavePage + signal importAccount + function clearAllTextFields() { + connectBtn.spinnerTriggered = false passwordFromBackupEdit.clear() errorText = "" fileImportBtnText = qsTr("Archive(none)") } + function errorOccured(errorMessage) { + errorText = errorMessage + connectBtn.spinnerTriggered = false + } + + color: JamiTheme.backgroundColor + JamiFileDialog { id: importFromFile_Dialog @@ -59,11 +70,6 @@ Rectangle { } } - color: JamiTheme.backgroundColor - - signal leavePage - signal importAccount - ColumnLayout { spacing: layoutSpacing @@ -91,7 +97,10 @@ Rectangle { hoveredColor: JamiTheme.buttonTintedGreyHovered pressedColor: JamiTheme.buttonTintedGreyPressed - onClicked: importFromFile_Dialog.open() + onClicked: { + errorText = "" + importFromFile_Dialog.open() + } } Text { @@ -128,26 +137,31 @@ Rectangle { font.kerning: true echoMode: TextInput.Password - borderColorMode: MaterialLineEdit.NORMAL + + onTextChanged: errorText = "" } - MaterialButton { + SpinnerButton { id: connectBtn Layout.alignment: Qt.AlignCenter Layout.preferredWidth: preferredWidth Layout.preferredHeight: preferredHeight - text: qsTr("CONNECT FROM BACKUP") - color: filePath.length === 0 ? - JamiTheme.buttonTintedGreyInactive : JamiTheme.buttonTintedGrey - enabled: !(filePath.length === 0) - hoveredColor: JamiTheme.buttonTintedGreyHovered - pressedColor: JamiTheme.buttonTintedGreyPressed + spinnerTriggeredtext: qsTr("Generating account…") + normalText: qsTr("CONNECT FROM BACKUP") + + enabled: { + if (spinnerTriggered) + return false + if (!(filePath.length === 0) && errorText.length === 0) + return true + return false + } onClicked: { - errorText = "" + spinnerTriggered = true importAccount() } } @@ -161,21 +175,26 @@ Rectangle { font.pointSize: JamiTheme.textFontSize color: "red" } + } - MaterialButton { - id: backButton + HoverableButton { + id: backButton - Layout.alignment: Qt.AlignCenter - Layout.preferredWidth: connectBtn.width / 2 - Layout.preferredHeight: preferredHeight + anchors.left: parent.left + anchors.top: parent.top + anchors.margins: 20 - text: qsTr("BACK") - color: JamiTheme.buttonTintedGrey - hoveredColor: JamiTheme.buttonTintedGreyHovered - pressedColor: JamiTheme.buttonTintedGreyPressed - outlined: true + width: 35 + height: 35 - onClicked: leavePage() - } + radius: 30 + + backgroundColor: root.color + onExitColor: root.color + + source: "qrc:/images/icons/ic_arrow_back_24px.svg" + toolTipText: qsTr("Back to welcome page") + + onClicked: leavePage() } } diff --git a/src/wizardview/components/ImportFromDevicePage.qml b/src/wizardview/components/ImportFromDevicePage.qml index d4d786e6..f3edcc3c 100644 --- a/src/wizardview/components/ImportFromDevicePage.qml +++ b/src/wizardview/components/ImportFromDevicePage.qml @@ -30,19 +30,30 @@ Rectangle { property alias text_passwordFromDeviceAlias: passwordFromDevice.text property string errorText: "" + signal leavePage + signal importAccount + function initializeOnShowUp() { clearAllTextFields() } function clearAllTextFields() { + connectBtn.spinnerTriggered = false pinFromDevice.clear() passwordFromDevice.clear() } + function errorOccured(errorMessage) { + errorText = errorMessage + connectBtn.spinnerTriggered = false + } + color: JamiTheme.backgroundColor - signal leavePage - signal importAccount + onVisibleChanged: { + if (visible) + pinFromDevice.focus = true + } ColumnLayout { spacing: layoutSpacing @@ -71,8 +82,9 @@ Rectangle { font.kerning: true echoMode: TextInput.Password - borderColorMode: MaterialLineEdit.NORMAL + + onTextChanged: errorText = "" } Text { @@ -83,7 +95,7 @@ Rectangle { Layout.preferredHeight: preferredHeight text: qsTr("Enter the PIN from another configured Jami account. " + - "Use the \"export Jami account\" feature to obtain a PIN") + "Use the \"Link Another Device\" feature to obtain a PIN") wrapMode: Text.Wrap onTextChanged: { @@ -106,23 +118,24 @@ Rectangle { font.kerning: true borderColorMode: MaterialLineEdit.NORMAL + + onTextChanged: errorText = "" } - MaterialButton { + SpinnerButton { id: connectBtn Layout.alignment: Qt.AlignCenter Layout.preferredWidth: preferredWidth Layout.preferredHeight: preferredHeight - text: qsTr("CONNECT FROM ANOTHER DEVICE") - color: pinFromDevice.text.length === 0? - JamiTheme.buttonTintedGreyInactive : JamiTheme.buttonTintedGrey - hoveredColor: JamiTheme.buttonTintedGreyHovered - pressedColor: JamiTheme.buttonTintedGreyPressed + spinnerTriggeredtext: qsTr("Generating account…") + normalText: qsTr("CONNECT FROM ANOTHER DEVICE") + + enabled: pinFromDevice.text.length !== 0 && !spinnerTriggered onClicked: { - errorText = "" + spinnerTriggered = true importAccount() } } @@ -137,21 +150,26 @@ Rectangle { font.pointSize: JamiTheme.textFontSize color: "red" } + } - MaterialButton { - id: backButton + HoverableButton { + id: backButton - Layout.alignment: Qt.AlignCenter - Layout.preferredWidth: connectBtn.width / 2 - Layout.preferredHeight: preferredHeight + anchors.left: parent.left + anchors.top: parent.top + anchors.margins: 20 - text: qsTr("BACK") - color: JamiTheme.buttonTintedGrey - hoveredColor: JamiTheme.buttonTintedGreyHovered - pressedColor: JamiTheme.buttonTintedGreyPressed - outlined: true + width: 35 + height: 35 - onClicked: leavePage() - } + radius: 30 + + backgroundColor: root.color + onExitColor: root.color + + source: "qrc:/images/icons/ic_arrow_back_24px.svg" + toolTipText: qsTr("Back to welcome page") + + onClicked: leavePage() } } diff --git a/src/wizardview/components/ProfilePage.qml b/src/wizardview/components/ProfilePage.qml index f1e64dda..557d0824 100644 --- a/src/wizardview/components/ProfilePage.qml +++ b/src/wizardview/components/ProfilePage.qml @@ -29,19 +29,22 @@ Rectangle { function initializeOnShowUp() { clearAllTextFields() boothImgBase64 = "" - readyToSaveDetails = false + saveProfileBtn.spinnerTriggered = true } function clearAllTextFields() { aliasEdit.clear() } + function readyToSaveDetails() { + saveProfileBtn.spinnerTriggered = false + } + color: JamiTheme.backgroundColor signal leavePage signal saveProfile - property var readyToSaveDetails: false property var showBottom: false property alias boothImgBase64: setAvatarWidget.imgBase64 property alias displayName: aliasEdit.text @@ -106,22 +109,18 @@ Rectangle { fieldLayoutWidth: saveProfileBtn.width } - MaterialButton { + SpinnerButton { id: saveProfileBtn Layout.alignment: Qt.AlignCenter Layout.preferredWidth: preferredWidth Layout.preferredHeight: preferredHeight - enabled: readyToSaveDetails - text: enabled? qsTr("Save Profile") : qsTr("Generating account…") - color: enabled? JamiTheme.wizardBlueButtons : JamiTheme.buttonTintedGreyInactive - hoveredColor: JamiTheme.buttonTintedBlueHovered - pressedColor: JamiTheme.buttonTintedBluePressed + enabled: !spinnerTriggered + normalText: qsTr("Save Profile") + spinnerTriggeredtext: qsTr("Generating account…") - onClicked: { - saveProfile() - } + onClicked: saveProfile() } MaterialButton { diff --git a/src/wizardview/components/SpinnerPage.qml b/src/wizardview/components/SpinnerPage.qml deleted file mode 100644 index 2fb3f8d0..00000000 --- a/src/wizardview/components/SpinnerPage.qml +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2020 by Savoir-faire Linux - * Author: Yang Wang - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -import QtQuick 2.14 -import QtQuick.Layouts 1.3 -import QtQuick.Controls 2.14 - -import "../../constant" - -ColumnLayout { - Layout.fillWidth: true - Layout.fillHeight: true - spacing: 6 - - property bool successState: true - property string progressLabelEditText: "Generating your Jami account" - - Item { - Layout.alignment: Qt.AlignHCenter - Layout.preferredHeight: 40 - Layout.fillWidth: true - Layout.fillHeight: true - } - Label { - id: spinnerLabel - Layout.alignment: Qt.AlignHCenter - Layout.minimumWidth: 200 - Layout.minimumHeight: 200 - - Layout.maximumWidth: 16777215 - Layout.maximumHeight: 16777215 - - property string spinnerDisplyState: successState ? "spinnerLabel_Regular" : "spinnerLabel_Failure" - onSpinnerDisplyStateChanged: { - switch (spinnerDisplyState) { - case "spinnerLabel_Regular": - background = Qt.createQmlObject("import QtQuick 2.14; -AnimatedImage { -source: \"qrc:/images/jami_eclipse_spinner.gif\" - -playing: true -paused: false -fillMode: Image.PreserveAspectFit -mipmap: true -}", spinnerLabel) - break - case "spinnerLabel_Failure": - background = Qt.createQmlObject("import QtQuick 2.14; -import \"qrc:/src/constant/\"; -Image { -anchors.fill: parent; -source:\"image://tintedPixmap/\" + (\"qrc:/images/icons/baseline-error_outline-24px.svg\").replace(\"qrc:/images/icons/\", \"\") + \"+\" + JamiTheme.urgentOrange_; -mipmap: true;}", spinnerLabel) - break - } - } - } - Item { - Layout.alignment: Qt.AlignHCenter - Layout.preferredHeight: 40 - Layout.fillWidth: true - Layout.fillHeight: true - } - Label { - id: progressLabel - Layout.alignment: Qt.AlignHCenter - text: successState ? progressLabelEditText : "Error creating account" - font.pointSize: 11 - font.kerning: true - - property string progressLabelState: successState ? "color_success" : "color_fail" - onProgressLabelStateChanged: { - switch (progressLabelState) { - case "color_success": - background = Qt.createQmlObject( - "import QtQuick 2.14; Rectangle { anchors.fill: parent; color: \"transparent\"; }", - progressLabel) - break - case "color_fail": - background = Qt.createQmlObject( - "import QtQuick 2.14; Rectangle { anchors.fill: parent; color: \"red\"; }", - progressLabel) - break - } - } - } - Item { - Layout.alignment: Qt.AlignHCenter - Layout.minimumHeight: 20 - Layout.maximumHeight: 20 - Layout.preferredHeight: 20 - Layout.fillWidth: true - Layout.fillHeight: false - } -} diff --git a/src/wizardview/components/WelcomePage.qml b/src/wizardview/components/WelcomePage.qml index f1ea2787..c15d66f9 100644 --- a/src/wizardview/components/WelcomePage.qml +++ b/src/wizardview/components/WelcomePage.qml @@ -37,6 +37,8 @@ Rectangle { ColumnLayout { anchors.centerIn: parent + spacing: layoutSpacing + Text { id: welcomeLabel @@ -71,11 +73,11 @@ Rectangle { id: newAccountButton Layout.alignment: Qt.AlignCenter - Layout.topMargin: 8 Layout.preferredWidth: preferredWidth Layout.preferredHeight: preferredHeight - text: qsTr("CREATE A JAMI ACCOUNT") + text: qsTr("Create a jami account") + fontCapitalization: Font.AllUppercase toolTipText: qsTr("Create new Jami account") source: "qrc:/images/default_avatar_overlay.svg" color: JamiTheme.buttonTintedBlue @@ -91,11 +93,11 @@ Rectangle { id: fromDeviceButton Layout.alignment: Qt.AlignCenter - Layout.topMargin: 8 Layout.preferredWidth: preferredWidth Layout.preferredHeight: preferredHeight - text: qsTr("IMPORT FROM ANOTHER DEVICE") + text: qsTr("Import from another device") + fontCapitalization: Font.AllUppercase toolTipText: qsTr("Import account from other device") source: "qrc:/images/icons/devices-24px.svg" color: JamiTheme.buttonTintedBlue @@ -111,11 +113,11 @@ Rectangle { id: fromBackupButton Layout.alignment: Qt.AlignCenter - Layout.topMargin: 8 Layout.preferredWidth: preferredWidth Layout.preferredHeight: preferredHeight - text: qsTr("CONNECT FROM BACKUP") + text: qsTr("Connect from backup") + fontCapitalization: Font.AllUppercase toolTipText: qsTr("Import account from backup file") source: "qrc:/images/icons/backup-24px.svg" color: JamiTheme.buttonTintedBlue @@ -131,11 +133,11 @@ Rectangle { id: showAdvancedButton Layout.alignment: Qt.AlignCenter - Layout.topMargin: 8 Layout.preferredWidth: preferredWidth Layout.preferredHeight: preferredHeight - text: qsTr("SHOW ADVANCED") + text: qsTr("Show advanced") + fontCapitalization: Font.AllUppercase toolTipText: qsTr("Show advanced options") color: JamiTheme.buttonTintedBlue hoveredColor: JamiTheme.buttonTintedBlueHovered @@ -158,13 +160,13 @@ Rectangle { id: connectAccountManagerButton Layout.alignment: Qt.AlignCenter - Layout.topMargin: 8 Layout.preferredWidth: preferredWidth Layout.preferredHeight: preferredHeight visible: false - text: qsTr("CONNECT TO MANAGEMENT SERVER") + text: qsTr("Connect to management server") + fontCapitalization: Font.AllUppercase toolTipText: qsTr("Login to account manager") source: "qrc:/images/icons/router-24px.svg" color: JamiTheme.buttonTintedBlue @@ -180,13 +182,13 @@ Rectangle { id: newSIPAccountButton Layout.alignment: Qt.AlignCenter - Layout.topMargin: 8 Layout.preferredWidth: preferredWidth Layout.preferredHeight: preferredHeight visible: false - text: qsTr("CREATE A SIP ACCOUNT") + text: qsTr("Create a sip account") + fontCapitalization: Font.AllUppercase toolTipText: qsTr("Create new SIP account") source: "qrc:/images/default_avatar_overlay.svg" color: JamiTheme.buttonTintedBlue @@ -198,4 +200,34 @@ Rectangle { } } } + + HoverableButton { + id: backButton + + anchors.left: parent.left + anchors.top: parent.top + anchors.margins: 20 + + Connections { + target: ClientWrapper.lrcInstance + + function onAccountListChanged() { + backButton.visible = ClientWrapper.utilsAdaptor.getAccountListSize() + } + } + + width: 35 + height: 35 + + visible: ClientWrapper.utilsAdaptor.getAccountListSize() + radius: 30 + + backgroundColor: root.color + onExitColor: root.color + + source: "qrc:/images/icons/ic_arrow_back_24px.svg" + toolTipText: qsTr("Back") + + onClicked: leavePage() + } }