1
0
Fork 0
mirror of https://git.jami.net/savoirfairelinux/jami-client-qt.git synced 2025-07-15 21:15:24 +02:00

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
This commit is contained in:
Ming Rui Zhang 2020-09-04 14:57:36 -04:00
parent c5687508cd
commit 2e0e250a2c
15 changed files with 469 additions and 410 deletions

View file

@ -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>

View file

@ -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

View file

@ -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

View file

@ -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"
}
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

View file

@ -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
}

View file

@ -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)

View file

@ -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
}

View file

@ -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()
}
}

View file

@ -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
}
}

View file

@ -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()
}
}

View file

@ -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()
}
}

View file

@ -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()
}
}

View file

@ -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 {

View file

@ -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
}
}

View file

@ -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()
}
}