ui: revamp login view to match latest designs
This includes changing the account selector from being a modal to a drop down menu, which also includes an option to generate a new account. In addition, it adds the status logo plus a dedicated headline. Closes: #5623 #5624
This commit is contained in:
parent
fcd728ed94
commit
1b7be6060d
|
@ -0,0 +1,69 @@
|
||||||
|
import QtQuick 2.13
|
||||||
|
import QtQuick.Controls 2.13
|
||||||
|
import QtQuick.Dialogs 1.3
|
||||||
|
|
||||||
|
import StatusQ.Core 0.1
|
||||||
|
import StatusQ.Core.Theme 0.1
|
||||||
|
import StatusQ.Components 0.1
|
||||||
|
import StatusQ.Popups 0.1
|
||||||
|
|
||||||
|
import shared.controls.chat 1.0
|
||||||
|
import utils 1.0
|
||||||
|
|
||||||
|
MenuItem {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property string label: ""
|
||||||
|
property string colorId: ""
|
||||||
|
property var colorHash
|
||||||
|
property url image: ""
|
||||||
|
signal clicked()
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
height: 64
|
||||||
|
background: Rectangle {
|
||||||
|
color: root.hovered ? Theme.palette.statusSelect.menuItemHoverBackgroundColor : Theme.palette.statusSelect.menuItemBackgroundColor
|
||||||
|
}
|
||||||
|
MouseArea {
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
anchors.fill: root
|
||||||
|
onClicked: {
|
||||||
|
root.clicked()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: userImageOrIcon
|
||||||
|
sourceComponent: !!root.image.toString() || !!root.colorId ? userImage : addIcon
|
||||||
|
anchors.leftMargin: Style.current.padding
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: addIcon
|
||||||
|
StatusRoundIcon {
|
||||||
|
icon.name: "add"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: userImage
|
||||||
|
UserImage {
|
||||||
|
name: root.label
|
||||||
|
image: root.image
|
||||||
|
colorId: root.colorId
|
||||||
|
colorHash: root.colorHash
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusBaseText {
|
||||||
|
text: root.label
|
||||||
|
font.pixelSize: 15
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.left: userImageOrIcon.right
|
||||||
|
anchors.leftMargin: 16
|
||||||
|
color: !!root.colorId ? Theme.palette.directColor1 : Theme.palette.primaryColor1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -4,17 +4,21 @@ import QtQuick.Layouts 1.13
|
||||||
import QtQuick.Dialogs 1.3
|
import QtQuick.Dialogs 1.3
|
||||||
import QtGraphicalEffects 1.13
|
import QtGraphicalEffects 1.13
|
||||||
|
|
||||||
|
import StatusQ.Core 0.1
|
||||||
|
import StatusQ.Core.Theme 0.1
|
||||||
|
import StatusQ.Components 0.1
|
||||||
import StatusQ.Controls 0.1 as StatusQControls
|
import StatusQ.Controls 0.1 as StatusQControls
|
||||||
|
import StatusQ.Popups 0.1
|
||||||
|
|
||||||
import shared.panels 1.0
|
import shared.panels 1.0
|
||||||
import shared.popups 1.0
|
import shared.popups 1.0
|
||||||
import shared.status 1.0
|
import shared.status 1.0
|
||||||
import shared.controls 1.0
|
import shared.controls 1.0
|
||||||
import shared.controls.chat 1.0
|
import shared.controls.chat 1.0
|
||||||
|
import "../panels"
|
||||||
import "../popups"
|
import "../popups"
|
||||||
import "../stores"
|
import "../stores"
|
||||||
|
|
||||||
import StatusQ.Components 0.1
|
|
||||||
|
|
||||||
import utils 1.0
|
import utils 1.0
|
||||||
|
|
||||||
|
@ -84,29 +88,28 @@ Item {
|
||||||
Item {
|
Item {
|
||||||
id: element
|
id: element
|
||||||
width: 360
|
width: 360
|
||||||
height: 200
|
height: childrenRect.height
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
UserImage {
|
Image {
|
||||||
id: userImage
|
id: statusIcon
|
||||||
|
width: 140
|
||||||
|
height: 140
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
source: Style.svg("status-logo-circle")
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
image: LoginStore.currentAccount.thumbnailImage
|
|
||||||
name: LoginStore.currentAccount.username
|
|
||||||
colorId: LoginStore.currentAccount.colorId
|
|
||||||
colorHash: LoginStore.currentAccount.colorHash
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StatusBaseText {
|
||||||
id: usernameText
|
id: welcomeBackText
|
||||||
text: LoginStore.currentAccount.username
|
text: qsTr("Welcome back")
|
||||||
font.weight: Font.Bold
|
font.weight: Font.Bold
|
||||||
font.pixelSize: 17
|
font.pixelSize: 17
|
||||||
anchors.top: userImage.bottom
|
anchors.top: statusIcon.bottom
|
||||||
anchors.topMargin: 4
|
anchors.topMargin: 10
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
color: Theme.palette.directColor1
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfirmAddExistingKeyModal {
|
ConfirmAddExistingKeyModal {
|
||||||
|
@ -127,57 +130,91 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Item {
|
||||||
property bool isHovered: false
|
id: userInfo
|
||||||
id: changeAccountBtn
|
height: userImage.height
|
||||||
width: 24
|
anchors.top: welcomeBackText.bottom
|
||||||
height: 24
|
anchors.topMargin: 64
|
||||||
anchors.left: usernameText.right
|
width: 318
|
||||||
anchors.leftMargin: 4
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
anchors.verticalCenter: usernameText.verticalCenter
|
|
||||||
|
|
||||||
color: isHovered ? Style.current.backgroundHover : Style.current.transparent
|
UserImage {
|
||||||
|
id: userImage
|
||||||
|
image: LoginStore.currentAccount.thumbnailImage
|
||||||
|
name: LoginStore.currentAccount.username
|
||||||
|
colorId: LoginStore.currentAccount.colorId
|
||||||
|
colorHash: LoginStore.currentAccount.colorHash
|
||||||
|
anchors.left: parent.left
|
||||||
|
}
|
||||||
|
|
||||||
radius: 4
|
StatusBaseText {
|
||||||
|
id: usernameText
|
||||||
|
text: LoginStore.currentAccount.username
|
||||||
|
font.pixelSize: 17
|
||||||
|
anchors.left: userImage.right
|
||||||
|
anchors.leftMargin: 16
|
||||||
|
anchors.verticalCenter: userImage.verticalCenter
|
||||||
|
color: Theme.palette.directColor1
|
||||||
|
}
|
||||||
|
|
||||||
SVGImage {
|
StatusQControls.StatusFlatRoundButton {
|
||||||
id: caretImg
|
icon.name: "chevron-down"
|
||||||
width: 10
|
type: StatusQControls.StatusFlatRoundButton.Type.Tertiary
|
||||||
height: 6
|
width: 24
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
height: 24
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
id: changeAccountBtn
|
||||||
source: Style.svg("caret")
|
anchors.verticalCenter: usernameText.verticalCenter
|
||||||
fillMode: Image.PreserveAspectFit
|
anchors.right: parent.right
|
||||||
}
|
|
||||||
ColorOverlay {
|
|
||||||
anchors.fill: caretImg
|
onClicked: {
|
||||||
source: caretImg
|
if (accountsPopup.opened) {
|
||||||
color: Style.current.secondaryText
|
accountsPopup.close()
|
||||||
}
|
} else {
|
||||||
MouseArea {
|
accountsPopup.popup(width-userInfo.width-16, userInfo.height+4)
|
||||||
hoverEnabled: true
|
}
|
||||||
anchors.fill: parent
|
}
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onEntered: {
|
StatusPopupMenu {
|
||||||
changeAccountBtn.isHovered = true
|
id: accountsPopup
|
||||||
}
|
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
|
||||||
onExited: {
|
width: 346
|
||||||
changeAccountBtn.isHovered = false
|
dim: false
|
||||||
}
|
Repeater {
|
||||||
onClicked: {
|
id: accounts
|
||||||
if (LoginStore.rowCount() > 1) {
|
model: LoginStore.loginModuleInst.accountsModel
|
||||||
selectAnotherAccountModal.open()
|
delegate: AccountMenuItemPanel {
|
||||||
} else {
|
label: model.username
|
||||||
confirmAddExstingKeyModal.open()
|
image: model.thumbnailImage
|
||||||
|
colorId: model.colorId
|
||||||
|
colorHash: model.colorHash
|
||||||
|
onClicked: {
|
||||||
|
LoginStore.setCurrentAccount(index)
|
||||||
|
resetLogin()
|
||||||
|
accountsPopup.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AccountMenuItemPanel {
|
||||||
|
label: qsTr("Generate new account")
|
||||||
|
onClicked: {
|
||||||
|
accountsPopup.close()
|
||||||
|
genKeyClicked();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Input {
|
Input {
|
||||||
id: txtPassword
|
id: txtPassword
|
||||||
anchors.top: changeAccountBtn.bottom
|
anchors.top: userInfo.bottom
|
||||||
anchors.topMargin: Style.current.padding * 2
|
anchors.topMargin: Style.current.padding * 2
|
||||||
|
anchors.left: undefined
|
||||||
|
anchors.right: undefined
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
width: 318
|
||||||
enabled: !loading
|
enabled: !loading
|
||||||
placeholderText: loading ?
|
placeholderText: loading ?
|
||||||
//% "Connecting..."
|
//% "Connecting..."
|
||||||
|
@ -185,7 +222,6 @@ Item {
|
||||||
//% "Enter password"
|
//% "Enter password"
|
||||||
qsTrId("enter-password")
|
qsTrId("enter-password")
|
||||||
textField.echoMode: TextInput.Password
|
textField.echoMode: TextInput.Password
|
||||||
textField.focus: true
|
|
||||||
Keys.onReturnPressed: {
|
Keys.onReturnPressed: {
|
||||||
doLogin(textField.text)
|
doLogin(textField.text)
|
||||||
}
|
}
|
||||||
|
@ -204,9 +240,9 @@ Item {
|
||||||
icon.width: 18
|
icon.width: 18
|
||||||
icon.height: 14
|
icon.height: 14
|
||||||
opacity: (loading || txtPassword.text.length > 0) ? 1 : 0
|
opacity: (loading || txtPassword.text.length > 0) ? 1 : 0
|
||||||
anchors.left: txtPassword.visible? txtPassword.right : changeAccountBtn.right
|
anchors.left: txtPassword.right
|
||||||
anchors.leftMargin: (loading || txtPassword.text.length > 0) ? Style.current.padding : Style.current.smallPadding
|
anchors.leftMargin: (loading || txtPassword.text.length > 0) ? Style.current.padding : Style.current.smallPadding
|
||||||
anchors.verticalCenter: txtPassword.visible? txtPassword.verticalCenter : changeAccountBtn.verticalCenter
|
anchors.verticalCenter: txtPassword.verticalCenter
|
||||||
state: loading ? "pending" : "default"
|
state: loading ? "pending" : "default"
|
||||||
onClicked: {
|
onClicked: {
|
||||||
doLogin(txtPassword.textField.text)
|
doLogin(txtPassword.textField.text)
|
||||||
|
@ -244,24 +280,12 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusQControls.StatusFlatButton {
|
|
||||||
id: generateKeysLinkText
|
|
||||||
//% "Generate new keys"
|
|
||||||
text: qsTrId("generate-new-keys")
|
|
||||||
anchors.top: txtPassword.visible? txtPassword.bottom : changeAccountBtn.bottom
|
|
||||||
anchors.topMargin: 16
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
onClicked: {
|
|
||||||
genKeyClicked();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
id: errMsg
|
id: errMsg
|
||||||
//% "Login failed. Please re-enter your password and try again."
|
//% "Login failed. Please re-enter your password and try again."
|
||||||
readonly property string incorrectPasswordMsg: qsTrId("login-failed--please-re-enter-your-password-and-try-again-")
|
readonly property string incorrectPasswordMsg: qsTrId("login-failed--please-re-enter-your-password-and-try-again-")
|
||||||
anchors.top: generateKeysLinkText.bottom
|
anchors.top: txtPassword.bottom
|
||||||
anchors.topMargin: Style.current.smallPadding
|
anchors.topMargin: Style.current.padding
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
visible: false
|
visible: false
|
||||||
text: incorrectPasswordMsg
|
text: incorrectPasswordMsg
|
||||||
|
|
Loading…
Reference in New Issue