Refactor SignIn, adjustments to HCheckBox & HBox

This commit is contained in:
miruka 2019-12-07 09:38:36 -04:00
parent 150744ab8a
commit 7235611d54
17 changed files with 233 additions and 227 deletions

View File

@ -0,0 +1,3 @@
<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="m16 2c3.309 0 6 2.691 6 6s-2.691 6-6 6-6-2.691-6-6 2.691-6 6-6zm0-2c-4.418 0-8 3.582-8 8s3.582 8 8 8 8-3.582 8-8-3.582-8-8-8zm-5.405 16.4-1.472 1.6h-3.123v2h-2v2h-2v-2.179l5.903-5.976c-.404-.559-.754-1.158-1.038-1.795l-6.865 6.95v5h6v-2h2v-2h2l2.451-2.663c-.655-.249-1.276-.562-1.856-.937zm7.405-11.4c.551 0 1 .449 1 1s-.449 1-1 1-1-.449-1-1 .449-1 1-1zm0-1c-1.104 0-2 .896-2 2s.896 2 2 2 2-.896 2-2-.896-2-2-2z"/>
</svg>

After

Width:  |  Height:  |  Size: 519 B

View File

@ -15,14 +15,6 @@ Rectangle {
property real multiplyWidth: 1.0 property real multiplyWidth: 1.0
property real multiplyHorizontalSpacing: 1.5
property real multiplyVerticalSpacing: 1.5
property int horizontalSpacing:
Math.min(theme.spacing * width / 400, theme.spacing) *
multiplyHorizontalSpacing
property int verticalSpacing: theme.spacing * multiplyVerticalSpacing
property alias title: interfaceTitle.text property alias title: interfaceTitle.text
property alias buttonModel: buttonRepeater.model property alias buttonModel: buttonRepeater.model
@ -51,7 +43,7 @@ Rectangle {
HColumnLayout { HColumnLayout {
id: mainColumn id: mainColumn
width: parent.width width: parent.width
spacing: interfaceBox.verticalSpacing spacing: theme.spacing
HLabel { HLabel {
id: interfaceTitle id: interfaceTitle
@ -62,21 +54,21 @@ Rectangle {
Layout.preferredWidth: parent.width Layout.preferredWidth: parent.width
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: interfaceBox.verticalSpacing Layout.topMargin: theme.spacing
Layout.leftMargin: interfaceBox.horizontalSpacing Layout.leftMargin: theme.spacing
Layout.rightMargin: interfaceBox.horizontalSpacing Layout.rightMargin: theme.spacing
} }
HColumnLayout { HColumnLayout {
id: interfaceBody id: interfaceBody
spacing: interfaceBox.verticalSpacing spacing: theme.spacing
Layout.preferredWidth: parent.width Layout.preferredWidth: parent.width
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: Layout.topMargin:
interfaceTitle.visible ? 0 : interfaceBox.verticalSpacing interfaceTitle.visible ? 0 : theme.spacing
Layout.leftMargin: interfaceBox.horizontalSpacing Layout.leftMargin: theme.spacing
Layout.rightMargin: interfaceBox.horizontalSpacing Layout.rightMargin: theme.spacing
} }
HGridLayout { HGridLayout {

View File

@ -21,8 +21,8 @@ CheckBox {
indicator: Rectangle { indicator: Rectangle {
implicitWidth: implicitHeight implicitWidth: theme.controls.checkBox.boxSize
implicitHeight: mainText.font.pixelSize * 1.5 implicitHeight: implicitWidth
x: box.leftPadding x: box.leftPadding
y: box.topPadding + box.availableHeight / 2 - height / 2 y: box.topPadding + box.availableHeight / 2 - height / 2
radius: theme.radius / 1.5 radius: theme.radius / 1.5

View File

@ -5,9 +5,6 @@ import "../../Base"
import "../../utils.js" as Utils import "../../utils.js" as Utils
HBox { HBox {
horizontalSpacing: currentSpacing
verticalSpacing: currentSpacing
buttonModel: [ buttonModel: [
{ name: "retry", text: qsTr("Retry"), iconName: "retry" }, { name: "retry", text: qsTr("Retry"), iconName: "retry" },
{ name: "cancel", text: qsTr("Cancel"), iconName: "cancel" }, { name: "cancel", text: qsTr("Cancel"), iconName: "cancel" },

View File

@ -4,9 +4,6 @@ import "../../Base"
import "../../utils.js" as Utils import "../../utils.js" as Utils
HBox { HBox {
horizontalSpacing: currentSpacing
verticalSpacing: currentSpacing
buttonModel: [ buttonModel: [
{ name: "export", text: qsTr("Export"), iconName: "export-keys"}, { name: "export", text: qsTr("Export"), iconName: "export-keys"},
{ name: "import", text: qsTr("Import"), iconName: "import-keys"}, { name: "import", text: qsTr("Import"), iconName: "import-keys"},

View File

@ -0,0 +1,15 @@
import QtQuick 2.12
import QtQuick.Layouts 1.12
import "../../Base"
HPage {
HTabbedBoxes {
tabModel: [
qsTr("Sign in"), qsTr("Register"), qsTr("Recovery"),
]
SignIn { Component.onCompleted: forceActiveFocus() }
Item {} // TODO
Item {} // TODO
}
}

View File

@ -0,0 +1,185 @@
import QtQuick 2.12
import QtQuick.Layouts 1.12
import "../../Base"
HBox {
id: signInBox
clickButtonOnEnter: "apply"
onFocusChanged: idField.forceActiveFocus()
buttonModel: [
{
name: "apply",
text: qsTr("Sign in"),
enabled: canSignIn,
iconName: "sign-in",
disableWhileLoading: false
},
{ name: "cancel", text: qsTr("Cancel"), iconName: "cancel"},
]
buttonCallbacks: ({
apply: button => {
button.loading = true
errorMessage.text = ""
let args = [
idField.text, passwordField.text,
undefined, serverField.text,
]
signInTimeout.restart()
py.callCoro("login_client", args, userId => {
signInTimeout.stop()
errorMessage.text = ""
button.loading = false
py.callCoro(
rememberAccount.checked ?
"saved_accounts.add": "saved_accounts.delete",
[userId]
)
pageLoader.showPage(
"AccountSettings/AccountSettings", {userId}
)
}, type => {
if (type === "CancelledError") return
signInTimeout.stop()
let txt = qsTr("Invalid request or login type")
if (type === "MatrixForbidden")
txt = qsTr("Invalid username or password")
if (type === "MatrixUserDeactivated")
txt = qsTr("This account was deactivated")
errorMessage.text = txt
button.loading = false
})
},
cancel: button => {}
})
property string signInWith: "username"
readonly property bool canSignIn:
serverField.text && idField.text && passwordField.text &&
! serverField.error
Timer {
id: signInTimeout
interval: 30 * 1000
onTriggered: {
errorMessage.text =
serverField.knownServerChosen ?
qsTr("This server seems unavailable. Verify your inter" +
"net connection or try again in a few minutes.") :
qsTr("This server seems unavailable. Verify the " +
"entered URL, your internet connection or try " +
"again in a few minutes.")
}
}
HRowLayout {
spacing: theme.spacing * 1.25
Layout.alignment: Qt.AlignHCenter
Layout.topMargin: spacing / 2
Layout.bottomMargin: Layout.topMargin
Repeater {
model: ["username", "email", "phone"]
HButton {
icon.name: modelData
circle: true
checked: signInWith == modelData
enabled: modelData == "username"
autoExclusive: true
onClicked: signInWith = modelData
}
}
}
HTextField {
id: serverField
placeholderText: qsTr("Homeserver URL")
text: "https://matrix.org"
error: ! /.+:\/\/.+/.test(cleanText)
Layout.fillWidth: true
readonly property string cleanText: text.toLowerCase().trim()
// 2019-11-11 https://www.hello-matrix.net/public_servers.php
readonly property var knownServers: [
"https://matrix.org",
"https://chat.weho.st",
"https://tchncs.de",
"https://chat.privacytools.io",
"https://hackerspaces.be",
"https://matrix.allmende.io",
"https://feneas.org",
"https://junta.pl",
"https://perthchat.org",
"https://matrix.tedomum.net",
"https://converser.eu",
"https://ru-matrix.org",
"https://matrix.sibnsk.net",
"https://alternanet.fr",
]
readonly property bool knownServerChosen:
knownServers.includes(cleanText)
}
HTextField {
id: idField
placeholderText: qsTr(
signInWith === "email" ? "Email" :
signInWith === "phone" ? "Phone" :
"Username"
)
Layout.fillWidth: true
}
HTextField {
id: passwordField
placeholderText: qsTr("Password")
echoMode: HTextField.Password
Layout.fillWidth: true
}
HCheckBox {
id: rememberAccount
text: qsTr("Remember my account")
checked: true
Layout.alignment: Qt.AlignHCenter
}
HLabel {
id: errorMessage
wrapMode: Text.Wrap
horizontalAlignment: Text.AlignHCenter
color: theme.colors.errorText
visible: Layout.maximumHeight > 0
Layout.maximumHeight: text ? implicitHeight : 0
Behavior on Layout.maximumHeight { HNumberAnimation {} }
Layout.fillWidth: true
}
}

View File

@ -1,5 +1,4 @@
import QtQuick 2.12 import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12 import QtQuick.Layouts 1.12
import "../../Base" import "../../Base"
import "../../utils.js" as Utils import "../../utils.js" as Utils

View File

@ -89,15 +89,14 @@ HBox {
id: publicCheckBox id: publicCheckBox
text: qsTr("Make this room public") text: qsTr("Make this room public")
subtitle.text: qsTr("Anyone will be able to join without invitation.") subtitle.text: qsTr("Anyone will be able to join without invitation.")
spacing: addChatBox.horizontalSpacing
Layout.maximumWidth: parent.width Layout.fillWidth: true
} }
EncryptCheckBox { EncryptCheckBox {
id: encryptCheckBox id: encryptCheckBox
Layout.maximumWidth: parent.width Layout.fillWidth: true
} }
HCheckBox { HCheckBox {
@ -105,9 +104,8 @@ HBox {
text: qsTr("Reject users from other matrix servers") text: qsTr("Reject users from other matrix servers")
subtitle.text: qsTr("Cannot be changed later!") subtitle.text: qsTr("Cannot be changed later!")
subtitle.color: theme.colors.middleBackground subtitle.color: theme.colors.middleBackground
spacing: addChatBox.horizontalSpacing
Layout.maximumWidth: parent.width Layout.fillWidth: true
} }
HLabel { HLabel {

View File

@ -10,5 +10,4 @@ HCheckBox {
qsTr("Cannot be disabled later!") + qsTr("Cannot be disabled later!") +
"</font>" "</font>"
subtitle.textFormat: Text.StyledText subtitle.textFormat: Text.StyledText
spacing: addChatBox.horizontalSpacing
} }

View File

@ -10,8 +10,12 @@ HBox {
onFocusChanged: userField.forceActiveFocus() onFocusChanged: userField.forceActiveFocus()
buttonModel: [ buttonModel: [
{ name: "apply", text: qsTr("Start chat"), {
iconName: "start-direct-chat", enabled: Boolean(userField.text) }, name: "apply",
text: qsTr("Start chat"),
iconName: "start-direct-chat",
enabled: Boolean(userField.text)
},
{ name: "cancel", text: qsTr("Cancel"), iconName: "cancel" }, { name: "cancel", text: qsTr("Cancel"), iconName: "cancel" },
] ]
@ -74,7 +78,7 @@ HBox {
EncryptCheckBox { EncryptCheckBox {
id: encryptCheckBox id: encryptCheckBox
Layout.maximumWidth: parent.width Layout.fillWidth: true
} }
HLabel { HLabel {

View File

@ -10,8 +10,12 @@ HBox {
onFocusChanged: roomField.forceActiveFocus() onFocusChanged: roomField.forceActiveFocus()
buttonModel: [ buttonModel: [
{ name: "apply", text: qsTr("Join"), iconName: "join", {
enabled: Boolean(roomField.text), }, name: "apply",
text: qsTr("Join"),
iconName: "join",
enabled: Boolean(roomField.text),
},
{ name: "cancel", text: qsTr("Cancel"), iconName: "cancel" }, { name: "cancel", text: qsTr("Cancel"), iconName: "cancel" },
] ]

View File

@ -1,188 +0,0 @@
import QtQuick 2.12
import QtQuick.Layouts 1.12
import "../Base"
HPage {
property string loginWith: "username"
readonly property bool canLogin:
serverField.text && idField.text && passwordField.text &&
! serverField.error
onFocusChanged: idField.forceActiveFocus()
HBox {
id: signInBox
Layout.alignment: Qt.AlignCenter
title: qsTr("Sign in")
clickButtonOnEnter: "login"
buttonModel: [
{ name: "register", text: qsTr("Register"), enabled: false },
{ name: "login", text: qsTr("Login"), enabled: canLogin,
disableWhileLoading: false },
{ name: "forgot", text: qsTr("Forgot?"), enabled: false },
]
buttonCallbacks: ({
register: button => {},
login: button => {
button.loading = true
errorMessage.text = ""
let args = [
idField.text, passwordField.text,
undefined, serverField.text,
]
loginTimeout.restart()
py.callCoro("login_client", args, userId => {
loginTimeout.stop()
errorMessage.text = ""
button.loading = false
py.callCoro(
rememberAccount.checked ?
"saved_accounts.add": "saved_accounts.delete",
[userId]
)
pageLoader.showPage(
"AccountSettings/AccountSettings", {userId}
)
}, type => {
if (type === "CancelledError") return
loginTimeout.stop()
let txt = qsTr("Invalid request or login type")
if (type === "MatrixForbidden")
txt = qsTr("Invalid username or password")
if (type === "MatrixUserDeactivated")
txt = qsTr("This account was deactivated")
errorMessage.text = txt
button.loading = false
})
},
forgot: button => {}
})
Timer {
id: loginTimeout
interval: 30 * 1000
onTriggered: {
errorMessage.text =
serverField.knownServerChosen ?
qsTr("This server seems unavailable. Verify your inter" +
"net connection or try again in a few minutes.") :
qsTr("This server seems unavailable. Verify the " +
"entered URL, your internet connection or try " +
"again in a few minutes.")
}
}
HRowLayout {
spacing: signInBox.horizontalSpacing * 1.25
Layout.alignment: Qt.AlignHCenter
Layout.topMargin: signInBox.verticalSpacing / 2
Layout.bottomMargin: Layout.topMargin
Repeater {
model: ["username", "email", "phone"]
HButton {
icon.name: modelData
circle: true
checked: loginWith == modelData
enabled: modelData == "username"
autoExclusive: true
onClicked: loginWith = modelData
}
}
}
HTextField {
id: serverField
placeholderText: qsTr("Homeserver URL")
text: "https://matrix.org"
error: ! /.+:\/\/.+/.test(cleanText)
Layout.fillWidth: true
readonly property string cleanText: text.toLowerCase().trim()
// 2019-11-11 https://www.hello-matrix.net/public_servers.php
readonly property var knownServers: [
"https://matrix.org",
"https://chat.weho.st",
"https://tchncs.de",
"https://chat.privacytools.io",
"https://hackerspaces.be",
"https://matrix.allmende.io",
"https://feneas.org",
"https://junta.pl",
"https://perthchat.org",
"https://matrix.tedomum.net",
"https://converser.eu",
"https://ru-matrix.org",
"https://matrix.sibnsk.net",
"https://alternanet.fr",
]
readonly property bool knownServerChosen:
knownServers.includes(cleanText)
}
HTextField {
id: idField
placeholderText: qsTr(
loginWith === "email" ? "Email" :
loginWith === "phone" ? "Phone" :
"Username"
)
Layout.fillWidth: true
}
HTextField {
id: passwordField
placeholderText: qsTr("Password")
echoMode: HTextField.Password
Layout.fillWidth: true
}
HCheckBox {
id: rememberAccount
text: qsTr("Automatically sign in")
checked: true
spacing: signInBox.horizontalSpacing
Layout.maximumWidth: parent.width
Layout.alignment: Qt.AlignHCenter
}
HLabel {
id: errorMessage
wrapMode: Text.Wrap
horizontalAlignment: Text.AlignHCenter
color: theme.colors.errorText
visible: Layout.maximumHeight > 0
Layout.maximumHeight: text ? implicitHeight : 0
Behavior on Layout.maximumHeight { HNumberAnimation {} }
Layout.fillWidth: true
}
}
}

View File

@ -44,7 +44,7 @@ BoxPopup {
popup.ok() popup.ok()
if ((modelSources["Account"] || []).length < 2) { if ((modelSources["Account"] || []).length < 2) {
pageLoader.showPage("SignIn") pageLoader.showPage("AddAccount/AddAccount")
} else if (window.uiState.pageProperties.userId == userId) { } else if (window.uiState.pageProperties.userId == userId) {
pageLoader.showPage("Default") pageLoader.showPage("Default")
} }

View File

@ -18,7 +18,7 @@ HRowLayout {
icon.name: "add-account" icon.name: "add-account"
toolTip.text: qsTr("Add another account") toolTip.text: qsTr("Add another account")
backgroundColor: theme.sidePane.settingsButton.background backgroundColor: theme.sidePane.settingsButton.background
onClicked: pageLoader.showPage("SignIn") onClicked: pageLoader.showPage("AddAccount/AddAccount")
Layout.fillHeight: true Layout.fillHeight: true
} }

View File

@ -90,7 +90,7 @@ Item {
Component.onCompleted: { Component.onCompleted: {
if (! py.startupAnyAccountsSaved) { if (! py.startupAnyAccountsSaved) {
pageLoader.showPage("SignIn") pageLoader.showPage("AddAccount/AddAccount")
return return
} }

View File

@ -145,6 +145,7 @@ controls:
checkBox: checkBox:
color checkIconColorize: colors.accentBackground color checkIconColorize: colors.accentBackground
color boxBackground: controls.button.background color boxBackground: controls.button.background
int boxSize: 24 * uiScale
color boxBorder: hsluv(0, 0, 50, 0.3) color boxBorder: hsluv(0, 0, 50, 0.3)
color boxHoveredBorder: colors.accentBackground color boxHoveredBorder: colors.accentBackground