diff --git a/qml.qrc b/qml.qrc index 6a45fb228895c60058137d1b250ea7aae34bcd74..fcc6b2d32dc7e91415b4c4902e740df7e8053e84 100644 --- a/qml.qrc +++ b/qml.qrc @@ -45,7 +45,6 @@ <file>src/wizardview/components/BackupKeyPage.qml</file> <file>src/wizardview/components/ImportFromDevicePage.qml</file> <file>src/wizardview/components/ConnectToAccountManagerPage.qml</file> - <file>src/wizardview/components/SpinnerPage.qml</file> <file>src/wizardview/components/ProfilePage.qml</file> <file>src/wizardview/components/CollapsiblePasswordWidget.qml</file> <file>src/MainApplicationWindow.qml</file> @@ -111,5 +110,6 @@ <file>src/commoncomponents/Scaffold.qml</file> <file>src/constant/JamiQmlUtils.qml</file> <file>src/wizardview/components/AccountCreationStepIndicator.qml</file> + <file>src/commoncomponents/SpinnerButton.qml</file> </qresource> </RCC> diff --git a/src/accountadapter.cpp b/src/accountadapter.cpp index d924bff9093dce70dc262840025c1961838ca97b..723db1e904e4af8c08b5352c39ad21e703c3a9d0 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 2129873f8b0361d350e44aeb1674bacecff4dfc8..969a3c54f126f42e95f4186a0a77d07cac4976a5 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 f7a43222ee99c7d5ee7fcb4d43d9c1024c18f41e..a2829c119a1ea6e4b587b5d2c8cf0346d176337e 100644 --- a/src/commoncomponents/MaterialLineEdit.qml +++ b/src/commoncomponents/MaterialLineEdit.qml @@ -1,7 +1,24 @@ +/* + * Copyright (C) 2020 by Savoir-faire Linux + * Author: Sébastien blin <sebastien.blin@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + import QtQuick 2.14 import QtQuick.Controls 2.14 import QtQuick.Layouts 1.14 -import QtQuick.Controls.Styles 1.4 import QtGraphicalEffects 1.15 import "../constant" @@ -9,6 +26,7 @@ import "../constant" TextField { enum BorderColorMode { NORMAL, + SEARCHING, RIGHT, ERROR } @@ -17,37 +35,39 @@ TextField { property int fieldLayoutHeight: 48 property bool layoutFillwidth: false - property int borderColorMode: InfoLineEdit.NORMAL - property var iconSource: { - if (readOnly) { - return "" - } - switch(borderColorMode){ - case InfoLineEdit.RIGHT: - return "qrc:/images/icons/round-check_circle-24px.svg" - case InfoLineEdit.NORMAL: - return "" - case InfoLineEdit.ERROR: - return "qrc:/images/icons/round-error-24px.svg" - } - } + property int borderColorMode: MaterialLineEdit.NORMAL + property var iconSource: "" property var backgroundColor: JamiTheme.rgb256(240,240,240) - property var borderColor: { - if (!enabled) { - return "transparent" - } + property var borderColor: "#333" + + signal imageClicked + + onBorderColorModeChanged: { + if (!enabled) + borderColor = "transparent" + if (readOnly) + iconSource = "" + switch(borderColorMode){ - case InfoLineEdit.NORMAL: - return "#333" - case InfoLineEdit.RIGHT: - return "green" - case InfoLineEdit.ERROR: - return "red" + case MaterialLineEdit.SEARCHING: + iconSource = "qrc:/images/jami_rolling_spinner.gif" + borderColor = "#333" + break + case MaterialLineEdit.NORMAL: + iconSource = "" + borderColor = "#333" + break + case MaterialLineEdit.RIGHT: + iconSource = "qrc:/images/icons/round-check_circle-24px.svg" + borderColor = "green" + break + case MaterialLineEdit.ERROR: + iconSource = "qrc:/images/icons/round-error-24px.svg" + borderColor = "red" + break } } - signal imageClicked - wrapMode: Text.Wrap readOnly: false selectByMouse: true @@ -58,12 +78,17 @@ TextField { verticalAlignment: Text.AlignVCenter Image { - source: iconSource - width: 24 - height: 24 + id: lineEditImage + anchors.verticalCenter: parent.verticalCenter anchors.right: parent.right anchors.rightMargin: 16 + + width: 24 + height: 24 + + visible: borderColorMode !== MaterialLineEdit.SEARCHING + source: borderColorMode === MaterialLineEdit.SEARCHING ? "" : iconSource layer { enabled: true effect: ColorOverlay { @@ -76,7 +101,7 @@ TextField { anchors.fill: parent hoverEnabled: true acceptedButtons: Qt.LeftButton - enabled: borderColorMode === InfoLineEdit.RIGHT + enabled: borderColorMode === MaterialLineEdit.RIGHT onReleased: { imageClicked() @@ -84,6 +109,21 @@ TextField { } } + AnimatedImage { + anchors.left: lineEditImage.left + anchors.verticalCenter: parent.verticalCenter + + width: 24 + height: 24 + + source: borderColorMode !== MaterialLineEdit.SEARCHING ? "" : iconSource + playing: true + paused: false + fillMode: Image.PreserveAspectFit + mipmap: true + visible: borderColorMode === MaterialLineEdit.SEARCHING + } + background: Rectangle { anchors.fill: parent radius: 4 diff --git a/src/commoncomponents/SpinnerButton.qml b/src/commoncomponents/SpinnerButton.qml new file mode 100644 index 0000000000000000000000000000000000000000..44326d5a83441991bc5508c97d3d5a97ace51498 --- /dev/null +++ b/src/commoncomponents/SpinnerButton.qml @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2020 by Savoir-faire Linux + * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +import QtQuick 2.14 +import QtQuick.Controls 2.14 +import net.jami.Models 1.0 + +MaterialButton { + id: root + + property bool spinnerTriggered: false + property string spinnerTriggeredtext: value + property string normalText: value + + animatedImageSource: spinnerTriggered ? "qrc:/images/jami_rolling_spinner.gif" : "" + text: spinnerTriggered ? spinnerTriggeredtext : normalText + color: !enabled ? JamiTheme.buttonTintedGreyInactive : + JamiTheme.wizardBlueButtons + + hoveredColor: JamiTheme.buttonTintedBlueHovered + pressedColor: JamiTheme.buttonTintedBluePressed +} diff --git a/src/settingsview/SettingsView.qml b/src/settingsview/SettingsView.qml index d20929d5f45325413a060e41970af6c1523dc12c..62cb2cb602ebb224c7ccb8ae0edef6b2714a7bc3 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 6aea2ea9335a64a0b8ab9ae7ecfb024b8e284619..7e0fd9aa770b3dd403923f682c983ede84a9ec20 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 7576b93227de5c4575f36c12449b241d63a54d00..afd988511bc842bc14c36f1fd8e67dee3038351e 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 8e694da49610f13d75b4869fbab3f8400d703e87..39ced2f30a09b737801042ec57647a47138ed5b7 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 d0f02390a856c8d4a4a37b2df7cd8ed8c679b69c..899289bf218d8059559699210ea1ba5a603c9fa7 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 98f5827080e86c2b42d0eeb35549aa7c232e33ff..9d0907384aaeb68620f022e604f6e52ddd1e17e1 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 d4d786e66b09ead29016547414065cb11d046e2d..f3edcc3ce09bba66990708776bd9ac6e0b61bd95 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 f1e64dda0a08d7e67648c13dfd1a784d89a07395..557d082423bfa3a7baf037ffd5d8c3ee48f7c151 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 2fb3f8d094295511026cc975603cd99fb9907d48..0000000000000000000000000000000000000000 --- a/src/wizardview/components/SpinnerPage.qml +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2020 by Savoir-faire Linux - * Author: Yang Wang <yang.wang@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - */ - -import QtQuick 2.14 -import QtQuick.Layouts 1.3 -import QtQuick.Controls 2.14 - -import "../../constant" - -ColumnLayout { - Layout.fillWidth: true - Layout.fillHeight: true - spacing: 6 - - property bool successState: true - property string progressLabelEditText: "Generating your Jami account" - - Item { - Layout.alignment: Qt.AlignHCenter - Layout.preferredHeight: 40 - Layout.fillWidth: true - Layout.fillHeight: true - } - Label { - id: spinnerLabel - Layout.alignment: Qt.AlignHCenter - Layout.minimumWidth: 200 - Layout.minimumHeight: 200 - - Layout.maximumWidth: 16777215 - Layout.maximumHeight: 16777215 - - property string spinnerDisplyState: successState ? "spinnerLabel_Regular" : "spinnerLabel_Failure" - onSpinnerDisplyStateChanged: { - switch (spinnerDisplyState) { - case "spinnerLabel_Regular": - background = Qt.createQmlObject("import QtQuick 2.14; -AnimatedImage { -source: \"qrc:/images/jami_eclipse_spinner.gif\" - -playing: true -paused: false -fillMode: Image.PreserveAspectFit -mipmap: true -}", spinnerLabel) - break - case "spinnerLabel_Failure": - background = Qt.createQmlObject("import QtQuick 2.14; -import \"qrc:/src/constant/\"; -Image { -anchors.fill: parent; -source:\"image://tintedPixmap/\" + (\"qrc:/images/icons/baseline-error_outline-24px.svg\").replace(\"qrc:/images/icons/\", \"\") + \"+\" + JamiTheme.urgentOrange_; -mipmap: true;}", spinnerLabel) - break - } - } - } - Item { - Layout.alignment: Qt.AlignHCenter - Layout.preferredHeight: 40 - Layout.fillWidth: true - Layout.fillHeight: true - } - Label { - id: progressLabel - Layout.alignment: Qt.AlignHCenter - text: successState ? progressLabelEditText : "Error creating account" - font.pointSize: 11 - font.kerning: true - - property string progressLabelState: successState ? "color_success" : "color_fail" - onProgressLabelStateChanged: { - switch (progressLabelState) { - case "color_success": - background = Qt.createQmlObject( - "import QtQuick 2.14; Rectangle { anchors.fill: parent; color: \"transparent\"; }", - progressLabel) - break - case "color_fail": - background = Qt.createQmlObject( - "import QtQuick 2.14; Rectangle { anchors.fill: parent; color: \"red\"; }", - progressLabel) - break - } - } - } - Item { - Layout.alignment: Qt.AlignHCenter - Layout.minimumHeight: 20 - Layout.maximumHeight: 20 - Layout.preferredHeight: 20 - Layout.fillWidth: true - Layout.fillHeight: false - } -} diff --git a/src/wizardview/components/WelcomePage.qml b/src/wizardview/components/WelcomePage.qml index f1ea2787f4ef18bc355a1723c5de4c8eeafa4298..c15d66f97c0217ce51f0e56ef6365082494dfef6 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() + } }