Refactor LoginPage into separate components
This commit is contained in:
parent
102baccbe5
commit
e09efaecda
3
TODO.md
3
TODO.md
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
57
harmonyqml/components/base/HInterfaceBox.qml
Normal file
57
harmonyqml/components/base/HInterfaceBox.qml
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
17
harmonyqml/components/base/HScalingBox.qml
Normal file
17
harmonyqml/components/base/HScalingBox.qml
Normal 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)
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
17
harmonyqml/components/pages/LoginPage/LoginPage.qml
Normal file
17
harmonyqml/components/pages/LoginPage/LoginPage.qml
Normal 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 }
|
||||
)
|
||||
}
|
||||
}
|
75
harmonyqml/components/pages/LoginPage/SignInBox.qml
Normal file
75
harmonyqml/components/pages/LoginPage/SignInBox.qml
Normal 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
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user