Refactor LoginPage into separate components

This commit is contained in:
miruka 2019-04-27 18:00:28 -04:00
parent 102baccbe5
commit e09efaecda
8 changed files with 195 additions and 150 deletions

View File

@ -1,6 +1,7 @@
- Current focus
- Merge login page
- Remember account dialog
- Just import nio?
- Use new H\* components everywhere
- TextInput.accepted() for SendBox
- Refactoring

View File

@ -10,7 +10,7 @@ ApplicationWindow {
Loader {
anchors.fill: parent
source: Backend.clientManager.clientCount < 1 ?
"pages/LoginPage.qml" : "pages/MainUI.qml"
"pages/LoginPage/LoginPage.qml" : "pages/MainUI.qml"
objectName: "UILoader"
}
}

View File

@ -12,6 +12,15 @@ Button {
property int contentWidth: 0
signal canceled
signal clicked
signal doubleClicked
signal entered
signal exited
signal pressAndHold
signal pressed
signal released
function loadingUntilFutureDone(future) {
loading = true
future.onGotResult.connect(function() { loading = false })
@ -75,17 +84,29 @@ Button {
}
MouseArea {
z: 101
anchors.fill: parent
hoverEnabled: true
propagateComposedEvents: true
onEntered: overlayOpacity = checked ? 0 : 0.3
onExited: overlayOpacity = 0
onPressed: overlayOpacity += 0.3
onCanceled: button.canceled()
onClicked: button.clicked()
onDoubleClicked: button.doubleClicked()
onEntered: {
overlayOpacity = checked ? 0 : 0.3
button.entered()
}
onExited: {
overlayOpacity = 0
button.exited()
}
onPressAndHold: button.pressAndHold()
onPressed: {
overlayOpacity += 0.3
button.pressed()
}
onReleased: {
if (checkable) { checked = ! checked }
overlayOpacity = checked ? 0 : 0.3
button.released()
}
}
}

View File

@ -0,0 +1,57 @@
import QtQuick 2.7
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.4
HScalingBox {
id: interfaceBox
property alias title: interfaceTitle.text
property alias buttonModel: interfaceButtonsRepeater.model
property var buttonCallbacks: []
property string enterButtonTarget: ""
default property alias body: interfaceBody.children
function clickEnterButtonTarget() {
for (var i = 0; i < buttonModel.length; i++) {
var btn = interfaceButtonsRepeater.itemAt(i)
if (btn.name === enterButtonTarget) { btn.clicked() }
}
}
ColumnLayout {
anchors.fill: parent
id: mainColumn
HRowLayout {
Layout.alignment: Qt.AlignHCenter
Layout.margins: interfaceBox.margins
HLabel {
id: interfaceTitle
font.pixelSize: HStyle.fontSize.big
}
}
ColumnLayout { id: interfaceBody }
HRowLayout {
Repeater {
id: interfaceButtonsRepeater
model: []
HButton {
property string name: modelData.name
id: button
text: modelData.text
iconName: modelData.iconName || ""
onClicked: buttonCallbacks[modelData.name](button)
Layout.fillWidth: true
Layout.preferredHeight: 32
}
}
}
}
}

View File

@ -0,0 +1,17 @@
import QtQuick 2.7
Rectangle {
property var container: parent
property real widthForHeight: 0.75
property int baseHeight: 300
property int startScalingUpAboveHeight: 1080
readonly property int baseWidth: baseHeight * widthForHeight
readonly property int margins: baseHeight * 0.03
color: Qt.hsla(1, 1, 1, 0.3)
height: Math.min(container.height, baseHeight)
width: Math.min(container.width, baseWidth)
scale: Math.max(1, container.height / startScalingUpAboveHeight)
}

View File

@ -1,143 +0,0 @@
import QtQuick 2.7
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.4
import "../base" as Base
Image {
id: loginBackground
asynchronous: true
fillMode: Image.PreserveAspectCrop
cache: false
source: "../../images/login_background.jpg"
function login() {
loginButton.loadingUntilFutureDone(Backend.clientManager.new(
"matrix.org", identifierField.text, passwordField.text
))
}
Rectangle {
color: Qt.hsla(1, 1, 1, 0.3)
id: loginBox
property real widthForHeight: 0.75
property int baseHeight: 300
property int baseWidth: baseHeight * widthForHeight
property int startScalingUpAboveHeight: 1080
anchors.centerIn: parent
height: Math.min(parent.height, baseHeight)
width: Math.min(parent.width, baseWidth)
scale: Math.max(1, parent.height / startScalingUpAboveHeight)
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
ColumnLayout {
anchors.fill: parent
id: mainColumn
property int hMargin: loginBox.baseWidth * 0.05
property int vMargin: hMargin * loginBox.widthForHeight
Base.HRowLayout {
Layout.alignment: Qt.AlignHCenter
Layout.margins: mainColumn.hMargin
Layout.topMargin: mainColumn.vMargin
Layout.bottomMargin: mainColumn.vMargin
Base.HLabel {
text: "Sign in"
font.pixelSize: Base.HStyle.fontSize.big
}
}
Item { Layout.fillHeight: true }
Base.HRowLayout {
Layout.margins: mainColumn.hMargin
Layout.topMargin: mainColumn.vMargin
Layout.bottomMargin: mainColumn.vMargin
Layout.alignment: Qt.AlignHCenter
spacing: mainColumn.hMargin * 1.25
Base.HButton {
id: loginWithUsernameButton
iconName: "username"
circle: true
checked: true
checkable: true
autoExclusive: true
}
Base.HButton {
id: loginWithEmailButton
iconName: "email"
circle: true
checkable: true
autoExclusive: true
}
Base.HButton {
id: loginWithPhoneButton
iconName: "phone"
circle: true
checkable: true
autoExclusive: true
}
}
Base.HTextField {
id: identifierField
placeholderText: qsTr(
loginWithEmailButton.checked ? "Email" :
loginWithPhoneButton.checked ? "Phone" :
"Username"
)
onAccepted: login()
Component.onCompleted: forceActiveFocus()
Layout.fillWidth: true
Layout.margins: mainColumn.hMargin
Layout.topMargin: mainColumn.vMargin
Layout.bottomMargin: mainColumn.vMargin
}
Base.HTextField {
id: passwordField
placeholderText: qsTr("Password")
echoMode: TextField.Password
onAccepted: login()
Layout.fillWidth: true
Layout.margins: mainColumn.hMargin
Layout.topMargin: mainColumn.vMargin
Layout.bottomMargin: mainColumn.vMargin
}
Item { Layout.fillHeight: true }
Base.HRowLayout {
Base.HButton {
text: qsTr("Register")
Layout.fillWidth: true
Layout.preferredHeight: 32
}
Base.HButton {
id: loginButton
text: qsTr("Login")
Layout.fillWidth: true
Layout.preferredHeight: 32
MouseArea {
anchors.fill: parent
onClicked: login()
}
}
Base.HButton {
text: qsTr("Forgot?")
Layout.fillWidth: true
Layout.preferredHeight: 32
}
}
}
}
}

View File

@ -0,0 +1,17 @@
import QtQuick 2.7
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.4
import "../../base" as Base
Base.HImage {
id: loginPage
fillMode: Image.PreserveAspectCrop
source: "../../../images/login_background.jpg"
Loader {
anchors.centerIn: parent
Component.onCompleted: setSource(
"SignInBox.qml", { "container": loginPage }
)
}
}

View File

@ -0,0 +1,75 @@
import QtQuick 2.7
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.4
import "../../base" as Base
Base.HInterfaceBox {
id: signInBox
title: "Sign in"
property string loginWith: "username"
enterButtonTarget: "login"
buttonModel: [
{ name: "register", text: qsTr("Register") },
{ name: "login", text: qsTr("Login") },
{ name: "forgot", text: qsTr("Forgot?") }
]
buttonCallbacks: {
"register": function(button) {},
"login": function(button) {
button.loadingUntilFutureDone(
Backend.clientManager.new(
"matrix.org", identifierField.text, passwordField.text
)
)
},
"forgot": function(button) {}
}
Base.HRowLayout {
spacing: signInBox.margins * 1.25
Layout.margins: signInBox.margins
Layout.alignment: Qt.AlignHCenter
Repeater {
model: ["username", "email", "phone"]
Base.HButton {
iconName: modelData
circle: true
checked: loginWith == modelData
autoExclusive: true
onClicked: loginWith = modelData
}
}
}
Base.HTextField {
id: identifierField
placeholderText: qsTr(
loginWith === "email" ? "Email" :
loginWith === "phone" ? "Phone" :
"Username"
)
onAccepted: signInBox.clickEnterButtonTarget()
Component.onCompleted: forceActiveFocus()
Layout.fillWidth: true
Layout.margins: signInBox.margins
}
Base.HTextField {
id: passwordField
placeholderText: qsTr("Password")
echoMode: TextField.Password
onAccepted: signInBox.clickEnterButtonTarget()
Layout.fillWidth: true
Layout.margins: signInBox.margins
}
}