Login.qml Example File

socialtodos/Login.qml
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtEnginio module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of The Qt Company Ltd nor the names of its
**     contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/

import QtQuick 2.1
import QtQuick.Layouts 1.0
import QtQuick.Controls 1.0 as Controls
import Enginio 1.0

Rectangle {
    width: 400
    height: 600

    Rectangle {
        id: header
        anchors.top: parent.top
        width: parent.width
        height: 70 * scaleFactor
        color: "white"

        Row {
            id: logo
            anchors.centerIn: parent
            anchors.horizontalCenterOffset: -4
            spacing: 4
            Image {
                source: "qrc:images/enginio.png"
                width: 160 * scaleFactor ; height: 60 * scaleFactor
                fillMode: Image.PreserveAspectFit
            }
            Text {
                text: "Todos"
                anchors.verticalCenter: parent.verticalCenter
                anchors.verticalCenterOffset: -3
                font.bold: true
                font.pixelSize: 46 * scaleFactor
                color: "#555"
            }
        }
        Rectangle {
            width: parent.width ; height: 1
            anchors.bottom: parent.bottom
            color: "#bbb"
        }
    }

    BorderImage {
        id: input

        width: parent.width
        anchors.top: header.bottom
        anchors.bottom: parent.bottom
        source: "qrc:images/delegate.png"
        border.left: 5; border.top: 5
        border.right: 5; border.bottom: 5

        Rectangle {
            y: -1 ; height: 1
            width: parent.width
            color: "#bbb"
        }
        Rectangle {
            y: 0 ; height: 1
            width: parent.width
            color: "white"
        }
    }

    Column {
        anchors.centerIn: parent
        anchors.alignWhenCentered: true
        width: 360 * scaleFactor
        spacing: 14 * intScaleFactor

        TextField {
            id: nameInput
            onAccepted: passwordInput.forceActiveFocus()
            placeholderText: "Username"
            KeyNavigation.tab: passwordInput
        }

        TextField {
            id: passwordInput
            onAccepted: login()
            placeholderText: "Password"
            echoMode: TextInput.Password
            KeyNavigation.tab: loginButton
        }

        Row {
            // button
            spacing: 20 * scaleFactor
            width: 360 * scaleFactor
            anchors.horizontalCenter: parent.horizontalCenter
            anchors.alignWhenCentered: true
            TouchButton {
                id: loginButton
                text: "Login"
                baseColor: "#7a5"
                width: (parent.width - parent.spacing)/2
                onClicked: login()
                enabled: enginioClient.authenticationState !== Enginio.Authenticating && nameInput.text.length && passwordInput.text.length
                KeyNavigation.tab: registerButton
            }
            TouchButton {
                id: registerButton
                text: "Register"
                onClicked: registerAndLogin()
                width: (parent.width - parent.spacing)/2
                enabled: enginioClient.authenticationState !== Enginio.Authenticating && nameInput.text.length && passwordInput.text.length
                KeyNavigation.tab: nameInput
            }
        }
    }

    Text {
        id: statusText
        anchors.bottom: parent.bottom
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.bottomMargin: 70 * scaleFactor
        font.pixelSize: 18 * scaleFactor
        color: "#444"
    }

    Component.onCompleted: {
        enginioClient.sessionAuthenticationError.connect(function(reply){
            statusText.text = "Login failed: " + reply.errorString
        })

       enginioClient.sessionAuthenticated.connect(function(reply){
           addUserToAllUsersGroup(reply.data.enginio_data.user.id)
        })
    }

    Controls.Stack.onStatusChanged: {
        if (Controls.Stack.status == Controls.Stack.Activating) {
            nameInput.text = ""
            passwordInput.text = ""
            statusText.text = ""
            nameInput.forceActiveFocus()
        }
    }

    function login() {
        statusText.text = "Logging in..."
        enginioClient.identity = null
        auth.user = nameInput.text
        auth.password = passwordInput.text
        enginioClient.identity = auth
    }

    // Register a new user and add her to the group "allUsers"
    function registerAndLogin() {
        statusText.text = "Creating user account..."
        var createAccount = enginioClient.create({ "username": nameInput.text, "password": passwordInput.text }, Enginio.UserOperation)
        createAccount.finished.connect(function() {
            if (createAccount.errorType !== EnginioReply.NoError) {
                statusText.text = "Account creation failed: " + createAccount.errorString
            } else {
                login()
            }
        })
    }

    function addUserToAllUsersGroup(userId) {
        var groupQuery = enginioClient.query({ "query": { "name" : "allUsers" } }, Enginio.UsergroupOperation)

        groupQuery.finished.connect(function(){
            if (groupQuery.errorType !== EnginioReply.NoError) {
                statusText.text = groupQuery.errorString
            } else if (groupQuery.data.results.length === 0 ){
                statusText.text = "Usergroup 'allUsers' not found, check required backend configuration from Social Todos example documentation."
            } else {
                var addUserToGroupData = {
                    "id": groupQuery.data.results[0].id,
                    "member" : {
                        "id": userId,
                        "objectType": "users"
                    }
                }
                var addUserToGroup = enginioClient.create(addUserToGroupData, Enginio.UsergroupMembersOperation)
                addUserToGroup.finished.connect(function(){
                    if (addUserToGroup.errorType === EnginioReply.NoError) {
                        switchToListsView()
                    } else if (addUserToGroup.errorType === EnginioReply.BackendError &&
                               addUserToGroup.backendStatus === 400) {
                        //User already present in group, OK to proceed
                        switchToListsView()
                    } else {
                        statusText.text = "User add to group failed: " + JSON.stringify(addUserToGroup.data.errors[0])
                    }
                })
            }
        })
    }

    function switchToListsView() {
        mainView.push({ item: lists, properties: {"username": enginioClient.identity.user}})
    }
}