diff --git a/interface/resources/qml/LoginDialog/CompleteProfileBody.qml b/interface/resources/qml/LoginDialog/CompleteProfileBody.qml index 4213daea6d..c2101aaea8 100644 --- a/interface/resources/qml/LoginDialog/CompleteProfileBody.qml +++ b/interface/resources/qml/LoginDialog/CompleteProfileBody.qml @@ -22,9 +22,12 @@ Item { width: root.width height: root.height readonly property string termsContainerText: qsTr("By creating this user profile, you agree to High Fidelity's Terms of Service") + readonly property int textFieldHeight: 31 readonly property string fontFamily: "Raleway" readonly property int fontSize: 15 readonly property bool fontBold: true + readonly property int textFieldFontSize: 18 + readonly property var passwordImageRatio: 16 / 23 property bool withOculus: withOculus property bool withSteam: withSteam @@ -60,7 +63,12 @@ Item { Item { id: contentItem - anchors.fill: parent + width: parent.width + height: errorContainer.height + fields.height + buttons.height + additionalTextContainer.height + + termsContainer.height + anchors.top: parent.top + anchors.topMargin: root.bannerHeight + 0.25 * parent.height + anchors.left: parent.left Item { id: errorContainer @@ -95,6 +103,182 @@ Item { loginErrorMessage.horizontalAlignment = Text.AlignLeft; errorContainer.height = 3 * loginErrorMessageTextMetrics.height; } + if (completeProfileBody.withOculus) { + errorContainer.anchors.bottom = fields.top; + } + } + } + + Item { + id: fields + width: root.bannerWidth + height: 3 * completeProfileBody.textFieldHeight + 2 * hifi.dimensions.contentSpacing.y + visible: completeProfileBody.withOculus + anchors { + left: parent.left + leftMargin: (parent.width - root.bannerWidth) / 2 + bottom: buttons.top + bottomMargin: hifi.dimensions.contentSpacing.y + } + + HifiControlsUit.TextField { + id: emailField + width: root.bannerWidth + height: completeProfileBody.textFieldHeight + anchors { + top: parent.top + } + placeholderText: "Email" + font.pixelSize: completeProfileBody.textFieldFontSize + styleRenderType: Text.QtRendering + activeFocusOnPress: true + Keys.onPressed: { + switch (event.key) { + case Qt.Key_Tab: + event.accepted = true; + if (event.modifiers === Qt.ShiftModifier) { + passwordField.focus = true; + } else { + usernameField.focus = true; + } + break; + case Qt.Key_Backtab: + event.accepted = true; + usernameField.focus = true; + break; + case Qt.Key_Enter: + case Qt.Key_Return: + event.accepted = true; + completeProfileBody.createAccountFromOculus(emailField.text, usernameField.text, passwordField.text); + break; + } + } + onFocusChanged: { + root.text = ""; + if (focus) { + root.isPassword = false; + } + } + } + + HifiControlsUit.TextField { + id: usernameField + width: root.bannerWidth + height: completeProfileBody.textFieldHeight + placeholderText: "Username" + font.pixelSize: completeProfileBody.textFieldFontSize + styleRenderType: Text.QtRendering + anchors { + top: emailField.bottom + topMargin: hifi.dimensions.contentSpacing.y + } + Keys.onPressed: { + if (!usernameField.visible) { + return; + } + switch (event.key) { + case Qt.Key_Tab: + event.accepted = true; + if (event.modifiers === Qt.ShiftModifier) { + emailField.focus = true; + } else { + passwordField.focus = true; + } + break; + case Qt.Key_Backtab: + event.accepted = true; + passwordField.focus = true; + break; + case Qt.Key_Enter: + case Qt.Key_Return: + event.accepted = true; + completeProfileBody.createAccountFromOculus(emailField.text, usernameField.text, passwordField.text); + break; + } + } + onFocusChanged: { + root.text = ""; + if (focus) { + root.isPassword = false; + } + } + } + HifiControlsUit.TextField { + id: passwordField + width: root.bannerWidth + height: completeProfileBody.textFieldHeight + placeholderText: "Password (min. 6 characters)" + font.pixelSize: completeProfileBody.textFieldFontSize + styleRenderType: Text.QtRendering + activeFocusOnPress: true + echoMode: passwordFieldMouseArea.showPassword ? TextInput.Normal : TextInput.Password + anchors { + top: usernameField.bottom + topMargin: hifi.dimensions.contentSpacing.y + } + + onFocusChanged: { + root.text = ""; + root.isPassword = focus; + } + + Item { + id: showPasswordContainer + z: 10 + // width + image's rightMargin + width: showPasswordImage.width + 8 + height: parent.height + anchors { + right: parent.right + } + + Image { + id: showPasswordImage + width: passwordField.height * passwordImageRatio + height: passwordField.height * passwordImageRatio + anchors { + right: parent.right + rightMargin: 8 + top: parent.top + topMargin: passwordFieldMouseArea.showPassword ? 6 : 8 + bottom: parent.bottom + bottomMargin: passwordFieldMouseArea.showPassword ? 5 : 8 + } + source: passwordFieldMouseArea.showPassword ? "../../images/eyeClosed.svg" : "../../images/eyeOpen.svg" + MouseArea { + id: passwordFieldMouseArea + anchors.fill: parent + acceptedButtons: Qt.LeftButton + property bool showPassword: false + onClicked: { + showPassword = !showPassword; + } + } + } + } + Keys.onPressed: { + switch (event.key) { + case Qt.Key_Tab: + event.accepted = true; + if (event.modifiers === Qt.ShiftModifier) { + emailField.focus = true; + } else if (usernameField.visible) { + usernameField.focus = true; + } else { + emailField.focus = true; + } + break; + case Qt.Key_Backtab: + event.accepted = true; + emailField.focus = true; + break; + case Qt.Key_Enter: + case Qt.Key_Return: + event.accepted = true; + completeProfileBody.createAccountFromOculus(emailField.text, usernameField.text, passwordField.text); + break; + } + } } } @@ -104,7 +288,7 @@ Item { height: d.minHeightButton anchors { top: parent.top - topMargin: (parent.height - additionalTextContainer.height) / 2 - hifi.dimensions.contentSpacing.y + topMargin: (parent.height - additionalTextContainer.height + fields.height) / 2 - hifi.dimensions.contentSpacing.y left: parent.left leftMargin: (parent.width - root.bannerWidth) / 2 } @@ -144,9 +328,7 @@ Item { fontBold: completeProfileBody.fontBold onClicked: { loginErrorMessage.visible = false; - console.log("withOculus: " + completeProfileBody.withOculus); if (completeProfileBody.withOculus) { - console.log("creating account through oculus"); loginDialog.createAccountFromOculus(); } else if (completeProfileBody.withSteam) { loginDialog.createAccountFromSteam(); @@ -271,6 +453,20 @@ Item { } onHandleCreateFailed: { console.log("Create Failed: " + error); + if (completeProfileBody.withOculus) { + loginErrorMessage.visible = true; + loginErrorMessage.text = error; + + if (loginErrorMessageTextMetrics.width > root.bannerWidth && root.isTablet) { + loginErrorMessage.wrapMode = Text.WordWrap; + loginErrorMessage.verticalAlignment = Text.AlignLeft; + loginErrorMessage.horizontalAlignment = Text.AlignLeft; + errorContainer.height = (loginErrorMessageTextMetrics.width / root.bannerWidth) * loginErrorMessageTextMetrics.height; + } else { + loginErrorMessage.wrapMode = Text.NoWrap; + errorContainer.height = loginErrorMessageTextMetrics.height; + } + } bodyLoader.setSource("UsernameCollisionBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": completeProfileBody.withSteam, "withOculus": completeProfileBody.withOculus }); diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index 7eb4ab3bcf..2b6667c683 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -88,8 +88,6 @@ Item { var savedUsername = Settings.getValue("keepMeLoggedIn/savedUsername", ""); emailField.text = keepMeLoggedInCheckbox.checked ? savedUsername === "Unknown user" ? "" : savedUsername : ""; if (linkAccountBody.linkSteam || linkAccountBody.linkOculus) { - linkInfoText.anchors.top = passwordField.bottom; - keepMeLoggedInCheckbox.anchors.top = linkInfoText.bottom; loginButton.width = (passwordField.width - hifi.dimensions.contentSpacing.x) / 2; loginButton.anchors.right = emailField.right; } else { @@ -115,7 +113,7 @@ Item { id: loginContainer width: emailField.width height: errorContainer.height + emailField.height + passwordField.height + 5.5 * hifi.dimensions.contentSpacing.y + - keepMeLoggedInCheckbox.height + loginButton.height + cantAccessTextMetrics.height + continueButton.height + linkInfoTextMetrics.height + keepMeLoggedInCheckbox.height + loginButton.height + cantAccessTextMetrics.height + continueButton.height anchors { top: parent.top topMargin: root.bannerHeight + 0.25 * parent.height @@ -320,38 +318,6 @@ Item { linkAccountBody.login() } } - TextMetrics { - id: linkInfoTextMetrics - font: linkInfoText.font - text: linkInfoText.text - } - Text { - id: linkInfoText - width: root.bannerWidth - visible: linkAccountBody.linkSteam || linkAccountBody.linkOculus - anchors { - top: loginButton.bottom - topMargin: hifi.dimensions.contentSpacing.y - left: emailField.left - } - - font.family: linkAccountBody.fontFamily - font.pixelSize: linkAccountBody.textFieldFontSize - color: "white" - text: qsTr(""); - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - Component.onCompleted: { - if (linkAccountBody.linkOculus) { - linkInfoText.text = qsTr("Your Oculus account information will not be exposed to others."); - } else if (linkAccountBody.linkSteam) { - linkInfoText.text = qsTr("Your Steam account information will not be exposed to others."); - } - if (linkInfoTextMetrics.width > root.bannerWidth) { - linkInfoText.wrapMode = Text.WordWrap; - } - } - } TextMetrics { id: cantAccessTextMetrics font: cantAccessText.font diff --git a/interface/resources/qml/LoginDialog/SignUpBody.qml b/interface/resources/qml/LoginDialog/SignUpBody.qml index e151179f8f..d356e62e1d 100644 --- a/interface/resources/qml/LoginDialog/SignUpBody.qml +++ b/interface/resources/qml/LoginDialog/SignUpBody.qml @@ -23,6 +23,7 @@ Item { clip: true height: root.height width: root.width + readonly property string termsContainerText: qsTr("By signing up, you agree to High Fidelity's Terms of Service") property int textFieldHeight: 31 property string fontFamily: "Raleway" property int fontSize: 15 @@ -365,6 +366,54 @@ Item { signUpBody.signup(); } } + Item { + id: termsContainer + width: parent.width + height: termsTextMetrics.height + anchors { + top: signUpButton.bottom + horizontalCenter: parent.horizontalCenter + topMargin: 2 * hifi.dimensions.contentSpacing.y + left: parent.left + } + TextMetrics { + id: termsTextMetrics + font: termsText.font + text: signUpBody.termsContainerText + Component.onCompleted: { + // with the link. + termsText.text = qsTr("By signing up, you agree to High Fidelity's Terms of Service") + } + } + + HifiStylesUit.InfoItem { + id: termsText + text: signUpBody.termsContainerText + font.family: signUpBody.fontFamily + font.pixelSize: signUpBody.fontSize + font.bold: signUpBody.fontBold + wrapMode: Text.WordWrap + color: hifi.colors.lightGray + linkColor: hifi.colors.blueAccent + lineHeight: 1 + lineHeightMode: Text.ProportionalHeight + + onLinkActivated: loginDialog.openUrl(link); + + Component.onCompleted: { + if (termsTextMetrics.width > root.bannerWidth && root.isTablet) { + termsText.width = root.bannerWidth; + termsText.wrapMode = Text.WordWrap; + additionalText.verticalAlignment = Text.AlignLeft; + additionalText.horizontalAlignment = Text.AlignLeft; + termsContainer.height = (termsTextMetrics.width / root.bannerWidth) * termsTextMetrics.height; + termsContainer.anchors.left = buttons.left; + } else { + termsText.anchors.centerIn = termsContainer; + } + } + } + } } } diff --git a/interface/resources/qml/LoginDialog/UsernameCollisionBody.qml b/interface/resources/qml/LoginDialog/UsernameCollisionBody.qml index bb9a2292f6..b7b1a95e19 100644 --- a/interface/resources/qml/LoginDialog/UsernameCollisionBody.qml +++ b/interface/resources/qml/LoginDialog/UsernameCollisionBody.qml @@ -19,6 +19,7 @@ import TabletScriptingInterface 1.0 Item { id: usernameCollisionBody clip: true + readonly property string termsContainerText: qsTr("By creating this user profile, you agree to High Fidelity's Terms of Service") width: root.width height: root.height readonly property string fontFamily: "Raleway" @@ -198,6 +199,55 @@ Item { } } } + Item { + id: termsContainer + width: parent.width + height: termsTextMetrics.height + anchors { + top: buttons.bottom + horizontalCenter: parent.horizontalCenter + topMargin: 2 * hifi.dimensions.contentSpacing.y + left: parent.left + leftMargin: (parent.width - buttons.width) / 2 + } + TextMetrics { + id: termsTextMetrics + font: termsText.font + text: usernameCollisionBody.termsContainerText + Component.onCompleted: { + // with the link. + termsText.text = qsTr("By creating this user profile, you agree to High Fidelity's Terms of Service") + } + } + + HifiStylesUit.InfoItem { + id: termsText + text: usernameCollisionBody.termsContainerText + font.family: usernameCollisionBody.fontFamily + font.pixelSize: usernameCollisionBody.fontSize + font.bold: usernameCollisionBody.fontBold + wrapMode: Text.WordWrap + color: hifi.colors.lightGray + linkColor: hifi.colors.blueAccent + lineHeight: 1 + lineHeightMode: Text.ProportionalHeight + + onLinkActivated: loginDialog.openUrl(link); + + Component.onCompleted: { + if (termsTextMetrics.width > root.bannerWidth && root.isTablet) { + termsText.width = root.bannerWidth; + termsText.wrapMode = Text.WordWrap; + additionalText.verticalAlignment = Text.AlignLeft; + additionalText.horizontalAlignment = Text.AlignLeft; + termsContainer.height = (termsTextMetrics.width / root.bannerWidth) * termsTextMetrics.height; + termsContainer.anchors.left = buttons.left; + } else { + termsText.anchors.centerIn = termsContainer; + } + } + } + } } Component.onCompleted: { diff --git a/interface/resources/qml/dialogs/TabletLoginDialog.qml b/interface/resources/qml/dialogs/TabletLoginDialog.qml index 06844c848a..4a6d710995 100644 --- a/interface/resources/qml/dialogs/TabletLoginDialog.qml +++ b/interface/resources/qml/dialogs/TabletLoginDialog.qml @@ -177,6 +177,6 @@ FocusScope { Component.onCompleted: { keyboardTimer.start(); - bodyLoader.setSource("../LoginDialog/LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "linkSteam": false }); + bodyLoader.setSource("../LoginDialog/UsernameCollisionBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": true, "linkSteam": false }); } }