Improved login usability

Locations automatically fast forward to login skipping location
  selection if just one location is available
RsLoginPassView nicer look
This commit is contained in:
Gioacchino Mazzurco 2017-04-04 02:15:22 +02:00
parent 8e03fab8da
commit 70e91f7164
4 changed files with 121 additions and 78 deletions

View File

@ -19,5 +19,6 @@
<file>qml/icons/document-share.png</file> <file>qml/icons/document-share.png</file>
<file>qml/icons/application-menu.png</file> <file>qml/icons/application-menu.png</file>
<file>qml/ContactSort.js</file> <file>qml/ContactSort.js</file>
<file>qml/icons/emblem-locked.png</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -50,8 +50,10 @@ Item
buttonText: "Save" buttonText: "Save"
onSubmit: onSubmit:
{ {
var jsonData = { pgp_name: login, ssl_name: login, pgp_password: password } var jsonData = { pgp_name: login, ssl_name: login,
rsApi.request("/control/create_location/", JSON.stringify(jsonData)) pgp_password: password }
rsApi.request("/control/create_location/",
JSON.stringify(jsonData))
locationView.state = "selectLocation" locationView.state = "selectLocation"
} }
} }
@ -72,76 +74,40 @@ Item
rsApi.request( "/control/login/", rsApi.request( "/control/login/",
JSON.stringify({id: locationView.sslid}) ) JSON.stringify({id: locationView.sslid}) )
locationView.attemptLogin = true locationView.attemptLogin = true
busyIndicator.running = true
attemptTimer.start() attemptTimer.start()
} }
} }
} }
] ]
function requestLocationsList() { rsApi.request("/control/locations/", "") } function requestLocationsListCB(par)
onFocusChanged: focus && requestLocationsList()
LibresapiLocalClient
{ {
id: rsApi var jsonData = JSON.parse(par.response).data
Component.onCompleted: if(jsonData.length === 1)
{ {
openConnection(apiSocketPath) // There is only one location so we can jump selecting location
locationView.requestLocationsList() var location = jsonData[0]
loginView.login = location.name
locationView.sslid = location.peer_id
locationView.state = "login"
} }
onGoodResponseReceived: else
{ {
var jsonData = JSON.parse(msg) // There is more then one location to choose from
locationsModel.json = par.response
if(jsonData)
{
if(jsonData.data)
{
if(jsonData.data[0] && jsonData.data[0].pgp_id)
{
// if location list update
locationsModel.json = msg
busyIndicator.running = false
}
if (jsonData.data.key_name)
{
if(jsonData.data.want_password)
{
// if Server requested password
var jsonPass = { password: locationView.password }
rsApi.request( "/control/password/",
JSON.stringify(jsonPass) )
locationView.attemptLogin = false
console.debug("RS core asked for password")
}
else
{
// if Already logged in
bottomButton.enabled = false
bottomButton.text = "Already logged in"
locationView.attemptLogin = false
busyIndicator.running = false
locationView.state = "selectLocation"
locationsListView.enabled = false
console.debug("Already logged in")
}
}
}
}
} }
} }
function requestLocationsList()
{ rsApi.request("/control/locations/", "", requestLocationsListCB) }
BusyIndicator { id: busyIndicator; anchors.centerIn: parent } onFocusChanged: focus && requestLocationsList()
Component.onCompleted: requestLocationsList()
JSONListModel JSONListModel
{ {
id: locationsModel id: locationsModel
query: "$.data[*]" query: "$.data[*]"
} }
ListView ListView
{ {
id: locationsListView id: locationsListView
@ -151,22 +117,23 @@ Item
model: locationsModel.model model: locationsModel.model
delegate: Button delegate: Button
{ {
text: model.name text: model.name
onClicked: onClicked:
{ {
loginView.login = text loginView.login = text
locationView.sslid = model.id locationView.sslid = model.id
locationView.state = "login" locationView.state = "login"
} }
} }
visible: false visible: false
} }
Button Button
{ {
id: bottomButton id: bottomButton
text: "Create new location" text: "Create new location"
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
onClicked: locationView.state = "createLocation" onClicked: locationView.state = "createLocation"
} }
@ -177,19 +144,60 @@ Item
anchors.fill: parent anchors.fill: parent
} }
BusyIndicator
{
id: busyIndicator
anchors.centerIn: parent
running: false
Connections
{
target: locationView
onAttemptLoginChanged:
if(locationView.attemptLogin) busyIndicator.running = true
}
}
LibresapiLocalClient
{
id: loginApi
Component.onCompleted: openConnection(apiSocketPath)
onGoodResponseReceived:
{
var jsonData = JSON.parse(msg)
if(jsonData && jsonData.data && jsonData.data.key_name)
{
if(jsonData.data.want_password)
{
// if Server requested password
var jsonPass = { password: locationView.password }
request( "/control/password/", JSON.stringify(jsonPass) )
locationView.attemptLogin = false
console.debug("RS core asked for password")
}
else
{
// if Already logged in
bottomButton.enabled = false
bottomButton.text = "Unlocking location..."
locationView.attemptLogin = false
locationView.state = "selectLocation"
locationsListView.enabled = false
console.debug("Already logged in")
}
}
}
}
Timer Timer
{ {
id: attemptTimer id: attemptTimer
interval: 500 interval: 1000
repeat: true repeat: true
triggeredOnStart: true triggeredOnStart: true
onTriggered: onTriggered:
{ {
if(locationView.focus)
locationView.requestLocationsList()
if (locationView.attemptLogin) if (locationView.attemptLogin)
rsApi.request("/control/password/", "") loginApi.request("/control/password/", "")
} }
} }
} }

View File

@ -19,13 +19,12 @@
import QtQuick 2.0 import QtQuick 2.0
import QtQuick.Layouts 1.3 import QtQuick.Layouts 1.3
import QtQuick.Controls 2.0 import QtQuick.Controls 2.0
import QtQml 2.2 //import QtQml 2.2
import org.retroshare.qml_components.LibresapiLocalClient 1.0
Item Item
{ {
id: loginView id: loginView
property string buttonText: "Login" property string buttonText: "Unlock"
property string login property string login
property string password property string password
signal submit(string login, string password) signal submit(string login, string password)
@ -34,19 +33,54 @@ Item
{ {
id: inputView id: inputView
width: parent.width width: parent.width
anchors.top: parent.top anchors.centerIn: parent
anchors.bottom: bottomButton.top
Row { Text {text: "Name:" } TextField { id: nameField; text: loginView.login } } Image
Row { Text {text: "Password:" } TextField { id: passwordField; text: loginView.password } } {
} source: "qrc:/qml/icons/emblem-locked.png"
Layout.alignment: Qt.AlignHCenter
}
Button Text
{ {
id: bottomButton text: "Login"
text: loginView.buttonText visible: loginView.login.length === 0
anchors.bottom: parent.bottom Layout.alignment: Qt.AlignHCenter
anchors.right: parent.right anchors.bottom: nameField.top
onClicked: loginView.submit(nameField.text, passwordField.text) anchors.bottomMargin: 5
}
TextField
{
id: nameField;
text: loginView.login
visible: loginView.login.length === 0
Layout.alignment: Qt.AlignHCenter
}
Text
{
id: passLabel
text: nameField.visible ?
"Passphrase" : "Enter passphrase for " + loginView.login
Layout.alignment: Qt.AlignHCenter
anchors.bottom: passwordField.top
anchors.bottomMargin: 5
}
TextField
{
id: passwordField
text: loginView.password
width: passLabel.width
echoMode: TextInput.Password
Layout.alignment: Qt.AlignHCenter
}
Button
{
id: bottomButton
text: loginView.buttonText
onClicked: loginView.submit(nameField.text, passwordField.text)
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
}
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB