import QtQuick 2.13 import QtQuick.Controls 2.13 import QtQuick.Layouts 1.13 import QtQuick.Dialogs 1.3 import QtGraphicalEffects 1.13 import StatusQ.Controls 0.1 as StatusQControls import shared.panels 1.0 import shared.popups 1.0 import shared.status 1.0 import shared.controls 1.0 import shared.controls.chat 1.0 import "../popups" import "../stores" import StatusQ.Components 0.1 import utils 1.0 Item { property bool loading: false signal genKeyClicked() signal addExistingKeyClicked() id: loginView anchors.fill: parent function doLogin(password) { if (loading || password.length === 0) return loading = true LoginStore.login(password) txtPassword.textField.clear() } function resetLogin() { if(localAccountSettings.storeToKeychainValue === Constants.storeToKeychainValueStore) { connection.enabled = true } else { txtPassword.visible = true txtPassword.forceActiveFocus(Qt.MouseFocusReason) } } Component.onCompleted: { resetLogin() } Connections{ id: connection target: LoginStore.loginModuleInst onObtainingPasswordError: { enabled = false obtainingPasswordErrorNotification.confirmationText = errorDescription obtainingPasswordErrorNotification.open() } onObtainingPasswordSuccess: { enabled = false doLogin(password) } } ConfirmationDialog { id: obtainingPasswordErrorNotification height: 270 confirmButtonLabel: qsTr("Ok") onConfirmButtonClicked: { close() } onClosed: { txtPassword.visible = true } } Item { id: element width: 360 height: 200 anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter UserImage { id: userImage anchors.horizontalCenter: parent.horizontalCenter image: LoginStore.currentAccount.thumbnailImage name: LoginStore.currentAccount.username colorId: LoginStore.currentAccount.colorId colorHash: LoginStore.currentAccount.colorHash } StyledText { id: usernameText text: LoginStore.currentAccount.username font.weight: Font.Bold font.pixelSize: 17 anchors.top: userImage.bottom anchors.topMargin: 4 anchors.horizontalCenter: parent.horizontalCenter } ConfirmAddExistingKeyModal { id: confirmAddExstingKeyModal onOpenModalClicked: { addExistingKeyClicked() } } SelectAnotherAccountModal { id: selectAnotherAccountModal onAccountSelected: { LoginStore.setCurrentAccount(index) resetLogin() } onOpenModalClicked: { addExistingKeyClicked() } } Rectangle { property bool isHovered: false id: changeAccountBtn width: 24 height: 24 anchors.left: usernameText.right anchors.leftMargin: 4 anchors.verticalCenter: usernameText.verticalCenter color: isHovered ? Style.current.backgroundHover : Style.current.transparent radius: 4 SVGImage { id: caretImg width: 10 height: 6 anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter source: Style.svg("caret") fillMode: Image.PreserveAspectFit } ColorOverlay { anchors.fill: caretImg source: caretImg color: Style.current.secondaryText } MouseArea { hoverEnabled: true anchors.fill: parent cursorShape: Qt.PointingHandCursor onEntered: { changeAccountBtn.isHovered = true } onExited: { changeAccountBtn.isHovered = false } onClicked: { if (LoginStore.rowCount() > 1) { selectAnotherAccountModal.open() } else { confirmAddExstingKeyModal.open() } } } } Input { id: txtPassword anchors.top: changeAccountBtn.bottom anchors.topMargin: Style.current.padding * 2 enabled: !loading placeholderText: loading ? //% "Connecting..." qsTrId("connecting") : //% "Enter password" qsTrId("enter-password") textField.echoMode: TextInput.Password textField.focus: true Keys.onReturnPressed: { doLogin(textField.text) } onTextEdited: { errMsg.visible = false loading = false } } StatusQControls.StatusRoundButton { id: submitBtn width: 40 height: 40 type: StatusQControls.StatusRoundButton.Type.Secondary icon.name: "arrow-right" icon.width: 18 icon.height: 14 opacity: (loading || txtPassword.text.length > 0) ? 1 : 0 anchors.left: txtPassword.visible? txtPassword.right : changeAccountBtn.right anchors.leftMargin: (loading || txtPassword.text.length > 0) ? Style.current.padding : Style.current.smallPadding anchors.verticalCenter: txtPassword.visible? txtPassword.verticalCenter : changeAccountBtn.verticalCenter state: loading ? "pending" : "default" onClicked: { doLogin(txtPassword.textField.text) } // https://www.figma.com/file/BTS422M9AkvWjfRrXED3WC/%F0%9F%91%8B-Onboarding%E2%8E%9CDesktop?node-id=6%3A0 Behavior on opacity { OpacityAnimator { from: 0.5 duration: 200 } } Behavior on anchors.leftMargin { NumberAnimation { duration: 200 } } } Connections { target: LoginStore.loginModuleInst onAccountLoginError: { if (error) { // SQLITE_NOTADB: "file is not a database" if (error === "file is not a database") { errMsg.text = errMsg.incorrectPasswordMsg } else { //% "Login failed: %1" errMsg.text = qsTrId("login-failed---1").arg(error.toUpperCase()) } errMsg.visible = true loading = false txtPassword.textField.forceActiveFocus() } } } StatusQControls.StatusFlatButton { id: generateKeysLinkText //% "Generate new keys" text: qsTrId("generate-new-keys") anchors.top: txtPassword.visible? txtPassword.bottom : changeAccountBtn.bottom anchors.topMargin: 16 anchors.horizontalCenter: parent.horizontalCenter onClicked: { genKeyClicked(); } } StyledText { id: errMsg //% "Login failed. Please re-enter your password and try again." readonly property string incorrectPasswordMsg: qsTrId("login-failed--please-re-enter-your-password-and-try-again-") anchors.top: generateKeysLinkText.bottom anchors.topMargin: Style.current.smallPadding anchors.horizontalCenter: parent.horizontalCenter visible: false text: incorrectPasswordMsg font.pixelSize: 13 color: Style.current.danger } } }