Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

Commit a232118a authored by Melvin Keskin's avatar Melvin Keskin Committed by Linus Jahn

Use consistent fields for JIDs and passwords and improve login page

 * Validate entered JID and password
 * Add show/hide button for password
 * Disable connect button if JID or password are invalid
 * Focus JID field after loading login page
 * Focus field with invalid input if connect button is clicked or enter key pressed
Signed-off-by: Linus Jahn's avatarLinus Jahn <lnj@kaidan.im>
parent c289c1f9
......@@ -37,6 +37,7 @@ set(KAIDAN_SOURCES
src/CameraImageCapture.cpp
src/MediaUtils.cpp
src/MediaRecorder.cpp
src/CredentialsValidator.cpp
# needed to trigger moc generation / to be displayed in IDEs
src/Enums.h
......
/*
* Kaidan - A user-friendly XMPP client for every device!
*
* Copyright (C) 2016-2020 Kaidan developers and contributors
* (see the LICENSE file for a full list of copyright authors)
*
* Kaidan is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* In addition, as a special exception, the author of Kaidan gives
* permission to link the code of its release with the OpenSSL
* project's "OpenSSL" library (or with modified versions of it that
* use the same license as the "OpenSSL" library), and distribute the
* linked executables. You must obey the GNU General Public License in
* all respects for all of the code used other than "OpenSSL". If you
* modify this file, you may extend this exception to your version of
* the file, but you are not obligated to do so. If you do not wish to
* do so, delete this exception statement from your version.
*
* Kaidan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Kaidan. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CredentialsValidator.h"
#include <QXmppUtils.h>
CredentialsValidator::CredentialsValidator(QObject *parent)
: QObject(parent)
{
}
bool CredentialsValidator::isJidValid(const QString &jid)
{
return jid.count('@') == 1 && isUsernameValid(QXmppUtils::jidToUser(jid)) && isServerValid(QXmppUtils::jidToDomain(jid));
}
bool CredentialsValidator::isUsernameValid(const QString &username)
{
return !(username.isEmpty() || username.contains(" "));
}
bool CredentialsValidator::isServerValid(const QString &server)
{
return !(server.isEmpty() || server.contains(" "));
}
bool CredentialsValidator::isPasswordValid(const QString &password)
{
return !password.isEmpty();
}
/*
* Kaidan - A user-friendly XMPP client for every device!
*
* Copyright (C) 2016-2020 Kaidan developers and contributors
* (see the LICENSE file for a full list of copyright authors)
*
* Kaidan is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* In addition, as a special exception, the author of Kaidan gives
* permission to link the code of its release with the OpenSSL
* project's "OpenSSL" library (or with modified versions of it that
* use the same license as the "OpenSSL" library), and distribute the
* linked executables. You must obey the GNU General Public License in
* all respects for all of the code used other than "OpenSSL". If you
* modify this file, you may extend this exception to your version of
* the file, but you are not obligated to do so. If you do not wish to
* do so, delete this exception statement from your version.
*
* Kaidan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Kaidan. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CREDENTIALSVALIDATOR_H
#define CREDENTIALSVALIDATOR_H
#include <QObject>
/**
* This is a validator for XMPP account credentials.
*/
class CredentialsValidator : public QObject
{
Q_OBJECT
public:
CredentialsValidator(QObject *parent = nullptr);
/**
* Returns true if the given string is a valid JID.
*
* @param jid JID to be validated
*/
Q_INVOKABLE static bool isJidValid(const QString &jid);
/**
* Returns true if the given string is a valid username.
*
* @param username username to be validated
*/
Q_INVOKABLE static bool isUsernameValid(const QString &username);
/**
* Returns true if the given string is a valid server.
*
* @param username server to be validated
*/
Q_INVOKABLE static bool isServerValid(const QString &server);
/**
* Returns true if the given string is a valid password.
*
* @param password password to be validated
*/
Q_INVOKABLE static bool isPasswordValid(const QString &password);
};
#endif // CREDENTIALSVALIDATOR_H
......@@ -68,6 +68,7 @@
#include "MediaSettingModel.h"
#include "MediaUtils.h"
#include "MediaRecorder.h"
#include "CredentialsValidator.h"
#ifdef STATIC_BUILD
#include "static_plugins.h"
......@@ -229,6 +230,7 @@ Q_DECL_EXPORT int main(int argc, char *argv[])
qRegisterMetaType<ImageEncoderSettings>();
qRegisterMetaType<AudioEncoderSettings>();
qRegisterMetaType<VideoEncoderSettings>();
qRegisterMetaType<CredentialsValidator*>();
// Enums for c++ member calls using enums
qRegisterMetaType<Enums::ConnectionState>();
......@@ -349,6 +351,7 @@ Q_DECL_EXPORT int main(int argc, char *argv[])
qmlRegisterType<MediaSettingsVideoCodecModel>(APPLICATION_ID, 1, 0, "MediaSettingsVideoCodecModel");
qmlRegisterType<MediaSettingsVideoFrameRateModel>(APPLICATION_ID, 1, 0, "MediaSettingsVideoFrameRateModel");
qmlRegisterType<MediaRecorder>(APPLICATION_ID, 1, 0, "MediaRecorder");
qmlRegisterType<CredentialsValidator>(APPLICATION_ID, 1, 0, "CredentialsValidator");
qmlRegisterUncreatableType<QAbstractItemModel>("EmojiModel", 0, 1, "QAbstractItemModel", "Used by proxy models");
qmlRegisterUncreatableType<Emoji>("EmojiModel", 0, 1, "Emoji", "Used by emoji models");
......
......@@ -36,6 +36,7 @@ import org.kde.kirigami 2.8 as Kirigami
import im.kaidan.kaidan 1.0
import "elements"
import "elements/fields"
Kirigami.Page {
title: qsTr("Log in")
......@@ -66,31 +67,24 @@ Kirigami.Page {
Layout.alignment: Qt.AlignCenter
Layout.maximumWidth: Kirigami.Units.gridUnit * 25
// JID field
Controls.Label {
id: jidLabel
text: qsTr("Your Jabber-ID:")
}
Controls.TextField {
JidField {
id: jidField
text: kaidan.jid
placeholderText: qsTr("user@example.org")
Layout.fillWidth: true
selectByMouse: true
inputMethodHints: Qt.ImhEmailCharactersOnly
}
// Password field
Controls.Label {
text: qsTr("Your Password:")
// Simulate the pressing of the connect button.
inputField {
onAccepted: connectButton.clicked()
}
}
Controls.TextField {
id: passField
text: kaidan.password
echoMode: TextInput.Password
selectByMouse: true
Layout.fillWidth: true
// password field
PasswordField {
id: passwordField
// Simulate the pressing of the connect button.
inputField {
onAccepted: connectButton.clicked()
}
}
// Connect button
......@@ -112,21 +106,20 @@ Kirigami.Page {
}
]
// Connect to the server and authenticate by the entered credentials if the JID is valid and a password entered.
onClicked: {
// connect to given account data
kaidan.jid = jidField.text
kaidan.password = passField.text
kaidan.mainConnect()
}
}
// connect when return was pressed
Keys.onPressed: {
if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
if (jidField.activeFocus)
passField.forceActiveFocus()
else
connectButton.clicked()
// If the JID is invalid, focus its field.
if (!jidField.valid) {
jidField.forceFocus()
// If the password is invalid, focus its field.
// This also implies that if the JID field is focused and the password invalid, the password field will be focused instead of immediately trying to connect.
} else if (!passwordField.valid) {
passwordField.forceFocus()
} else {
kaidan.jid = jidField.text
kaidan.password = passwordField.text
kaidan.mainConnect()
}
}
}
}
......@@ -137,6 +130,10 @@ Kirigami.Page {
}
}
Component.onCompleted: {
jidField.forceFocus()
}
Connections {
target: kaidan
......
/*
* Kaidan - A user-friendly XMPP client for every device!
*
* Copyright (C) 2016-2020 Kaidan developers and contributors
* (see the LICENSE file for a full list of copyright authors)
*
* Kaidan is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* In addition, as a special exception, the author of Kaidan gives
* permission to link the code of its release with the OpenSSL
* project's "OpenSSL" library (or with modified versions of it that
* use the same license as the "OpenSSL" library), and distribute the
* linked executables. You must obey the GNU General Public License in
* all respects for all of the code used other than "OpenSSL". If you
* modify this file, you may extend this exception to your version of
* the file, but you are not obligated to do so. If you do not wish to
* do so, delete this exception statement from your version.
*
* Kaidan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Kaidan. If not, see <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.7
import im.kaidan.kaidan 1.0
/**
* This is the base for fields which are used to enter credentials.
*/
Field {
valid: false
property alias credentialsValidator: credentialsValidator
CredentialsValidator {
id: credentialsValidator
}
}
/*
* Kaidan - A user-friendly XMPP client for every device!
*
* Copyright (C) 2016-2020 Kaidan developers and contributors
* (see the LICENSE file for a full list of copyright authors)
*
* Kaidan is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* In addition, as a special exception, the author of Kaidan gives
* permission to link the code of its release with the OpenSSL
* project's "OpenSSL" library (or with modified versions of it that
* use the same license as the "OpenSSL" library), and distribute the
* linked executables. You must obey the GNU General Public License in
* all respects for all of the code used other than "OpenSSL". If you
* modify this file, you may extend this exception to your version of
* the file, but you are not obligated to do so. If you do not wish to
* do so, delete this exception statement from your version.
*
* Kaidan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Kaidan. If not, see <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.7
import QtQuick.Controls 2.3 as Controls
import QtQuick.Layouts 1.3
import org.kde.kirigami 2.8 as Kirigami
/**
* This is a text field which can be focused and show a hint for invalid input.
*/
ColumnLayout {
// text of the label for the input field
property alias labelText: label.text
// input field
property alias inputField: inputField
// placeholder text for the input field
property alias placeholderText: inputField.placeholderText
// input method hints for the input field
property alias inputMethodHints: inputField.inputMethodHints
// entered text
property alias text: inputField.text
// text to be shown as a hint if the entered text is not valid
property alias invalidHintText: invalidHint.text
// validity of the entered text
property bool valid: true
// requirement for showing the hint for invalid input
property bool invalidHintMayBeShown: false
// label for the input field
Controls.Label {
id: label
}
RowLayout {
// input field
Kirigami.ActionTextField {
id: inputField
Layout.fillWidth: true
selectByMouse: true
// Show a hint for the first time if the entered text is not valid as soon as the input field loses the focus.
onFocusChanged: {
if (!focus && !invalidHintMayBeShown) {
invalidHintMayBeShown = true
toggleHintForInvalidText()
}
}
}
// icon for an invalid input
Kirigami.Icon {
id: invalidIcon
visible: invalidHint.visible
source: "error"
width: Kirigami.Units.iconSizes.smallMedium
height: width
}
}
// hint for entering a valid input
Controls.Label {
id: invalidHint
visible: false
Layout.fillWidth: true
leftPadding: 5
rightPadding: 5
wrapMode: Text.Wrap
color: Kirigami.Theme.neutralTextColor
}
/**
* Shows a hint if the entered text is not valid or hides it otherwise.
* If invalidHintMayBeShown was initially set to false, that is only done if the input field has lost the focus at least one time because of its onFocusChanged().
*/
function toggleHintForInvalidText() {
invalidHint.visible = !valid && invalidHintMayBeShown && invalidHintText.length > 0;
}
/**
* Focuses the input field.
* If the input field is already focused, the focusing is executed again to trigger its onFocusChanged().
*/
function forceFocus() {
if (inputField.focus)
inputField.focus = false
inputField.forceActiveFocus()
}
}
/*
* Kaidan - A user-friendly XMPP client for every device!
*
* Copyright (C) 2016-2020 Kaidan developers and contributors
* (see the LICENSE file for a full list of copyright authors)
*
* Kaidan is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* In addition, as a special exception, the author of Kaidan gives
* permission to link the code of its release with the OpenSSL
* project's "OpenSSL" library (or with modified versions of it that
* use the same license as the "OpenSSL" library), and distribute the
* linked executables. You must obey the GNU General Public License in
* all respects for all of the code used other than "OpenSSL". If you
* modify this file, you may extend this exception to your version of
* the file, but you are not obligated to do so. If you do not wish to
* do so, delete this exception statement from your version.
*
* Kaidan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Kaidan. If not, see <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.7
import im.kaidan.kaidan 1.0
/**
* This is a JID field with a hint for invalid JIDs.
*/
CredentialsField {
labelText: qsTr("Chat address")
placeholderText: qsTr("user@example.org")
inputMethodHints: Qt.ImhEmailCharactersOnly
invalidHintText: qsTr("The chat address must have the form <b>username@server</b>")
// Validate the entered JID and show a hint if it is not valid.
onTextChanged: {
valid = credentialsValidator.isJidValid(text)
toggleHintForInvalidText()
}
}
/*
* Kaidan - A user-friendly XMPP client for every device!
*
* Copyright (C) 2016-2020 Kaidan developers and contributors
* (see the LICENSE file for a full list of copyright authors)
*
* Kaidan is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* In addition, as a special exception, the author of Kaidan gives
* permission to link the code of its release with the OpenSSL
* project's "OpenSSL" library (or with modified versions of it that
* use the same license as the "OpenSSL" library), and distribute the
* linked executables. You must obey the GNU General Public License in
* all respects for all of the code used other than "OpenSSL". If you
* modify this file, you may extend this exception to your version of
* the file, but you are not obligated to do so. If you do not wish to
* do so, delete this exception statement from your version.
*
* Kaidan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Kaidan. If not, see <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.7
import org.kde.kirigami 2.8 as Kirigami
import im.kaidan.kaidan 1.0
/**
* This is a password field with a hint for empty passwords and an option for showing the password.
*/
CredentialsField {
labelText: qsTr("Password")
invalidHintText: qsTr("Please enter a valid password")
// indicator for showing the hidden password
property bool showPassword: false
// Add a button for showing and hiding the entered password.
inputField {
echoMode: showPassword ? TextInput.Normal : TextInput.Password
rightActions: [
Kirigami.Action {
iconName: showPassword ? "password-show-on" : "password-show-off"
onTriggered: showPassword = !showPassword
}
]
}
// Validate the entered password and show a hint if it is not valid.
onTextChanged: {
valid = credentialsValidator.isPasswordValid(text)
toggleHintForInvalidText()
}
}
......@@ -46,6 +46,11 @@
<file>elements/TextAvatar.qml</file>
<file>elements/Avatar.qml</file>
<file>elements/fields/Field.qml</file>
<file>elements/fields/CredentialsField.qml</file>
<file>elements/fields/JidField.qml</file>
<file>elements/fields/PasswordField.qml</file>
<file>settings/SettingsItem.qml</file>
<file>settings/SettingsPage.qml</file>
<file>settings/SettingsSheet.qml</file>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment