From 9a4246e2756073b62234abe67743fa95a58274a5 Mon Sep 17 00:00:00 2001 From: Slava Monich Date: Sun, 18 Oct 2020 01:16:15 +0300 Subject: [PATCH] Tweaked InitializationPage UI 1. Only load app icon once 2. Removed come unused ids and attributes 3. EnterKey magic 4. Use FadeAnimation --- qml/pages/InitializationPage.qml | 661 ++++++++++++++----------------- 1 file changed, 300 insertions(+), 361 deletions(-) diff --git a/qml/pages/InitializationPage.qml b/qml/pages/InitializationPage.qml index 02f59d9..46ec314 100644 --- a/qml/pages/InitializationPage.qml +++ b/qml/pages/InitializationPage.qml @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with Fernschreiber. If not, see . */ -import QtQuick 2.6 +import QtQuick 2.0 import Sailfish.Silica 1.0 import WerkWolf.Fernschreiber 1.0 @@ -29,11 +29,6 @@ Page { property int authorizationState: TelegramAPI.Closed property var authorizationStateData: null - BusyLabel { - text: qsTr("Loading...") - running: initializationPage.loading - } - Component.onCompleted: { initializationPage.authorizationState = tdLibWrapper.getAuthorizationState(); initializationPage.authorizationStateData = tdLibWrapper.getAuthorizationStateData(); @@ -44,6 +39,7 @@ Page { initializationPage.loading = false; welcomeColumn.visible = false; enterPinColumn.visible = true; + enterPinField.focus = true enterPasswordColumn.visible = false; waitRegistrationColumn.visible = false; break; @@ -60,6 +56,7 @@ Page { enterPinColumn.visible = false; enterPasswordColumn.visible = false; waitRegistrationColumn.visible = true; + pageHeader.title = qsTr("User Registration") break; default: // Nothing ;) @@ -73,6 +70,7 @@ Page { case TelegramAPI.WaitCode: initializationPage.loading = false; enterPinColumn.visible = true; + enterPinField.focus = true enterPasswordColumn.visible = false; waitRegistrationColumn.visible = false; break; @@ -103,21 +101,21 @@ Page { SilicaFlickable { id: welcomeFlickable - contentHeight: contentItem.childrenRect.height + contentHeight: content.height Behavior on contentHeight { NumberAnimation {} } anchors.fill: parent Column { - id: welcomeColumn + id: content width: parent.width - spacing: Theme.paddingSmall + spacing: Theme.paddingLarge PageHeader { + id: pageHeader title: qsTr("Welcome to Fernschreiber!") } Image { - id: fernschreiberImage source: "../../images/fernschreiber.png" anchors { horizontalCenter: parent.horizontalCenter @@ -125,374 +123,315 @@ Page { fillMode: Image.PreserveAspectFit asynchronous: true - width: 1/2 * parent.width + width: Math.min(2 * Theme.itemSizeHuge, Math.min(Screen.width, Screen.height) / 2) } - Label { - id: enterPhoneNumberLabel - wrapMode: Text.Wrap - x: Theme.horizontalPageMargin - width: parent.width - ( 2 * Theme.horizontalPageMargin ) - horizontalAlignment: Text.AlignHCenter - text: qsTr("Please enter your phone number to continue.") - font.pixelSize: Theme.fontSizeMedium - anchors { - horizontalCenter: parent.horizontalCenter - } + BusyLabel { + text: qsTr("Loading...") + running: initializationPage.loading + Behavior on opacity { FadeAnimation {} } + visible: opacity > 0 } - TextField { - id: phoneNumberTextField - placeholderText: "Use the international format, e.g. +4912342424242" - inputMethodHints: Qt.ImhDialableCharactersOnly - labelVisible: false + Column { + id: welcomeColumn width: parent.width - } + spacing: Theme.paddingLarge - Button { - id: continueWithPhoneNumberButton - text: qsTr("Continue") - anchors { - horizontalCenter: parent.horizontalCenter - } - enabled: phoneNumberTextField.text.match(/\+[1-9][0-9]{4,}/g) - onClicked: { - initializationPage.loading = true; - welcomeColumn.visible = false; - tdLibWrapper.setAuthenticationPhoneNumber(phoneNumberTextField.text); - } - } + Behavior on opacity { FadeAnimation {} } + opacity: visible ? 1 : 0 - } - - Column { - id: pinErrorColumn -// y: ( parent.height - ( errorInfoLabel.height + fernschreiberErrorImage.height + errorOkButton.height + ( 3 * Theme.paddingSmall ) ) ) / 2 - width: parent.width - spacing: Theme.paddingSmall - - Behavior on opacity { NumberAnimation {} } - opacity: visible ? 1 : 0 - visible: false - - Image { - id: fernschreiberErrorImage - source: "../../images/fernschreiber.png" - anchors { - horizontalCenter: parent.horizontalCenter + InfoLabel { + text: qsTr("Please enter your phone number to continue.") } - fillMode: Image.PreserveAspectFit - asynchronous: true - width: 1/2 * parent.width - } - - InfoLabel { - id: errorInfoLabel - font.pixelSize: Theme.fontSizeLarge - text: "" - } - - Button { - id: errorOkButton - text: qsTr("OK") - anchors { - horizontalCenter: parent.horizontalCenter - } - onClicked: { - pinErrorColumn.visible = false; - welcomeColumn.visible = true; - } - } - } - - Column { - id: enterPasswordColumn -// y: ( parent.height - ( fernschreiberPasswordImage.height + enterPasswordLabel.height + enterPasswordField.height + enterPasswordButton.height + ( 3 * Theme.paddingSmall ) ) ) / 2 - width: parent.width - spacing: Theme.paddingSmall - - Behavior on opacity { NumberAnimation {} } - opacity: visible ? 1.0 : 0.0 - visible: false - - Image { - id: fernschreiberPasswordImage - source: "../../images/fernschreiber.png" - anchors { - horizontalCenter: parent.horizontalCenter - } - - fillMode: Image.PreserveAspectFit - asynchronous: true - width: 1/2 * parent.width - } - - InfoLabel { - id: enterPasswordLabel - font.pixelSize: Theme.fontSizeLarge - text: qsTr("Please enter your password:") - } - - PasswordField { - id: enterPasswordField - anchors { - horizontalCenter: parent.horizontalCenter - } - font.pixelSize: Theme.fontSizeLarge - width: parent.width - 2 * Theme.horizontalPageMargin - horizontalAlignment: TextInput.AlignHCenter - } - - Button { - id: enterPasswordButton - text: qsTr("OK") - anchors { - horizontalCenter: parent.horizontalCenter - } - onClicked: { - initializationPage.loading = true; - enterPasswordColumn.visible = false; - tdLibWrapper.setAuthenticationPassword(enterPasswordField.text); - } - } - } - - Column { - id: enterPinColumn - topPadding: Theme.paddingLarge - bottomPadding: Theme.paddingLarge - width: parent.width - spacing: Theme.paddingSmall - - Behavior on opacity { NumberAnimation {} } - opacity: visible ? 1.0 : 0.0 - visible: false - - - Image { - id: fernschreiberPinImage - source: "../../images/fernschreiber.png" - anchors { - horizontalCenter: parent.horizontalCenter - } - - fillMode: Image.PreserveAspectFit - asynchronous: true - width: 1/2 * parent.width - } - - InfoLabel { - id: enterPinLabel - font.pixelSize: Theme.fontSizeLarge - text: qsTr("Please enter the code that you received:") - } - - TextField { - id: enterPinField - anchors { - horizontalCenter: parent.horizontalCenter - } - inputMethodHints: Qt.ImhDigitsOnly - font.pixelSize: Theme.fontSizeExtraLarge - width: parent.width - 4 * Theme.paddingLarge - horizontalAlignment: TextInput.AlignHCenter - } - - Button { - id: enterPinButton - text: qsTr("OK") - anchors { - horizontalCenter: parent.horizontalCenter - } - onClicked: { - initializationPage.loading = true; - enterPinColumn.visible = false; - tdLibWrapper.setAuthenticationCode(enterPinField.text); - } - } - } - - Column { - id: linkingErrorColumn - topPadding: Theme.paddingLarge - bottomPadding: Theme.paddingLarge - width: parent.width - spacing: Theme.paddingSmall - - Behavior on opacity { NumberAnimation {} } - opacity: visible ? 1.0 : 0.0 - visible: false - - Image { - id: fernschreiberLinkingErrorImage - source: "../../images/fernschreiber.png" - anchors { - horizontalCenter: parent.horizontalCenter - } - - fillMode: Image.PreserveAspectFit - asynchronous: true - width: 1/2 * parent.width - } - - InfoLabel { - id: linkingErrorInfoLabel - font.pixelSize: Theme.fontSizeLarge - text: qsTr("Unable to authenticate you with the entered code.") - } - - Button { - id: enterPinAgainButton - text: qsTr("Enter code again") - anchors { - horizontalCenter: parent.horizontalCenter - } - onClicked: { - linkingErrorColumn.visible = false; - enterPinColumn.visible = true; - } - } - - Button { - id: restartAuthenticationButton - text: qsTr("Restart authentication") - anchors { - horizontalCenter: parent.horizontalCenter - } - onClicked: { - linkingErrorColumn.visible = false; - welcomeColumn.visible = true; - } - } - } - - Column { - id: waitRegistrationColumn - topPadding: Theme.paddingLarge - bottomPadding: Theme.paddingLarge - width: parent.width - spacing: Theme.paddingLarge - - Behavior on opacity { NumberAnimation {} } - opacity: visible ? 1.0 : 0.0 - visible: false - - PageHeader { - title: qsTr("User Registration") - } - Image { - id: waitRegistrationImage - source: "../../images/fernschreiber.png" - anchors { - horizontalCenter: parent.horizontalCenter - } - - fillMode: Image.PreserveAspectFit - asynchronous: true - width: 1/2 * Screen.width - } - - InfoLabel { - id: waitRegistrationInfoLabel - property bool acknowledged - font.pixelSize: Theme.fontSizeExtraSmall - textFormat: Text.StyledText - horizontalAlignment: Text.AlignLeft - linkColor: Theme.primaryColor - property var stateText: initializationPage.authorizationStateData.authorization_state && initializationPage.authorizationStateData.authorization_state.terms_of_service ? - initializationPage.authorizationStateData.authorization_state.terms_of_service.text : - null - visible: !!stateText && !acknowledged - text: { - if(!stateText) { - return ''; + TextField { + id: phoneNumberTextField + placeholderText: "Use the international format, e.g. +4912342424242" + inputMethodHints: Qt.ImhDialableCharactersOnly + labelVisible: false + width: parent.width + readonly property bool validInput: text.match(/\+[1-9][0-9]{4,}/g) + EnterKey.iconSource: "image://theme/icon-m-enter-next" + EnterKey.enabled: validInput + EnterKey.onClicked: { + validator = filledValidator + if(acceptableInput) { + continueWithPhoneNumberButton.focus = true + continueWithPhoneNumberButton.enter() + } } - var entities = stateText.entities; - if(entities && entities.length > 0 && entities[0]["type"]["@type"] === "textEntityTypeTextUrl") { //we just use the first entity for now. - var offset = entities[0].offset; - var length = entities[0].length; - return (stateText.text.slice(0,entities[0].offset) - + "" - + stateText.text.slice(entities[0].offset, entities[0].offset + entities[0].length) - + '' - + stateText.text.slice(entities[0].offset + entities[0].length)).replace(/\n/gm, "
"); + } + + Button { + id: continueWithPhoneNumberButton + text: qsTr("Continue") + anchors { + horizontalCenter: parent.horizontalCenter + } + enabled: phoneNumberTextField.validInput + onClicked: enter() + function enter() { + initializationPage.loading = true; + welcomeColumn.visible = false; + tdLibWrapper.setAuthenticationPhoneNumber(phoneNumberTextField.text); } - return stateText.text.replace(/\n/gm, "
"); - - - } - //JSON.stringify(initializationPage.authorizationStateData, null, 2)//qsTr("Unable to authenticate you with the entered code.") - } - - Button { - id: acknowledgeTOCButton - visible: waitRegistrationInfoLabel.visible - text: qsTr("OK") - anchors { - horizontalCenter: parent.horizontalCenter - } - onClicked: { - waitRegistrationInfoLabel.acknowledged = true; - userFirstNameTextField.focus = true } } - RegExpValidator { - id: filledValidator - regExp: /.+/ - } - TextField { - id: userFirstNameTextField - visible: !waitRegistrationInfoLabel.visible - opacity: visible ? 1.0 : 0.0 - Behavior on opacity { NumberAnimation {} } - placeholderText: qsTr("Enter your First Name") - labelVisible: false + + Column { + id: pinErrorColumn width: parent.width - EnterKey.iconSource: !!text ? "image://theme/icon-m-enter-next" : "image://theme/icon-m-text-input" - EnterKey.onClicked: { - validator = filledValidator - if(acceptableInput) userLastNameTextField.focus = true; - } - } - TextField { - id: userLastNameTextField - visible: !waitRegistrationInfoLabel.visible - opacity: visible ? 1.0 : 0.0 - Behavior on opacity { NumberAnimation {} } - placeholderText: qsTr("Enter your Last Name") - labelVisible: false - width: parent.width - EnterKey.iconSource: !!text ? "image://theme/icon-m-enter-accept" : "image://theme/icon-m-text-input" - EnterKey.onClicked: { - validator = filledValidator - if(acceptableInput) registerUserButton.onClicked(null); - } - } - Button { - id: registerUserButton - visible: !waitRegistrationInfoLabel.visible - opacity: visible ? 1.0 : 0.0 - Behavior on opacity { NumberAnimation {} } - text: qsTr("Register User") - anchors { - horizontalCenter: parent.horizontalCenter - } - onClicked: { - userFirstNameTextField.validator = filledValidator - userLastNameTextField.validator = filledValidator - if(userFirstNameTextField.acceptableInput && userLastNameTextField.acceptableInput) { - tdLibWrapper.registerUser(userFirstNameTextField.text, userLastNameTextField.text); - } else if(!userFirstNameTextField.acceptableInput) { - userFirstNameTextField.focus = true; - } else { - userLastNameTextField.focus = true; - } + spacing: Theme.paddingLarge + Behavior on opacity { FadeAnimation {} } + opacity: visible ? 1 : 0 + visible: false + + InfoLabel { + id: errorInfoLabel + font.pixelSize: Theme.fontSizeLarge + text: "" } + + Button { + text: qsTr("OK") + anchors { + horizontalCenter: parent.horizontalCenter + } + onClicked: { + pinErrorColumn.visible = false; + welcomeColumn.visible = true; + } + } + } + + Column { + id: enterPasswordColumn + width: parent.width + spacing: Theme.paddingLarge + + Behavior on opacity { FadeAnimation {} } + opacity: visible ? 1.0 : 0.0 + visible: false + + InfoLabel { + font.pixelSize: Theme.fontSizeLarge + text: qsTr("Please enter your password:") + } + + PasswordField { + id: enterPasswordField + anchors { + horizontalCenter: parent.horizontalCenter + } + font.pixelSize: Theme.fontSizeLarge + width: parent.width - 2 * Theme.horizontalPageMargin + horizontalAlignment: TextInput.AlignHCenter + } + + Button { + text: qsTr("OK") + anchors { + horizontalCenter: parent.horizontalCenter + } + onClicked: { + initializationPage.loading = true; + enterPasswordColumn.visible = false; + tdLibWrapper.setAuthenticationPassword(enterPasswordField.text); + } + } + } + + Column { + id: enterPinColumn + width: parent.width + spacing: Theme.paddingLarge + + Behavior on opacity { FadeAnimation {} } + opacity: visible ? 1.0 : 0.0 + visible: false + + InfoLabel { + font.pixelSize: Theme.fontSizeLarge + text: qsTr("Please enter the code that you received:") + } + + TextField { + id: enterPinField + anchors { + horizontalCenter: parent.horizontalCenter + } + inputMethodHints: Qt.ImhDigitsOnly + font.pixelSize: Theme.fontSizeExtraLarge + width: parent.width - 4 * Theme.paddingLarge + horizontalAlignment: TextInput.AlignHCenter + EnterKey.iconSource: "image://theme/icon-m-enter-next" + EnterKey.enabled: text.length > 0 + EnterKey.onClicked: enterPinButton.enter() + } + + Button { + id: enterPinButton + text: qsTr("OK") + anchors { + horizontalCenter: parent.horizontalCenter + } + onClicked: enter() + function enter() { + initializationPage.loading = true; + enterPinColumn.visible = false; + tdLibWrapper.setAuthenticationCode(enterPinField.text); + } + } + } + + Column { + id: linkingErrorColumn + width: parent.width + spacing: Theme.paddingLarge + + Behavior on opacity { FadeAnimation {} } + opacity: visible ? 1.0 : 0.0 + visible: false + + InfoLabel { + font.pixelSize: Theme.fontSizeLarge + text: qsTr("Unable to authenticate you with the entered code.") + } + + Button { + text: qsTr("Enter code again") + anchors { + horizontalCenter: parent.horizontalCenter + } + onClicked: { + linkingErrorColumn.visible = false; + enterPinColumn.visible = true; + } + } + + Button { + text: qsTr("Restart authentication") + anchors { + horizontalCenter: parent.horizontalCenter + } + onClicked: { + linkingErrorColumn.visible = false; + welcomeColumn.visible = true; + } + } + } + + Column { + id: waitRegistrationColumn + width: parent.width + spacing: Theme.paddingLarge + + Behavior on opacity { FadeAnimation {} } + opacity: visible ? 1.0 : 0.0 + visible: false + + InfoLabel { + id: waitRegistrationInfoLabel + property bool acknowledged + font.pixelSize: Theme.fontSizeExtraSmall + textFormat: Text.StyledText + horizontalAlignment: Text.AlignLeft + linkColor: Theme.primaryColor + property var stateText: initializationPage.authorizationStateData.authorization_state && initializationPage.authorizationStateData.authorization_state.terms_of_service ? + initializationPage.authorizationStateData.authorization_state.terms_of_service.text : + null + visible: !!stateText && !acknowledged + text: { + if(!stateText) { + return ''; + } + var entities = stateText.entities; + if(entities && entities.length > 0 && entities[0]["type"]["@type"] === "textEntityTypeTextUrl") { //we just use the first entity for now. + var offset = entities[0].offset; + var length = entities[0].length; + return (stateText.text.slice(0,entities[0].offset) + + "" + + stateText.text.slice(entities[0].offset, entities[0].offset + entities[0].length) + + '' + + stateText.text.slice(entities[0].offset + entities[0].length)).replace(/\n/gm, "
"); + } + return stateText.text.replace(/\n/gm, "
"); + } + } + + Button { + visible: waitRegistrationInfoLabel.visible + text: qsTr("OK") + anchors { + horizontalCenter: parent.horizontalCenter + } + onClicked: { + waitRegistrationInfoLabel.acknowledged = true; + userFirstNameTextField.focus = true + } + } + RegExpValidator { + id: filledValidator + regExp: /.+/ + } + TextField { + id: userFirstNameTextField + visible: !waitRegistrationInfoLabel.visible + opacity: visible ? 1.0 : 0.0 + Behavior on opacity { FadeAnimation {} } + placeholderText: qsTr("Enter your First Name") + labelVisible: false + width: parent.width + EnterKey.iconSource: !!text ? "image://theme/icon-m-enter-next" : "image://theme/icon-m-text-input" + EnterKey.onClicked: { + validator = filledValidator + if(acceptableInput) userLastNameTextField.focus = true; + } + } + TextField { + id: userLastNameTextField + visible: !waitRegistrationInfoLabel.visible + opacity: visible ? 1.0 : 0.0 + Behavior on opacity { FadeAnimation {} } + placeholderText: qsTr("Enter your Last Name") + labelVisible: false + width: parent.width + EnterKey.iconSource: !!text ? "image://theme/icon-m-enter-accept" : "image://theme/icon-m-text-input" + EnterKey.onClicked: { + validator = filledValidator + if(acceptableInput) registerUserButton.onClicked(null); + } + } + Button { + id: registerUserButton + visible: !waitRegistrationInfoLabel.visible + opacity: visible ? 1.0 : 0.0 + Behavior on opacity { FadeAnimation {} } + text: qsTr("Register User") + anchors { + horizontalCenter: parent.horizontalCenter + } + onClicked: { + userFirstNameTextField.validator = filledValidator + userLastNameTextField.validator = filledValidator + if(userFirstNameTextField.acceptableInput && userLastNameTextField.acceptableInput) { + tdLibWrapper.registerUser(userFirstNameTextField.text, userLastNameTextField.text); + } else if(!userFirstNameTextField.acceptableInput) { + userFirstNameTextField.focus = true; + } else { + userLastNameTextField.focus = true; + } + + } + } + } + + Item { + width: 1 + height: Theme.paddingLarge } } } - } -