Improve first-run UX
- Replace LoginPage with step-by-step approach to support different login flows - Implement login using SSO
This commit is contained in:
64
imports/NeoChat/Component/Login/Homeserver.qml
Normal file
64
imports/NeoChat/Component/Login/Homeserver.qml
Normal file
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2020 Tobias Fella <fella@posteo.de>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.14
|
||||
import QtQuick.Controls 2.14 as QQC2
|
||||
import QtQuick.Layouts 1.14
|
||||
|
||||
import org.kde.kirigami 2.12 as Kirigami
|
||||
|
||||
import org.kde.neochat 1.0
|
||||
|
||||
LoginStep {
|
||||
id: root
|
||||
|
||||
readonly property var homeserver: customHomeserver.visible ? customHomeserver.text : serverCombo.currentText
|
||||
property bool loading: false
|
||||
|
||||
title: i18n("@title", "Select a Homeserver")
|
||||
|
||||
action: Kirigami.Action {
|
||||
enabled: LoginHelper.homeserverReachable && !customHomeserver.visible || customHomeserver.acceptableInput
|
||||
onTriggered: {
|
||||
// TODO
|
||||
console.log("register todo")
|
||||
}
|
||||
}
|
||||
|
||||
onHomeserverChanged: {
|
||||
LoginHelper.testHomeserver("@user:" + homeserver)
|
||||
}
|
||||
|
||||
Kirigami.FormLayout {
|
||||
Component.onCompleted: Controller.testHomeserver(homeserver)
|
||||
|
||||
QQC2.ComboBox {
|
||||
id: serverCombo
|
||||
|
||||
Kirigami.FormData.label: i18n("Homeserver:")
|
||||
model: ["matrix.org", "kde.org", "tchncs.de", i18n("Other...")]
|
||||
}
|
||||
|
||||
QQC2.TextField {
|
||||
id: customHomeserver
|
||||
|
||||
Kirigami.FormData.label: i18n("Url:")
|
||||
visible: serverCombo.currentIndex === 3
|
||||
onTextChanged: {
|
||||
Controller.testHomeserver(text)
|
||||
}
|
||||
validator: RegularExpressionValidator {
|
||||
regularExpression: /([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9]+(:[0-9]+)?/
|
||||
}
|
||||
}
|
||||
|
||||
QQC2.Button {
|
||||
id: continueButton
|
||||
text: i18nc("@action:button", "Continue")
|
||||
action: root.action
|
||||
}
|
||||
}
|
||||
}
|
||||
23
imports/NeoChat/Component/Login/Loading.qml
Normal file
23
imports/NeoChat/Component/Login/Loading.qml
Normal file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2020 Tobias Fella <fella@posteo.de>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-only
|
||||
*/
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.12 as QQC2
|
||||
import QtQuick.Layouts 1.12
|
||||
|
||||
import org.kde.neochat 1.0
|
||||
|
||||
import NeoChat.Component 1.0
|
||||
|
||||
import org.kde.kirigami 2.12 as Kirigami
|
||||
|
||||
QQC2.BusyIndicator {
|
||||
|
||||
property var showContinueButton: false
|
||||
property var showBackButton: false
|
||||
property string title: i18n("Loading")
|
||||
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
68
imports/NeoChat/Component/Login/Login.qml
Normal file
68
imports/NeoChat/Component/Login/Login.qml
Normal file
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2020 Carl Schwan <carl@carlschwan.eu>
|
||||
* SPDX-FileCopyrightText: 2020 Tobias Fella <fella@posteo.de>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.12 as QQC2
|
||||
import QtQuick.Layouts 1.12
|
||||
|
||||
import org.kde.kirigami 2.12 as Kirigami
|
||||
|
||||
import org.kde.neochat 1.0
|
||||
import NeoChat.Component 1.0
|
||||
|
||||
LoginStep {
|
||||
id: login
|
||||
|
||||
showContinueButton: true
|
||||
showBackButton: false
|
||||
|
||||
title: i18nc("@title", "Login")
|
||||
message: i18n("Enter your Matrix ID")
|
||||
|
||||
Component.onCompleted: {
|
||||
LoginHelper.matrixId = ""
|
||||
}
|
||||
|
||||
Kirigami.FormLayout {
|
||||
QQC2.TextField {
|
||||
id: matrixIdField
|
||||
Kirigami.FormData.label: i18n("Matrix ID:")
|
||||
placeholderText: "@user:matrix.org"
|
||||
onTextChanged: {
|
||||
if(acceptableInput) {
|
||||
LoginHelper.matrixId = text
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
matrixIdField.forceActiveFocus()
|
||||
}
|
||||
|
||||
Keys.onReturnPressed: {
|
||||
login.action.trigger()
|
||||
}
|
||||
|
||||
validator: RegularExpressionValidator {
|
||||
regularExpression: /^\@?[a-zA-Z0-9\._=\-/]+\:[a-zA-Z0-9\-]+(\.[a-zA-Z0-9\-]+)*\.[a-zA-Z]+(:[0-9]+)?$/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
action: Kirigami.Action {
|
||||
text: LoginHelper.testing && matrixIdField.acceptableInput ? i18n("Loading") : i18nc("@action:button", "Continue")
|
||||
onTriggered: {
|
||||
if (LoginHelper.supportsSso && LoginHelper.supportsPassword) {
|
||||
processed("qrc:/imports/NeoChat/Component/Login/LoginMethod.qml");
|
||||
} else if (LoginHelper.supportsPassword) {
|
||||
processed("qrc:/imports/NeoChat/Component/Login/Password.qml");
|
||||
} else {
|
||||
processed("qrc:/imports/NeoChat/Component/Login/Sso.qml");
|
||||
}
|
||||
}
|
||||
enabled: LoginHelper.homeserverReachable
|
||||
}
|
||||
}
|
||||
35
imports/NeoChat/Component/Login/LoginMethod.qml
Normal file
35
imports/NeoChat/Component/Login/LoginMethod.qml
Normal file
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2020 Tobias Fella <fella@posteo.de>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.14
|
||||
import QtQuick.Controls 2.14 as Controls
|
||||
import QtQuick.Layouts 1.14
|
||||
import org.kde.kirigami 2.12 as Kirigami
|
||||
|
||||
import org.kde.neochat 1.0
|
||||
import NeoChat.Component.Login 1.0
|
||||
|
||||
LoginStep {
|
||||
id: loginMethod
|
||||
|
||||
title: i18n("Login Methods")
|
||||
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
Controls.Button {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: i18n("Login with password")
|
||||
Layout.preferredWidth: Kirigami.Units.gridUnit * 12
|
||||
onClicked: processed("qrc:/imports/NeoChat/Component/Login/Password.qml")
|
||||
}
|
||||
|
||||
Controls.Button {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: i18n("Login with single sign-on")
|
||||
Layout.preferredWidth: Kirigami.Units.gridUnit * 12
|
||||
onClicked: processed("qrc:/imports/NeoChat/Component/Login/Sso.qml")
|
||||
}
|
||||
}
|
||||
35
imports/NeoChat/Component/Login/LoginRegister.qml
Normal file
35
imports/NeoChat/Component/Login/LoginRegister.qml
Normal file
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2020 Tobias Fella <fella@posteo.de>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import QtQuick 2.14
|
||||
import QtQuick.Controls 2.14 as Controls
|
||||
import QtQuick.Layouts 1.14
|
||||
|
||||
import org.kde.kirigami 2.12 as Kirigami
|
||||
|
||||
import org.kde.neochat 1.0
|
||||
|
||||
import NeoChat.Component.Login 1.0
|
||||
|
||||
LoginStep {
|
||||
id: loginRegister
|
||||
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
Controls.Button {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: i18n("Login")
|
||||
Layout.preferredWidth: Kirigami.Units.gridUnit * 12
|
||||
onClicked: processed("qrc:/imports/NeoChat/Component/Login/Login.qml")
|
||||
}
|
||||
|
||||
Controls.Button {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: i18n("Register")
|
||||
Layout.preferredWidth: Kirigami.Units.gridUnit * 12
|
||||
onClicked: processed("qrc:/imports/NeoChat/Component/Login/Homeserver.qml")
|
||||
}
|
||||
}
|
||||
28
imports/NeoChat/Component/Login/LoginStep.qml
Normal file
28
imports/NeoChat/Component/Login/LoginStep.qml
Normal file
@@ -0,0 +1,28 @@
|
||||
// SPDX-FileCopyrightText: 2020 Carl Schwan <carlschwan@kde.org>
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import QtQuick 2.14
|
||||
import QtQuick.Controls 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
|
||||
/// Step for the login/registration flow
|
||||
ColumnLayout {
|
||||
|
||||
property string title: i18n("Welcome")
|
||||
property string message: i18n("Welcome")
|
||||
property bool showContinueButton: false
|
||||
property bool showBackButton: false
|
||||
property bool acceptable: false
|
||||
property string previousUrl: ""
|
||||
|
||||
/// Process this module, this is called by the continue button.
|
||||
/// Should call \sa processed when it finish successfully.
|
||||
property Action action: null
|
||||
|
||||
/// Called when switching to the next step.
|
||||
signal processed(url nextUrl)
|
||||
|
||||
signal showMessage(string message)
|
||||
|
||||
}
|
||||
56
imports/NeoChat/Component/Login/Password.qml
Normal file
56
imports/NeoChat/Component/Login/Password.qml
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2020 Tobias Fella <fella@posteo.de>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-only
|
||||
*/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.12 as QQC2
|
||||
import QtQuick.Layouts 1.12
|
||||
|
||||
import org.kde.kirigami 2.12 as Kirigami
|
||||
|
||||
import org.kde.neochat 1.0
|
||||
import NeoChat.Component 1.0
|
||||
|
||||
|
||||
LoginStep {
|
||||
id: password
|
||||
|
||||
title: i18nc("@title", "Password")
|
||||
message: i18n("Enter your password")
|
||||
showContinueButton: true
|
||||
showBackButton: true
|
||||
previousUrl: LoginHelper.isLoggingIn ? "" : LoginHelper.supportsSso ? "qrc:/imports/NeoChat/Component/Login/LoginMethod.qml" : "qrc:/imports/NeoChat/Component/Login/Login.qml"
|
||||
|
||||
action: Kirigami.Action {
|
||||
text: i18nc("@action:button", "Login")
|
||||
enabled: passwordField.text.length > 0 && !LoginHelper.isLoggingIn
|
||||
onTriggered: {
|
||||
LoginHelper.login();
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: LoginHelper
|
||||
function onConnected() {
|
||||
processed("qrc:/imports/NeoChat/Component/Login/Loading.qml")
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.FormLayout {
|
||||
Kirigami.PasswordField {
|
||||
id: passwordField
|
||||
onTextChanged: LoginHelper.password = text
|
||||
enabled: !LoginHelper.isLoggingIn
|
||||
|
||||
Component.onCompleted: {
|
||||
passwordField.forceActiveFocus()
|
||||
}
|
||||
|
||||
Keys.onReturnPressed: {
|
||||
password.action.trigger()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
42
imports/NeoChat/Component/Login/Sso.qml
Normal file
42
imports/NeoChat/Component/Login/Sso.qml
Normal file
@@ -0,0 +1,42 @@
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2020 Tobias Fella <fella@posteo.de>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-only
|
||||
*/
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.12 as QQC2
|
||||
import QtQuick.Layouts 1.12
|
||||
|
||||
import org.kde.neochat 1.0
|
||||
|
||||
import NeoChat.Component 1.0
|
||||
|
||||
import org.kde.kirigami 2.12 as Kirigami
|
||||
|
||||
LoginStep {
|
||||
id: root
|
||||
|
||||
title: i18nc("@title", "Login")
|
||||
message: i18n("Login with single sign-on")
|
||||
|
||||
Kirigami.FormLayout {
|
||||
Connections {
|
||||
target: LoginHelper
|
||||
onSsoUrlChanged: {
|
||||
Qt.openUrlExternally(LoginHelper.ssoUrl)
|
||||
}
|
||||
onConnected: proccessed("qrc:/imports/NeoChat/Component/Login/Loading.qml")
|
||||
}
|
||||
|
||||
QQC2.Button {
|
||||
text: i18n("Login")
|
||||
onClicked: {
|
||||
LoginHelper.loginWithSso()
|
||||
root.showMessage(i18n("Complete the authentification steps in your browser"))
|
||||
}
|
||||
Component.onCompleted: forceActiveFocus()
|
||||
Keys.onReturnPressed: clicked()
|
||||
}
|
||||
}
|
||||
}
|
||||
7
imports/NeoChat/Component/Login/qmldir
Normal file
7
imports/NeoChat/Component/Login/qmldir
Normal file
@@ -0,0 +1,7 @@
|
||||
module NeoChat.Component.Login
|
||||
Login 1.0 Login.qml
|
||||
Password 1.0 Password.qml
|
||||
LoginRegister 1.0 LoginRegister.qml
|
||||
Loading 1.0 Loading.qml
|
||||
LoginMethod 1.0 LoginMethod.qml
|
||||
LoginStep 1.0 LoginStep.qml
|
||||
Reference in New Issue
Block a user