diff --git a/interface/resources/qml/LoginDialog.qml b/interface/resources/qml/LoginDialog.qml
index 1c205b5f5e..2d5c68c0e8 100644
--- a/interface/resources/qml/LoginDialog.qml
+++ b/interface/resources/qml/LoginDialog.qml
@@ -120,6 +120,6 @@ FocusScope {
}
Component.onCompleted: {
- bodyLoader.setSource("LoginDialog/LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "linkSteam": false });
+ bodyLoader.setSource("LoginDialog/LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "linkSteam": false, "linkOculus": false });
}
}
diff --git a/interface/resources/qml/LoginDialog/CompleteProfileBody.qml b/interface/resources/qml/LoginDialog/CompleteProfileBody.qml
index 144b91063f..ebc677fb00 100644
--- a/interface/resources/qml/LoginDialog/CompleteProfileBody.qml
+++ b/interface/resources/qml/LoginDialog/CompleteProfileBody.qml
@@ -22,11 +22,16 @@ 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 string termsContainerOculusText: qsTr("By signing up, 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
- readonly property bool withSteam: withSteam
+ property bool withOculus: withOculus
+ property bool withSteam: withSteam
property string errorString: errorString
readonly property bool loginDialogPoppedUp: loginDialog.getLoginDialogPoppedUp()
@@ -61,15 +66,20 @@ 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
- width: parent.width
+ width: root.bannerWidth
height: loginErrorMessageTextMetrics.height
anchors {
- bottom: buttons.top;
- bottomMargin: hifi.dimensions.contentSpacing.y;
+ bottom: completeProfileBody.withOculus ? fields.top : buttons.top;
+ bottomMargin: 1.5 * hifi.dimensions.contentSpacing.y;
left: buttons.left;
}
TextMetrics {
@@ -79,8 +89,8 @@ Item {
}
Text {
id: loginErrorMessage;
- width: root.bannerWidth
color: "red";
+ width: root.bannerWidth;
font.family: completeProfileBody.fontFamily
font.pixelSize: 18
font.bold: completeProfileBody.fontBold
@@ -88,13 +98,196 @@ Item {
horizontalAlignment: Text.AlignHCenter
text: completeProfileBody.errorString
visible: true
+ onTextChanged: {
+ mainContainer.recalculateErrorMessage();
+ }
+ Component.onCompleted: {
+ mainContainer.recalculateErrorMessage();
+ }
}
- Component.onCompleted: {
- if (loginErrorMessageTextMetrics.width > root.bannerWidth && root.isTablet) {
- loginErrorMessage.wrapMode = Text.WordWrap;
- loginErrorMessage.verticalAlignment = Text.AlignLeft;
- loginErrorMessage.horizontalAlignment = Text.AlignLeft;
- errorContainer.height = 3 * loginErrorMessageTextMetrics.height;
+ }
+
+ 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: usernameField
+ width: root.bannerWidth
+ height: completeProfileBody.textFieldHeight
+ placeholderText: "Username"
+ font.pixelSize: completeProfileBody.textFieldFontSize
+ styleRenderType: Text.QtRendering
+ anchors {
+ top: parent.top
+ }
+ Keys.onPressed: {
+ if (!usernameField.visible) {
+ return;
+ }
+ switch (event.key) {
+ case Qt.Key_Tab:
+ event.accepted = true;
+ if (event.modifiers === Qt.ShiftModifier) {
+ passwordField.focus = true;
+ } else {
+ emailField.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;
+ loginDialog.createAccountFromOculus(emailField.text, usernameField.text, passwordField.text);
+ bodyLoader.setSource("LoggingInBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": completeProfileBody.withSteam,
+ "linkSteam": false, "withOculus": completeProfileBody.withOculus, "linkOculus": false, "createOculus": true });
+ break;
+ }
+ }
+ onFocusChanged: {
+ root.text = "";
+ if (focus) {
+ root.isPassword = false;
+ }
+ }
+ Component.onCompleted: {
+ var userID = "";
+ if (completeProfileBody.withOculus) {
+ userID = loginDialog.oculusUserID();
+ }
+ usernameField.text = userID;
+ }
+ }
+ HifiControlsUit.TextField {
+ id: emailField
+ width: root.bannerWidth
+ height: completeProfileBody.textFieldHeight
+ anchors {
+ top: usernameField.bottom
+ topMargin: hifi.dimensions.contentSpacing.y
+ }
+ 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) {
+ usernameField.focus = true;
+ } else {
+ passwordField.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;
+ loginDialog.createAccountFromOculus(emailField.text, usernameField.text, passwordField.text);
+ bodyLoader.setSource("LoggingInBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": completeProfileBody.withSteam,
+ "linkSteam": false, "withOculus": completeProfileBody.withOculus, "linkOculus": false, "createOculus": true });
+ break;
+ }
+ }
+ onFocusChanged: {
+ root.text = "";
+ if (focus) {
+ root.isPassword = false;
+ }
+ }
+ }
+ HifiControlsUit.TextField {
+ id: passwordField
+ width: root.bannerWidth
+ height: completeProfileBody.textFieldHeight
+ placeholderText: "Password (optional)"
+ font.pixelSize: completeProfileBody.textFieldFontSize
+ styleRenderType: Text.QtRendering
+ activeFocusOnPress: true
+ echoMode: passwordFieldMouseArea.showPassword ? TextInput.Normal : TextInput.Password
+ anchors {
+ top: emailField.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;
+ loginDialog.createAccountFromOculus(emailField.text, usernameField.text, passwordField.text);
+ bodyLoader.setSource("LoggingInBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": completeProfileBody.withSteam,
+ "linkSteam": false, "withOculus": completeProfileBody.withOculus, "linkOculus": false, "createOculus": true });
+ break;
+ }
}
}
}
@@ -105,7 +298,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,7 +337,7 @@ Item {
width: (parent.width - hifi.dimensions.contentSpacing.x) / 2
height: d.minHeightButton
- text: qsTr("Create your profile")
+ text: completeProfileBody.withOculus ? qsTr("Sign Up") : qsTr("Create your profile")
color: hifi.buttons.blue
fontFamily: completeProfileBody.fontFamily
@@ -158,55 +351,12 @@ Item {
UserActivityLogger.logAction("encourageLoginDialog", data);
}
loginErrorMessage.visible = false;
- loginDialog.createAccountFromSteam();
- }
- }
- }
-
- Item {
- id: additionalTextContainer
- width: parent.width
- height: additionalTextMetrics.height
- anchors {
- top: buttons.bottom
- horizontalCenter: parent.horizontalCenter
- topMargin: hifi.dimensions.contentSpacing.y
- left: parent.left
- }
-
- TextMetrics {
- id: additionalTextMetrics
- font: additionalText.font
- text: "Already have a High Fidelity profile? Link to an existing profile here."
- }
-
- HifiStylesUit.ShortcutText {
- id: additionalText
- text: "Already have a High Fidelity profile? Link to an existing profile here."
-
- font.family: completeProfileBody.fontFamily
- font.pixelSize: completeProfileBody.fontSize
- font.bold: completeProfileBody.fontBold
- wrapMode: Text.NoWrap
- lineHeight: 1
- lineHeightMode: Text.ProportionalHeight
- horizontalAlignment: Text.AlignHCenter
- linkColor: hifi.colors.blueAccent
-
- onLinkActivated: {
- loginDialog.isLogIn = true;
- bodyLoader.setSource("LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "errorString": "", "withSteam": true, "linkSteam": true });
- }
- Component.onCompleted: {
- if (additionalTextMetrics.width > root.bannerWidth && root.isTablet) {
- additionalText.width = root.bannerWidth;
- additionalText.wrapMode = Text.WordWrap;
- additionalText.verticalAlignment = Text.AlignLeft;
- additionalText.horizontalAlignment = Text.AlignLeft;
- additionalTextContainer.height = (additionalTextMetrics.width / root.bannerWidth) * additionalTextMetrics.height;
- additionalTextContainer.anchors.left = buttons.left;
- } else {
- additionalText.anchors.centerIn = additionalTextContainer;
+ if (completeProfileBody.withOculus) {
+ loginDialog.createAccountFromOculus(emailField.text, usernameField.text, passwordField.text);
+ bodyLoader.setSource("LoggingInBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": completeProfileBody.withSteam,
+ "linkSteam": false, "withOculus": completeProfileBody.withOculus, "linkOculus": false, "createOculus": true });
+ } else if (completeProfileBody.withSteam) {
+ loginDialog.createAccountFromSteam();
}
}
}
@@ -217,29 +367,33 @@ Item {
width: parent.width
height: termsTextMetrics.height
anchors {
- top: additionalTextContainer.bottom
+ top: buttons.bottom
horizontalCenter: parent.horizontalCenter
- topMargin: 2 * hifi.dimensions.contentSpacing.y
+ topMargin: hifi.dimensions.contentSpacing.y
left: parent.left
}
TextMetrics {
id: termsTextMetrics
font: termsText.font
- text: completeProfileBody.termsContainerText
+ text: completeProfileBody.withOculus ? completeProfileBody.termsContainerOculusText : completeProfileBody.termsContainerText
Component.onCompleted: {
// with the link.
- termsText.text = qsTr("By creating this user profile, you agree to High Fidelity's Terms of Service")
+ if (completeProfileBody.withOculus) {
+ termsText.text = qsTr("By signing up, you agree to High Fidelity's Terms of Service")
+ } else {
+ termsText.text = qsTr("By creating this user profile, you agree to High Fidelity's Terms of Service")
+ }
}
}
HifiStylesUit.InfoItem {
id: termsText
- text: completeProfileBody.termsContainerText
+ text: completeProfileBody.withOculus ? completeProfileBody.termsContainerOculusText : completeProfileBody.termsContainerText
font.family: completeProfileBody.fontFamily
font.pixelSize: completeProfileBody.fontSize
font.bold: completeProfileBody.fontBold
wrapMode: Text.WordWrap
- color: hifi.colors.lightGray
+ color: hifi.colors.white
linkColor: hifi.colors.blueAccent
lineHeight: 1
lineHeightMode: Text.ProportionalHeight
@@ -247,7 +401,7 @@ Item {
onLinkActivated: loginDialog.openUrl(link);
Component.onCompleted: {
- if (termsTextMetrics.width > root.bannerWidth && root.isTablet) {
+ if (termsTextMetrics.width > root.bannerWidth) {
termsText.width = root.bannerWidth;
termsText.wrapMode = Text.WordWrap;
additionalText.verticalAlignment = Text.AlignLeft;
@@ -260,14 +414,86 @@ Item {
}
}
}
+
+ Item {
+ id: additionalTextContainer
+ width: parent.width
+ height: additionalTextMetrics.height
+ anchors {
+ top: termsContainer.bottom
+ horizontalCenter: parent.horizontalCenter
+ topMargin: 2 * hifi.dimensions.contentSpacing.y
+ left: parent.left
+ }
+
+ TextMetrics {
+ id: additionalTextMetrics
+ font: additionalText.font
+ text: "Already have a High Fidelity profile? Link to an existing profile here."
+ }
+
+ HifiStylesUit.ShortcutText {
+ id: additionalText
+ text: "Already have a High Fidelity profile? Link to an existing profile here."
+ width: root.bannerWidth;
+ font.family: completeProfileBody.fontFamily
+ font.pixelSize: completeProfileBody.fontSize
+ font.bold: completeProfileBody.fontBold
+ wrapMode: Text.NoWrap
+ lineHeight: 1
+ lineHeightMode: Text.ProportionalHeight
+ horizontalAlignment: Text.AlignHCenter
+ linkColor: hifi.colors.blueAccent
+
+ onLinkActivated: {
+ bodyLoader.setSource("LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "errorString": "",
+ "withSteam": completeProfileBody.withSteam, "linkSteam": completeProfileBody.withSteam, "withOculus": completeProfileBody.withOculus,
+ "linkOculus": completeProfileBody.withOculus });
+ }
+ Component.onCompleted: {
+ if (additionalTextMetrics.width > root.bannerWidth) {
+ additionalText.wrapMode = Text.WordWrap;
+ additionalText.verticalAlignment = Text.AlignLeft;
+ additionalText.horizontalAlignment = Text.AlignLeft;
+ additionalTextContainer.height = (additionalTextMetrics.width / root.bannerWidth) * additionalTextMetrics.height;
+ additionalTextContainer.anchors.left = buttons.left;
+ } else {
+ additionalText.anchors.centerIn = additionalTextContainer;
+ }
+ }
+ }
+ }
+ }
+ function recalculateErrorMessage() {
+ if (completeProfileBody.errorString !== "") {
+ loginErrorMessage.visible = true;
+ var errorLength = completeProfileBody.errorString.split(/\r\n|\r|\n/).length;
+ var errorStringEdited = completeProfileBody.errorString.replace(/[\n\r]+/g, "\n");
+ loginErrorMessage.text = errorStringEdited;
+ if (errorLength > 1.0) {
+ loginErrorMessage.wrapMode = Text.WordWrap;
+ loginErrorMessage.verticalAlignment = Text.AlignLeft;
+ loginErrorMessage.horizontalAlignment = Text.AlignLeft;
+ errorContainer.height = errorLength * loginErrorMessageTextMetrics.height;
+ } else if (loginErrorMessageTextMetrics.width > root.bannerWidth) {
+ 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;
+ loginErrorMessage.verticalAlignment = Text.AlignVCenter;
+ loginErrorMessage.horizontalAlignment = Text.AlignHCenter;
+ errorContainer.height = loginErrorMessageTextMetrics.height;
+ }
+ }
}
}
Connections {
target: loginDialog
onHandleCreateCompleted: {
- console.log("Create Succeeded")
-
+ console.log("Create Succeeded");
if (completeProfileBody.withSteam) {
if (completeProfileBody.loginDialogPoppedUp) {
var data = {
@@ -277,20 +503,24 @@ Item {
}
loginDialog.loginThroughSteam();
}
- bodyLoader.setSource("LoggingInBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": completeProfileBody.withSteam, "linkSteam": false });
+ bodyLoader.setSource("LoggingInBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": completeProfileBody.withSteam, "linkSteam": false,
+ "withOculus": completeProfileBody.withOculus, "linkOculus": false });
}
onHandleCreateFailed: {
console.log("Create Failed: " + error);
- if (completeProfileBody.withSteam) {
+ if (completeProfileBody.withSteam || completeProfileBody.withOculus) {
if (completeProfileBody.loginDialogPoppedUp) {
+ action = completeProfileBody.withSteam ? "Steam" : "Oculus";
var data = {
- "action": "user failed to create a profile with Steam from the complete profile screen"
+ "action": "user failed to create a profile with " + action + " from the complete profile screen"
}
UserActivityLogger.logAction("encourageLoginDialog", data);
}
}
-
- bodyLoader.setSource("UsernameCollisionBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": completeProfileBody.withSteam });
+ if (!completeProfileBody.withOculus) {
+ bodyLoader.setSource("UsernameCollisionBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": completeProfileBody.withSteam,
+ "withOculus": completeProfileBody.withOculus });
+ }
}
}
@@ -302,5 +532,6 @@ Item {
}
d.resize();
root.text = "";
+ usernameField.forceActiveFocus();
}
}
diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml
index 5048bf0278..4dd05f594d 100644
--- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml
+++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml
@@ -36,9 +36,10 @@ Item {
property bool keyboardRaised: false
property bool punctuationMode: false
- property bool withSteam: false
+ property bool withSteam: withSteam
property bool linkSteam: linkSteam
- property bool withOculus: false
+ property bool withOculus: withOculus
+ property bool linkOculus: linkOculus
property string errorString: errorString
property bool lostFocus: false
@@ -83,23 +84,24 @@ Item {
}
UserActivityLogger.logAction("encourageLoginDialog", data);
}
-
- bodyLoader.setSource("LoggingInBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": linkAccountBody.withSteam, "withOculus": linkAccountBody.withOculus, "linkSteam": linkAccountBody.linkSteam });
+ bodyLoader.setSource("LoggingInBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": linkAccountBody.withSteam,
+ "withOculus": linkAccountBody.withOculus, "linkSteam": linkAccountBody.linkSteam, "linkOculus": linkAccountBody.linkOculus });
}
function init() {
// going to/from sign in/up dialog.
- loginDialog.isLogIn = true;
loginErrorMessage.text = linkAccountBody.errorString;
loginErrorMessage.visible = (linkAccountBody.errorString !== "");
- loginButton.text = !linkAccountBody.linkSteam ? "Log In" : "Link Account";
+ if (loginErrorMessageTextMetrics.width > emailField.width) {
+ loginErrorMessage.wrapMode = Text.WordWrap;
+ errorContainer.height = (loginErrorMessageTextMetrics.width / emailField.width) * loginErrorMessageTextMetrics.height;
+ }
+ loginButton.text = (!linkAccountBody.linkSteam && !linkAccountBody.linkOculus) ? "Log In" : "Link Account";
loginButton.color = hifi.buttons.blue;
emailField.placeholderText = "Username or Email";
var savedUsername = Settings.getValue("keepMeLoggedIn/savedUsername", "");
emailField.text = keepMeLoggedInCheckbox.checked ? savedUsername === "Unknown user" ? "" : savedUsername : "";
- if (linkAccountBody.linkSteam) {
- steamInfoText.anchors.top = passwordField.bottom;
- keepMeLoggedInCheckbox.anchors.top = steamInfoText.bottom;
+ if (linkAccountBody.linkSteam || linkAccountBody.linkOculus) {
loginButton.width = (passwordField.width - hifi.dimensions.contentSpacing.x) / 2;
loginButton.anchors.right = emailField.right;
} else {
@@ -125,7 +127,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 + steamInfoTextMetrics.height
+ keepMeLoggedInCheckbox.height + loginButton.height + cantAccessTextMetrics.height + continueButton.height
anchors {
top: parent.top
topMargin: root.bannerHeight + 0.25 * parent.height
@@ -135,7 +137,7 @@ Item {
Item {
id: errorContainer
- width: loginErrorMessageTextMetrics.width
+ width: parent.width
height: loginErrorMessageTextMetrics.height
anchors {
bottom: emailField.top;
@@ -304,7 +306,7 @@ Item {
fontSize: linkAccountBody.fontSize
fontBold: linkAccountBody.fontBold
color: hifi.buttons.noneBorderlessWhite;
- visible: linkAccountBody.linkSteam
+ visible: linkAccountBody.linkSteam || linkAccountBody.linkOculus
anchors {
top: keepMeLoggedInCheckbox.bottom
topMargin: hifi.dimensions.contentSpacing.y
@@ -315,10 +317,9 @@ Item {
"action": "user clicked cancel at link account screen"
};
UserActivityLogger.logAction("encourageLoginDialog", data);
- loginDialog.dismissLoginDialog();
}
-
- bodyLoader.setSource("CompleteProfileBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": linkAccountBody.withSteam, "errorString": "" });
+ bodyLoader.setSource("CompleteProfileBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": linkAccountBody.withSteam,
+ "withOculus": linkAccountBody.withOculus, "errorString": "" });
}
}
HifiControlsUit.Button {
@@ -337,33 +338,6 @@ Item {
linkAccountBody.login();
}
}
- TextMetrics {
- id: steamInfoTextMetrics
- font: steamInfoText.font
- text: steamInfoText.text
- }
- Text {
- id: steamInfoText
- width: root.bannerWidth
- visible: linkAccountBody.linkSteam
- anchors {
- top: loginButton.bottom
- topMargin: hifi.dimensions.contentSpacing.y
- left: emailField.left
- }
-
- font.family: linkAccountBody.fontFamily
- font.pixelSize: linkAccountBody.textFieldFontSize
- color: "white"
- text: qsTr("Your Steam account information will not be exposed to others.");
- verticalAlignment: Text.AlignVCenter
- horizontalAlignment: Text.AlignHCenter
- Component.onCompleted: {
- if (steamInfoTextMetrics.width > root.bannerWidth) {
- steamInfoText.wrapMode = Text.WordWrap;
- }
- }
- }
TextMetrics {
id: cantAccessTextMetrics
font: cantAccessText.font
@@ -372,7 +346,7 @@ Item {
HifiStylesUit.ShortcutText {
id: cantAccessText
z: 10
- visible: !linkAccountBody.linkSteam
+ visible: !linkAccountBody.linkSteam && !linkAccountBody.linkOculus
anchors {
top: loginButton.bottom
topMargin: hifi.dimensions.contentSpacing.y
@@ -423,10 +397,10 @@ Item {
buttonGlyphSize: 24
buttonGlyphRightMargin: 10
onClicked: {
- // if (loginDialog.isOculusStoreRunning()) {
- // linkAccountBody.withOculus = true;
- // loginDialog.loginThroughSteam();
- // } else
+ if (loginDialog.isOculusRunning()) {
+ linkAccountBody.withOculus = true;
+ loginDialog.loginThroughOculus();
+ } else
if (loginDialog.isSteamRunning()) {
linkAccountBody.withSteam = true;
loginDialog.loginThroughSteam();
@@ -446,18 +420,17 @@ Item {
}
bodyLoader.setSource("LoggingInBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader,
- "withSteam": linkAccountBody.withSteam, "withOculus": linkAccountBody.withOculus, "linkSteam": linkAccountBody.linkSteam });
+ "withSteam": linkAccountBody.withSteam, "withOculus": linkAccountBody.withOculus, "linkSteam": linkAccountBody.linkSteam, "linkOculus": linkAccountBody.linkOculus });
}
Component.onCompleted: {
- if (linkAccountBody.linkSteam) {
+ if (linkAccountBody.linkSteam || linkAccountBody.linkOculus) {
continueButton.visible = false;
return;
}
- // if (loginDialog.isOculusStoreRunning()) {
- // continueButton.text = qsTr("CONTINUE WITH OCULUS");
- // continueButton.buttonGlyph = hifi.glyphs.oculus;
- // } else
- if (loginDialog.isSteamRunning()) {
+ if (loginDialog.isOculusRunning()) {
+ continueButton.text = qsTr("CONTINUE WITH OCULUS");
+ continueButton.buttonGlyph = hifi.glyphs.oculus;
+ } else if (loginDialog.isSteamRunning()) {
continueButton.text = qsTr("CONTINUE WITH STEAM");
continueButton.buttonGlyph = hifi.glyphs.steamSquare;
} else {
@@ -470,7 +443,7 @@ Item {
id: signUpContainer
width: loginContainer.width
height: signUpTextMetrics.height
- visible: !linkAccountBody.linkSteam
+ visible: !linkAccountBody.linkSteam && !linkAccountBody.linkOculus
anchors {
left: loginContainer.left
top: loginContainer.bottom
@@ -519,7 +492,7 @@ Item {
UserActivityLogger.logAction("encourageLoginDialog", data);
}
bodyLoader.setSource("SignUpBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader,
- "errorString": "", "linkSteam": linkAccountBody.linkSteam });
+ "errorString": "" });
}
}
}
@@ -543,7 +516,7 @@ Item {
fontFamily: linkAccountBody.fontFamily
fontSize: linkAccountBody.fontSize
fontBold: linkAccountBody.fontBold
- visible: linkAccountBody.loginDialogPoppedUp && !linkAccountBody.linkSteam;
+ visible: loginDialog.getLoginDialogPoppedUp() && !linkAccountBody.linkSteam && !linkAccountBody.linkOculus;
onClicked: {
if (linkAccountBody.loginDialogPoppedUp) {
var data = {
diff --git a/interface/resources/qml/LoginDialog/LoggingInBody.qml b/interface/resources/qml/LoginDialog/LoggingInBody.qml
index 5e4a6c4cb3..583f00583b 100644
--- a/interface/resources/qml/LoginDialog/LoggingInBody.qml
+++ b/interface/resources/qml/LoginDialog/LoggingInBody.qml
@@ -29,6 +29,8 @@ Item {
property bool withSteam: withSteam
property bool withOculus: withOculus
property bool linkSteam: linkSteam
+ property bool linkOculus: linkOculus
+ property bool createOculus: createOculus
readonly property bool loginDialogPoppedUp: loginDialog.getLoginDialogPoppedUp()
@@ -75,15 +77,25 @@ Item {
}
}
+ Timer {
+ id: oculusSuccessTimer
+ interval: 500;
+ running: false;
+ repeat: false;
+ onTriggered: {
+ loginDialog.loginThroughOculus();
+ init();
+ }
+ }
+
function init() {
// For the process of logging in.
loggingInText.wrapMode = Text.NoWrap;
-
- if (loggingInBody.linkSteam) {
+ if (loggingInBody.createOculus) {
+ loggingInGlyph.text = hifi.glyphs.oculus;
loggingInGlyph.visible = true;
- loggingInText.text = "Linking to Steam";
+ loggingInText.text = "Creating account with Oculus";
loggingInText.x = loggingInHeader.width/2 - loggingInTextMetrics.width/2 + loggingInGlyphTextMetrics.width/2;
- loginDialog.linkSteam();
} else if (loggingInBody.withSteam) {
loggingInGlyph.visible = true;
loggingInText.text = "Logging in to Steam";
@@ -100,12 +112,18 @@ Item {
loggingInSpinner.visible = true;
}
function loadingSuccess() {
- loggingInSpinner.visible = false;
if (loggingInBody.linkSteam) {
loggingInText.text = "Linking to Steam";
+ loggingInText.x = loggingInHeader.width/2 - loggingInTextMetrics.width/2 + loggingInGlyphTextMetrics.width/2;
loginDialog.linkSteam();
return;
+ } else if (loggingInBody.linkOculus) {
+ loggingInText.text = "Linking to Oculus";
+ loggingInText.x = loggingInHeader.width/2 - loggingInTextMetrics.width/2 + loggingInGlyphTextMetrics.width/2;
+ loginDialog.linkOculus();
+ return;
}
+ loggingInSpinner.visible = false;
if (loggingInBody.withSteam) {
// reset the flag.
loggingInGlyph.visible = false;
@@ -246,6 +264,26 @@ Item {
verticalAlignment: Text.AlignVCenter;
visible: false;
}
+ HifiControlsUit.Button {
+ id: okButton;
+ width: d.minWidthButton
+ height: d.minHeightButton
+ text: qsTr("OK")
+ color: hifi.buttons.white
+ anchors {
+ top: loggedInGlyph.bottom
+ topMargin: 3 * hifi.dimensions.contentSpacing.y
+ left: parent.left
+ leftMargin: (parent.width - width) / 2;
+ }
+ onClicked: {
+ root.tryDestroy();
+ if (loginDialog.getLoginDialogPoppedUp()) {
+ loginDialog.dismissLoginDialog();
+ }
+ }
+ visible: false
+ }
}
}
}
@@ -257,6 +295,34 @@ Item {
Connections {
target: loginDialog
+ onHandleCreateCompleted: {
+ console.log("Create Succeeded")
+ if (loggingInBody.withOculus) {
+ if (loggingInBody.loginDialogPoppedUp) {
+ var data = {
+ "action": "user created Oculus account successfully"
+ };
+ UserActivityLogger.logAction("encourageLoginDialog", data);
+ }
+ loggingInBody.createOculus = false;
+ loggingInText.text = "Account created!";
+ loggingInText.x = loggingInHeader.width/2 - loggingInTextMetrics.width/2 + loggingInGlyphTextMetrics.width/2;
+ oculusSuccessTimer.start();
+ }
+ }
+ onHandleCreateFailed: {
+ console.log("Create Failed: " + error);
+ if (loggingInBody.withOculus) {
+ if (loggingInBody.loginDialogPoppedUp) {
+ var data = {
+ "action": "user created Oculus account unsuccessfully"
+ };
+ UserActivityLogger.logAction("encourageLoginDialog", data);
+ }
+ bodyLoader.setSource("CompleteProfileBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": loggingInBody.withSteam,
+ "withOculus": loggingInBody.withOculus, "errorString": error });
+ }
+ }
onHandleLinkCompleted: {
console.log("Link Succeeded");
if (loggingInBody.linkSteam) {
@@ -267,21 +333,40 @@ Item {
};
UserActivityLogger.logAction("encourageLoginDialog", data);
}
-
- loggingInBody.loadingSuccess();
+ } else if (loggingInBody.linkOculus) {
+ loggingInBody.linkOculus = false;
+ if (loggingInBody.loginDialogPoppedUp) {
+ var data = {
+ "action": "user linked Oculus with their hifi account credentials successfully"
+ };
+ UserActivityLogger.logAction("encourageLoginDialog", data);
+ }
}
+ loggingInBody.loadingSuccess();
}
onHandleLinkFailed: {
console.log("Link Failed: " + error);
- if (loggingInBody.linkSteam) {
+ loggingInSpinner.visible = false;
+ if (loggingInBody.linkOculus) {
+ loggingInText.text = "Oculus failed to link";
+ if (loggingInBody.loginDialogPoppedUp) {
+ var data = {
+ "action": "user linked Oculus unsuccessfully"
+ };
+ UserActivityLogger.logAction("encourageLoginDialog", data);
+ }
+ okButton.visible = true;
+ } else if (loggingInBody.linkSteam){
if (loggingInBody.loginDialogPoppedUp) {
var data = {
"action": "user linked Steam unsuccessfully"
};
UserActivityLogger.logAction("encourageLoginDialog", data);
}
+ } else {
+ bodyLoader.setSource("LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "linkSteam": loggingInBody.linkSteam,
+ "linkOculus": loggingInBody.linkOculus, "errorString": error });
}
- bodyLoader.setSource("LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "linkSteam": true, "errorString": error });
}
onHandleLoginCompleted: {
@@ -292,8 +377,19 @@ Item {
onHandleLoginFailed: {
console.log("Login Failed")
loggingInSpinner.visible = false;
+ loggingInGlyph.visible = false;
var errorString = "";
- if (loggingInBody.linkSteam && loggingInBody.withSteam) {
+ if (loggingInBody.linkOculus && loggingInBody.withOculus) {
+ errorString = "Username or password is incorrect.";
+ if (loggingInBody.loginDialogPoppedUp) {
+ var data = {
+ "action": "user failed to link Oculus with their hifi account credentials"
+ };
+ UserActivityLogger.logAction("encourageLoginDialog", data);
+ }
+ bodyLoader.setSource("LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": loggingInBody.withSteam,
+ "withOculus": loggingInBody.withOculus, "linkSteam": loggingInBody.linkSteam, "linkOculus": loggingInBody.linkOculus, "errorString": errorString });
+ } else if (loggingInBody.linkSteam && loggingInBody.withSteam) {
errorString = "Username or password is incorrect.";
if (loggingInBody.loginDialogPoppedUp) {
var data = {
@@ -301,9 +397,9 @@ Item {
};
UserActivityLogger.logAction("encourageLoginDialog", data);
}
- bodyLoader.setSource("LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": loggingInBody.withSteam, "linkSteam": loggingInBody.linkSteam, "errorString": errorString });
+ bodyLoader.setSource("LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": loggingInBody.withSteam,
+ "withOculus": loggingInBody.withOculus, "linkSteam": loggingInBody.linkSteam, "linkOculus": loggingInBody.linkOculus, "errorString": errorString });
} else if (loggingInBody.withSteam) {
- loggingInGlyph.visible = false;
errorString = "Your Steam authentication has failed. Please make sure you are logged into Steam and try again.";
if (loggingInBody.loginDialogPoppedUp) {
var data = {
@@ -311,19 +407,19 @@ Item {
};
UserActivityLogger.logAction("encourageLoginDialog", data);
}
- bodyLoader.setSource("CompleteProfileBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": loggingInBody.withSteam, "errorString": errorString });
+ bodyLoader.setSource("CompleteProfileBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": loggingInBody.withSteam,
+ "withOculus": loggingInBody.withOculus, "linkSteam": loggingInBody.linkSteam, "linkOculus": loggingInBody.linkOculus, "errorString": errorString });
} else if (loggingInBody.withOculus) {
- loggingInGlyph.visible = false;
- errorString = "Your Oculus authentication has failed. Please make sure you are logged into Oculus and try again."
+ errorString = "Your Oculus account is not connected to an existing High Fidelity account. Please create a new one."
if (loggingInBody.loginDialogPoppedUp) {
var data = {
"action": "user failed to authenticate with Oculus to log in"
};
UserActivityLogger.logAction("encourageLoginDialog", data);
}
- bodyLoader.setSource("LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "errorString": errorString });
- }
- else {
+ bodyLoader.setSource("CompleteProfileBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": loggingInBody.withSteam,
+ "withOculus": loggingInBody.withOculus, "linkSteam": loggingInBody.linkSteam, "linkOculus": loggingInBody.linkOculus, "errorString": errorString });
+ } else {
errorString = "Username or password is incorrect.";
if (loggingInBody.loginDialogPoppedUp) {
var data = {
diff --git a/interface/resources/qml/LoginDialog/SignUpBody.qml b/interface/resources/qml/LoginDialog/SignUpBody.qml
index 3ba66391e6..64df9089a1 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
@@ -37,7 +38,6 @@ Item {
onKeyboardRaisedChanged: d.resize();
property string errorString: errorString
- property bool linkSteam: linkSteam
property bool lostFocus: false
readonly property bool loginDialogPoppedUp: loginDialog.getLoginDialogPoppedUp()
@@ -73,7 +73,6 @@ Item {
function init() {
// going to/from sign in/up dialog.
- loginDialog.isLogIn = false;
emailField.placeholderText = "Email";
emailField.text = "";
emailField.anchors.top = usernameField.bottom;
@@ -353,7 +352,7 @@ Item {
}
UserActivityLogger.logAction("encourageLoginDialog", data);
}
- bodyLoader.setSource("LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "linkSteam": signUpBody.linkSteam });
+ bodyLoader.setSource("LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "linkSteam": false });
}
}
HifiControlsUit.Button {
@@ -380,6 +379,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.white
+ linkColor: hifi.colors.blueAccent
+ lineHeight: 1
+ lineHeightMode: Text.ProportionalHeight
+
+ onLinkActivated: loginDialog.openUrl(link);
+
+ Component.onCompleted: {
+ if (termsTextMetrics.width > root.bannerWidth) {
+ 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;
+ }
+ }
+ }
+ }
}
}
@@ -433,14 +480,15 @@ Item {
if (errorString !== "") {
loginErrorMessage.visible = true;
+ var errorLength = errorString.split(/\r\n|\r|\n/).length;
var errorStringEdited = errorString.replace(/[\n\r]+/g, "\n");
loginErrorMessage.text = errorStringEdited;
- loginErrorMessageTextMetrics.text = errorString;
- if (loginErrorMessageTextMetrics.width > usernameField.width) {
+ if (errorLength > 1.0) {
+ loginErrorMessage.width = root.bannerWidth;
loginErrorMessage.wrapMode = Text.WordWrap;
loginErrorMessage.verticalAlignment = Text.AlignLeft;
loginErrorMessage.horizontalAlignment = Text.AlignLeft;
- errorContainer.height = (loginErrorMessageTextMetrics.width / usernameField.width) * loginErrorMessageTextMetrics.height;
+ errorContainer.height = errorLength * loginErrorMessageTextMetrics.height;
}
errorContainer.anchors.bottom = usernameField.top;
errorContainer.anchors.bottomMargin = hifi.dimensions.contentSpacing.y;
diff --git a/interface/resources/qml/LoginDialog/UsernameCollisionBody.qml b/interface/resources/qml/LoginDialog/UsernameCollisionBody.qml
index af46fc0223..2c8e61a29a 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"
@@ -26,13 +27,18 @@ Item {
readonly property int textFieldFontSize: 18
readonly property bool fontBold: true
- readonly property bool withSteam: withSteam
+ property bool withSteam: withSteam
+ property bool withOculus: withOculus
readonly property bool loginDialogPoppedUp: loginDialog.getLoginDialogPoppedUp()
function create() {
mainTextContainer.visible = false
- loginDialog.createAccountFromSteam(textField.text);
+ if (usernameCollisionBody.withOculus) {
+ loginDialog.createAccountFromOculus(textField.text);
+ } else if (usernameCollisionBody.withSteam) {
+ loginDialog.createAccountFromSteam(textField.text);
+ }
}
property bool keyboardEnabled: false
@@ -90,12 +96,19 @@ Item {
font.family: usernameCollisionBody.fontFamily
font.pixelSize: usernameCollisionBody.fontSize
font.bold: usernameCollisionBody.fontBold
- text: qsTr("Your Steam username is not available.");
+ text: qsTr("");
wrapMode: Text.WordWrap
color: hifi.colors.redAccent
lineHeight: 1
lineHeightMode: Text.ProportionalHeight
horizontalAlignment: Text.AlignHCenter
+ Component.onCompleted: {
+ if (usernameCollisionBody.withOculus) {
+ text = qsTr("Your Oculus username is not available.");
+ } else if (usernameCollisionBody.withSteam) {
+ text = qsTr("Your Steam username is not available.");
+ }
+ }
}
@@ -164,7 +177,8 @@ Item {
fontSize: usernameCollisionBody.fontSize
fontBold: usernameCollisionBody.fontBold
onClicked: {
- bodyLoader.setSource("CompleteProfileBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "errorString": "" });
+ bodyLoader.setSource("CompleteProfileBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": usernameCollisionBody.withSteam,
+ "withOculus": usernameCollisionBody.withOculus, "errorString": "" });
}
}
HifiControlsUit.Button {
@@ -187,6 +201,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.white
+ linkColor: hifi.colors.blueAccent
+ lineHeight: 1
+ lineHeightMode: Text.ProportionalHeight
+
+ onLinkActivated: loginDialog.openUrl(link);
+
+ Component.onCompleted: {
+ if (termsTextMetrics.width > root.bannerWidth) {
+ 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: {
@@ -201,18 +264,25 @@ Item {
target: loginDialog
onHandleCreateCompleted: {
console.log("Create Succeeded");
- if (usernameCollisionBody.withSteam) {
+ if (usernameCollisionBody.withOculus) {
+ if (usernameCollisionBody.loginDialogPoppedUp) {
+ var data = {
+ "action": "user created a profile with Oculus successfully in the username collision screen"
+ }
+ UserActivityLogger.logAction("encourageLoginDialog", data);
+ }
+ loginDialog.loginThroughOculus();
+ } else if (usernameCollisionBody.withSteam) {
if (usernameCollisionBody.loginDialogPoppedUp) {
var data = {
"action": "user created a profile with Steam successfully in the username collision screen"
}
UserActivityLogger.logAction("encourageLoginDialog", data);
}
-
loginDialog.loginThroughSteam();
}
-
- bodyLoader.setSource("LoggingInBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": usernameCollisionBody.withSteam, "linkSteam": false })
+ bodyLoader.setSource("LoggingInBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": usernameCollisionBody.withSteam,
+ "withOculus": usernameCollisionBody.withOculus, "linkSteam": false, "linkOculus": false })
}
onHandleCreateFailed: {
console.log("Create Failed: " + error)
diff --git a/interface/resources/qml/OverlayLoginDialog.qml b/interface/resources/qml/OverlayLoginDialog.qml
index 8f709af2ab..0ad2c57e5f 100644
--- a/interface/resources/qml/OverlayLoginDialog.qml
+++ b/interface/resources/qml/OverlayLoginDialog.qml
@@ -150,6 +150,6 @@ FocusScope {
Component.onCompleted: {
keyboardTimer.start();
- bodyLoader.setSource("LoginDialog/LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "linkSteam": false });
+ bodyLoader.setSource("LoginDialog/LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "linkSteam": false, "linkOculus": false });
}
}
diff --git a/interface/resources/qml/dialogs/TabletLoginDialog.qml b/interface/resources/qml/dialogs/TabletLoginDialog.qml
index 3ad17430cd..8d6444bc0e 100644
--- a/interface/resources/qml/dialogs/TabletLoginDialog.qml
+++ b/interface/resources/qml/dialogs/TabletLoginDialog.qml
@@ -14,6 +14,8 @@ import QtQuick 2.5
import controlsUit 1.0 as HifiControlsUit
import stylesUit 1.0 as HifiStylesUit
+import TabletScriptingInterface 1.0
+
import "../LoginDialog"
FocusScope {
@@ -25,10 +27,9 @@ FocusScope {
width: parent.width
height: parent.height
- signal sendToScript(var message);
- signal canceled();
+ property var tabletProxy: Tablet.getTablet("com.highfidelity.interface.tablet.system");
- property bool isHMD: false
+ property bool isHMD: HMD.active
property bool gotoPreviousApp: false;
property bool keyboardEnabled: false
@@ -52,6 +53,7 @@ FocusScope {
}
function tryDestroy() {
+ tabletProxy.gotoHomeScreen();
}
MouseArea {
@@ -76,7 +78,7 @@ FocusScope {
interval: 200
onTriggered: {
- if (MenuInterface.isOptionChecked("Use 3D Keyboard")) {
+ if (MenuInterface.isOptionChecked("Use 3D Keyboard") && root.isHMD) {
KeyboardScriptingInterface.raised = true;
}
}
@@ -169,11 +171,13 @@ FocusScope {
Component.onDestruction: {
loginKeyboard.raised = false;
- KeyboardScriptingInterface.raised = false;
+ if (root.isHMD) {
+ KeyboardScriptingInterface.raised = false;
+ }
}
Component.onCompleted: {
keyboardTimer.start();
- bodyLoader.setSource("../LoginDialog/LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "linkSteam": false });
+ bodyLoader.setSource("../LoginDialog/LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "linkSteam": false, "linkOculus": false });
}
}
diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp
index 68ac05ef18..30d422949f 100644
--- a/interface/src/Application.cpp
+++ b/interface/src/Application.cpp
@@ -120,6 +120,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -800,7 +801,6 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) {
if (auto steamClient = pluginManager->getSteamClientPlugin()) {
steamClient->init();
}
-
PROFILE_SET_THREAD_NAME("Main Thread");
#if defined(Q_OS_WIN)
@@ -2737,6 +2737,7 @@ Application::~Application() {
if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) {
steamClient->shutdown();
}
+
DependencyManager::destroy();
DependencyManager::destroy(); // must be destroyed before the FramebufferCache
@@ -4873,6 +4874,10 @@ void Application::idle() {
steamClient->runCallbacks();
}
+ if (auto oculusPlugin = PluginManager::getInstance()->getOculusPlatformPlugin()) {
+ oculusPlugin->handleOVREvents();
+ }
+
float secondsSinceLastUpdate = (float)_lastTimeUpdated.nsecsElapsed() / NSECS_PER_MSEC / MSECS_PER_SECOND;
_lastTimeUpdated.start();
diff --git a/interface/src/ui/LoginDialog.cpp b/interface/src/ui/LoginDialog.cpp
index 6e9c91785f..4359318833 100644
--- a/interface/src/ui/LoginDialog.cpp
+++ b/interface/src/ui/LoginDialog.cpp
@@ -18,6 +18,7 @@
#include
#include
+#include
#include
#include
#include
@@ -109,8 +110,16 @@ bool LoginDialog::isSteamRunning() const {
return steamClient && steamClient->isRunning();
}
-bool LoginDialog::isOculusStoreRunning() const {
- return qApp->property(hifi::properties::OCULUS_STORE).toBool();
+bool LoginDialog::isOculusRunning() const {
+ auto oculusPlatformPlugin = PluginManager::getInstance()->getOculusPlatformPlugin();
+ return (oculusPlatformPlugin && oculusPlatformPlugin->isRunning());
+}
+
+QString LoginDialog::oculusUserID() const {
+ if (auto oculusPlatformPlugin = PluginManager::getInstance()->getOculusPlatformPlugin()) {
+ return oculusPlatformPlugin->getOculusUserID();
+ }
+ return "";
}
void LoginDialog::dismissLoginDialog() {
@@ -126,6 +135,79 @@ void LoginDialog::login(const QString& username, const QString& password) const
DependencyManager::get()->requestAccessToken(username, password);
}
+void LoginDialog::loginThroughOculus() {
+ qDebug() << "Attempting to login through Oculus";
+ if (auto oculusPlatformPlugin = PluginManager::getInstance()->getOculusPlatformPlugin()) {
+ oculusPlatformPlugin->requestNonceAndUserID([this] (QString nonce, QString oculusID) {
+ DependencyManager::get()->requestAccessTokenWithOculus(nonce, oculusID);
+ });
+ }
+}
+
+void LoginDialog::linkOculus() {
+ qDebug() << "Attempting to link Oculus account";
+ if (auto oculusPlatformPlugin = PluginManager::getInstance()->getOculusPlatformPlugin()) {
+ oculusPlatformPlugin->requestNonceAndUserID([this] (QString nonce, QString oculusID) {
+ if (nonce.isEmpty() || oculusID.isEmpty()) {
+ emit handleLoginFailed();
+ return;
+ }
+
+ JSONCallbackParameters callbackParams;
+ callbackParams.callbackReceiver = this;
+ callbackParams.jsonCallbackMethod = "linkCompleted";
+ callbackParams.errorCallbackMethod = "linkFailed";
+ const QString LINK_OCULUS_PATH = "api/v1/user/oculus/link";
+
+ QJsonObject payload;
+ payload["oculus_nonce"] = nonce;
+ payload["oculus_id"] = oculusID;
+
+ auto accountManager = DependencyManager::get();
+ accountManager->sendRequest(LINK_OCULUS_PATH, AccountManagerAuth::Required,
+ QNetworkAccessManager::PostOperation, callbackParams,
+ QJsonDocument(payload).toJson());
+ });
+ }
+}
+
+void LoginDialog::createAccountFromOculus(QString email, QString username, QString password) {
+ qDebug() << "Attempting to create account from Oculus info";
+ if (auto oculusPlatformPlugin = PluginManager::getInstance()->getOculusPlatformPlugin()) {
+ oculusPlatformPlugin->requestNonceAndUserID([this, email, username, password] (QString nonce, QString oculusID) {
+ if (nonce.isEmpty() || oculusID.isEmpty()) {
+ emit handleLoginFailed();
+ return;
+ }
+
+ JSONCallbackParameters callbackParams;
+ callbackParams.callbackReceiver = this;
+ callbackParams.jsonCallbackMethod = "createCompleted";
+ callbackParams.errorCallbackMethod = "createFailed";
+
+ const QString CREATE_ACCOUNT_FROM_OCULUS_PATH = "api/v1/user/oculus/create";
+
+ QJsonObject payload;
+ payload["oculus_nonce"] = nonce;
+ payload["oculus_id"] = oculusID;
+ if (!email.isEmpty()) {
+ payload["email"] = email;
+ }
+ if (!username.isEmpty()) {
+ payload["username"] = username;
+ }
+ if (!password.isEmpty()) {
+ payload["password"] = password;
+ }
+
+ auto accountManager = DependencyManager::get();
+ accountManager->sendRequest(CREATE_ACCOUNT_FROM_OCULUS_PATH, AccountManagerAuth::None,
+ QNetworkAccessManager::PostOperation, callbackParams,
+ QJsonDocument(payload).toJson());
+ });
+ }
+}
+
void LoginDialog::loginThroughSteam() {
qDebug() << "Attempting to login through Steam";
if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) {
@@ -157,7 +239,7 @@ void LoginDialog::linkSteam() {
const QString LINK_STEAM_PATH = "api/v1/user/steam/link";
QJsonObject payload;
- payload.insert("steam_auth_ticket", QJsonValue::fromVariant(QVariant(ticket)));
+ payload["steam_auth_ticket"] = QJsonValue::fromVariant(QVariant(ticket));
auto accountManager = DependencyManager::get();
accountManager->sendRequest(LINK_STEAM_PATH, AccountManagerAuth::Required,
@@ -184,9 +266,9 @@ void LoginDialog::createAccountFromSteam(QString username) {
const QString CREATE_ACCOUNT_FROM_STEAM_PATH = "api/v1/user/steam/create";
QJsonObject payload;
- payload.insert("steam_auth_ticket", QJsonValue::fromVariant(QVariant(ticket)));
+ payload["steam_auth_ticket"] = QJsonValue::fromVariant(QVariant(ticket));
if (!username.isEmpty()) {
- payload.insert("username", QJsonValue::fromVariant(QVariant(username)));
+ payload["username"] = username;
}
auto accountManager = DependencyManager::get();
@@ -214,6 +296,45 @@ void LoginDialog::createCompleted(QNetworkReply* reply) {
}
void LoginDialog::createFailed(QNetworkReply* reply) {
+ if (isOculusRunning()) {
+ auto replyData = reply->readAll();
+ QJsonParseError parseError;
+ auto doc = QJsonDocument::fromJson(replyData, &parseError);
+ if (parseError.error != QJsonParseError::NoError) {
+ emit handleCreateFailed(reply->errorString());
+ return;
+ }
+ auto data = doc["data"];
+ auto error = data["error"];
+ auto oculusError = data["oculus"];
+ auto user = error["username"].toArray();
+ auto uid = error["uid"].toArray();
+ auto email = error["email"].toArray();
+ auto password = error["password"].toArray();
+ QString reply;
+ if (uid[0].isString()) {
+ emit handleCreateFailed("Oculus ID " + uid[0].toString() + ".");
+ return;
+ }
+ if (user[0].isString()) {
+ reply = "Username " + user[0].toString() + ".";
+ }
+ if (email[0].isString()) {
+ reply.append((!reply.isEmpty()) ? "\n" : "");
+ reply.append("Email " + email[0].toString() + ".");
+ }
+ if (password[0].isString()) {
+ reply.append((!reply.isEmpty()) ? "\n" : "");
+ reply.append("Password " + password[0].toString() + ".");
+ }
+ if (!oculusError.isNull() && !oculusError.isUndefined()) {
+ emit handleCreateFailed("Could not verify token with Oculus. Please try again.");
+ return;
+ } else {
+ emit handleCreateFailed(reply);
+ return;
+ }
+ }
emit handleCreateFailed(reply->errorString());
}
diff --git a/interface/src/ui/LoginDialog.h b/interface/src/ui/LoginDialog.h
index 2714d654bf..7c932932cf 100644
--- a/interface/src/ui/LoginDialog.h
+++ b/interface/src/ui/LoginDialog.h
@@ -22,7 +22,6 @@ extern const QUrl OVERLAY_LOGIN_DIALOG;
class LoginDialog : public OffscreenQmlDialog {
Q_OBJECT
- Q_PROPERTY(bool isLogIn READ getIsLogIn WRITE setIsLogIn)
HIFI_QML_DECL
public:
@@ -67,24 +66,23 @@ protected slots:
Q_INVOKABLE void dismissLoginDialog();
Q_INVOKABLE bool isSteamRunning() const;
- Q_INVOKABLE bool isOculusStoreRunning() const;
+ Q_INVOKABLE bool isOculusRunning() const;
+
+ Q_INVOKABLE QString oculusUserID() const;
Q_INVOKABLE void login(const QString& username, const QString& password) const;
Q_INVOKABLE void loginThroughSteam();
Q_INVOKABLE void linkSteam();
Q_INVOKABLE void createAccountFromSteam(QString username = QString());
+ Q_INVOKABLE void loginThroughOculus();
+ Q_INVOKABLE void linkOculus();
+ Q_INVOKABLE void createAccountFromOculus(QString email = QString(), QString username = QString(), QString password = QString());
Q_INVOKABLE void signup(const QString& email, const QString& username, const QString& password);
Q_INVOKABLE void openUrl(const QString& url) const;
Q_INVOKABLE bool getLoginDialogPoppedUp() const;
-
-private:
- bool getIsLogIn() const { return _isLogIn; }
- void setIsLogIn(const bool isLogIn) { _isLogIn = isLogIn; }
-
- bool _isLogIn{ false };
};
#endif // hifi_LoginDialog_h
diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h
index a061a4c923..944d5e89d1 100644
--- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h
+++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h
@@ -31,6 +31,8 @@ public:
virtual void compositeExtra() override;
+ virtual void pluginUpdate() override {};
+
protected:
mutable bool _isThrottled = false;
diff --git a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h
index 11563b3798..e4ff1b8b37 100644
--- a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h
+++ b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h
@@ -20,6 +20,7 @@ public:
QImage getScreenshot(float aspectRatio = 0.0f) const override;
QImage getSecondaryCameraScreenshot() const override;
void copyTextureToQuickFramebuffer(NetworkTexturePointer source, QOpenGLFramebufferObject* target, GLsync* fenceSync) override {};
+ void pluginUpdate() override {};
private:
static const QString NAME;
};
diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h
index a56daaad83..4aeacbe05c 100644
--- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h
+++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h
@@ -46,6 +46,8 @@ public:
virtual bool onDisplayTextureReset() override { _clearPreviewFlag = true; return true; };
+ void pluginUpdate() override {};
+
signals:
void hmdMountedChanged();
void hmdVisibleChanged(bool visible);
diff --git a/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.h
index 5a7ca24059..a55bde0f4e 100644
--- a/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.h
+++ b/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.h
@@ -28,6 +28,8 @@ public:
// to the HMD plugins.
//virtual glm::mat4 getEyeToHeadTransform(Eye eye) const override;
+ virtual void pluginUpdate() override {};
+
protected:
virtual bool internalActivate() override;
virtual void internalDeactivate() override;
diff --git a/libraries/networking/src/AccountManager.cpp b/libraries/networking/src/AccountManager.cpp
index 989661cb81..f74b337ee7 100644
--- a/libraries/networking/src/AccountManager.cpp
+++ b/libraries/networking/src/AccountManager.cpp
@@ -588,6 +588,29 @@ void AccountManager::requestAccessTokenWithSteam(QByteArray authSessionTicket) {
connect(requestReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(requestAccessTokenError(QNetworkReply::NetworkError)));
}
+void AccountManager::requestAccessTokenWithOculus(const QString& nonce, const QString &oculusID) {
+ QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
+
+ QNetworkRequest request;
+ request.setHeader(QNetworkRequest::UserAgentHeader, _userAgentGetter());
+
+ QUrl grantURL = _authURL;
+ grantURL.setPath("/oauth/token");
+
+ QByteArray postData;
+ postData.append("grant_type=password&");
+ postData.append("oculus_nonce=" + nonce + "&");
+ postData.append("oculus_id=" + oculusID + "&");
+ postData.append("scope=" + ACCOUNT_MANAGER_REQUESTED_SCOPE);
+
+ request.setUrl(grantURL);
+ request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
+
+ QNetworkReply* requestReply = networkAccessManager.post(request, postData);
+ connect(requestReply, &QNetworkReply::finished, this, &AccountManager::requestAccessTokenFinished);
+ connect(requestReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(requestAccessTokenError(QNetworkReply::NetworkError)));
+}
+
void AccountManager::refreshAccessToken() {
// we can't refresh our access token if we don't have a refresh token, so check for that first
diff --git a/libraries/networking/src/AccountManager.h b/libraries/networking/src/AccountManager.h
index ca2b826c98..477488031d 100644
--- a/libraries/networking/src/AccountManager.h
+++ b/libraries/networking/src/AccountManager.h
@@ -106,6 +106,7 @@ public:
public slots:
void requestAccessToken(const QString& login, const QString& password);
void requestAccessTokenWithSteam(QByteArray authSessionTicket);
+ void requestAccessTokenWithOculus(const QString& nonce, const QString& oculusID);
void requestAccessTokenWithAuthCode(const QString& authCode,
const QString& clientId,
const QString& clientSecret,
diff --git a/libraries/plugins/src/plugins/DisplayPlugin.h b/libraries/plugins/src/plugins/DisplayPlugin.h
index ad49ceafe6..fde43e7a5b 100644
--- a/libraries/plugins/src/plugins/DisplayPlugin.h
+++ b/libraries/plugins/src/plugins/DisplayPlugin.h
@@ -217,6 +217,9 @@ public:
static const QString& MENU_PATH();
+ // for updating plugin-related commands. Mimics the input plugin.
+ virtual void pluginUpdate() = 0;
+
signals:
void recommendedFramebufferSizeChanged(const QSize& size);
void resetSensorsRequested();
diff --git a/libraries/plugins/src/plugins/Forward.h b/libraries/plugins/src/plugins/Forward.h
index 90746d648e..fc1e12b639 100644
--- a/libraries/plugins/src/plugins/Forward.h
+++ b/libraries/plugins/src/plugins/Forward.h
@@ -21,6 +21,7 @@ class DisplayPlugin;
class InputPlugin;
class CodecPlugin;
class SteamClientPlugin;
+class OculusPlatformPlugin;
class Plugin;
class PluginContainer;
class PluginManager;
@@ -35,4 +36,5 @@ using CodecPluginPointer = std::shared_ptr;
using CodecPluginList = std::vector;
using CodecPluginProvider = std::function;
using SteamClientPluginPointer = std::shared_ptr;
+using OculusPlatformPluginPointer = std::shared_ptr;
using InputPluginSettingsPersister = std::function;
diff --git a/libraries/plugins/src/plugins/OculusPlatformPlugin.h b/libraries/plugins/src/plugins/OculusPlatformPlugin.h
new file mode 100644
index 0000000000..93bf534c6e
--- /dev/null
+++ b/libraries/plugins/src/plugins/OculusPlatformPlugin.h
@@ -0,0 +1,28 @@
+//
+// Created by Wayne Chen on 2018/12/20
+// Copyright 2018 High Fidelity Inc.
+//
+// Distributed under the Apache License, Version 2.0.
+// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2-0.html
+//
+#pragma once
+
+#include
+
+#include
+
+using NonceUserIDCallback = std::function;
+
+class OculusPlatformPlugin {
+public:
+ virtual ~OculusPlatformPlugin() = default;
+
+ virtual QString getName() const = 0;
+ virtual QString getOculusUserID() const = 0;
+
+ virtual bool isRunning() const = 0;
+
+ virtual void requestNonceAndUserID(NonceUserIDCallback callback) = 0;
+
+ virtual void handleOVREvents() = 0;
+};
diff --git a/libraries/plugins/src/plugins/PluginManager.cpp b/libraries/plugins/src/plugins/PluginManager.cpp
index 13fa75f030..0d0209e35f 100644
--- a/libraries/plugins/src/plugins/PluginManager.cpp
+++ b/libraries/plugins/src/plugins/PluginManager.cpp
@@ -188,6 +188,22 @@ const SteamClientPluginPointer PluginManager::getSteamClientPlugin() {
return steamClientPlugin;
}
+const OculusPlatformPluginPointer PluginManager::getOculusPlatformPlugin() {
+ static OculusPlatformPluginPointer oculusPlatformPlugin;
+ static std::once_flag once;
+ std::call_once(once, [&] {
+ // Now grab the dynamic plugins
+ for (auto loader : getLoadedPlugins()) {
+ OculusPlatformProvider* oculusPlatformProvider = qobject_cast(loader->instance());
+ if (oculusPlatformProvider) {
+ oculusPlatformPlugin = oculusPlatformProvider->getOculusPlatformPlugin();
+ break;
+ }
+ }
+ });
+ return oculusPlatformPlugin;
+}
+
const DisplayPluginList& PluginManager::getDisplayPlugins() {
static std::once_flag once;
static auto deviceAddedCallback = [](QString deviceName) {
diff --git a/libraries/plugins/src/plugins/PluginManager.h b/libraries/plugins/src/plugins/PluginManager.h
index e340b2fa21..1a578c7406 100644
--- a/libraries/plugins/src/plugins/PluginManager.h
+++ b/libraries/plugins/src/plugins/PluginManager.h
@@ -27,6 +27,7 @@ public:
const InputPluginList& getInputPlugins();
const CodecPluginList& getCodecPlugins();
const SteamClientPluginPointer getSteamClientPlugin();
+ const OculusPlatformPluginPointer getOculusPlatformPlugin();
DisplayPluginList getPreferredDisplayPlugins();
void setPreferredDisplayPlugins(const QStringList& displays);
diff --git a/libraries/plugins/src/plugins/RuntimePlugin.h b/libraries/plugins/src/plugins/RuntimePlugin.h
index 9a7d6e0638..756b4ff585 100644
--- a/libraries/plugins/src/plugins/RuntimePlugin.h
+++ b/libraries/plugins/src/plugins/RuntimePlugin.h
@@ -51,5 +51,13 @@ public:
virtual SteamClientPluginPointer getSteamClientPlugin() = 0;
};
+class OculusPlatformProvider {
+public:
+ virtual OculusPlatformPluginPointer getOculusPlatformPlugin() = 0;
+};
+
#define SteamClientProvider_iid "com.highfidelity.plugins.steamclient"
Q_DECLARE_INTERFACE(SteamClientProvider, SteamClientProvider_iid)
+
+#define OculusPlatformProvider_iid "com.highfidelity.plugins.oculusplatform"
+Q_DECLARE_INTERFACE(OculusPlatformProvider, OculusPlatformProvider_iid)
\ No newline at end of file
diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp
index f10aba7920..a67e3127e5 100644
--- a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp
+++ b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp
@@ -12,6 +12,7 @@
#include
#include
#include
+#include
#include "OculusHelpers.h"
@@ -30,7 +31,7 @@ bool OculusBaseDisplayPlugin::beginFrameRender(uint32_t frameIndex) {
return false;
}
- if (ovr::quitRequested(status) || ovr::displayLost(status) || !ovr::handleOVREvents()) {
+ if (ovr::quitRequested(status) || ovr::displayLost(status)) {
QMetaObject::invokeMethod(qApp, "quit");
return false;
}
diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.h b/plugins/oculus/src/OculusBaseDisplayPlugin.h
index 547d3ee5fe..1abb7cdad7 100644
--- a/plugins/oculus/src/OculusBaseDisplayPlugin.h
+++ b/plugins/oculus/src/OculusBaseDisplayPlugin.h
@@ -13,6 +13,9 @@
#include
+#define OVRPL_DISABLED
+#include
+
class OculusBaseDisplayPlugin : public HmdDisplayPlugin {
using Parent = HmdDisplayPlugin;
public:
@@ -30,7 +33,7 @@ public:
QRectF getPlayAreaRect() override;
QVector getSensorPositions() override;
-
+
protected:
void customizeContext() override;
void uncustomizeContext() override;
diff --git a/plugins/oculus/src/OculusHelpers.cpp b/plugins/oculus/src/OculusHelpers.cpp
index 548afb97ab..2693b9ee7e 100644
--- a/plugins/oculus/src/OculusHelpers.cpp
+++ b/plugins/oculus/src/OculusHelpers.cpp
@@ -296,34 +296,3 @@ controller::Pose hifi::ovr::toControllerPose(ovrHandType hand,
pose.valid = true;
return pose;
}
-
-bool hifi::ovr::handleOVREvents() {
-#ifdef OCULUS_APP_ID
- if (qApp->property(hifi::properties::OCULUS_STORE).toBool()) {
- // pop messages to see if we got a return for an entitlement check
- ovrMessageHandle message = ovr_PopMessage();
-
- while (message) {
- switch (ovr_Message_GetType(message)) {
- case ovrMessage_Entitlement_GetIsViewerEntitled: {
- if (!ovr_Message_IsError(message)) {
- // this viewer is entitled, no need to flag anything
- qCDebug(oculusLog) << "Oculus Platform entitlement check succeeded, proceeding normally";
- } else {
- // we failed the entitlement check, quit
- qCDebug(oculusLog) << "Oculus Platform entitlement check failed, app will now quit" << OCULUS_APP_ID;
- return false;
- }
- }
- }
-
- // free the message handle to cleanup and not leak
- ovr_FreeMessage(message);
-
- // pop the next message to check, if there is one
- message = ovr_PopMessage();
- }
- }
-#endif
- return true;
-}
diff --git a/plugins/oculus/src/OculusHelpers.h b/plugins/oculus/src/OculusHelpers.h
index bdfc4434bb..3587117825 100644
--- a/plugins/oculus/src/OculusHelpers.h
+++ b/plugins/oculus/src/OculusHelpers.h
@@ -30,7 +30,6 @@ struct ovr {
static ovrSessionStatus getStatus(ovrResult& result);
static ovrTrackingState getTrackingState(double absTime = 0.0, ovrBool latencyMarker = ovrFalse);
static QString getError();
- static bool handleOVREvents();
static inline bool quitRequested() { return quitRequested(getStatus()); }
static inline bool reorientRequested() { return reorientRequested(getStatus()); }
diff --git a/plugins/oculus/src/OculusPlatformPlugin.cpp b/plugins/oculus/src/OculusPlatformPlugin.cpp
new file mode 100644
index 0000000000..27fb98c8b5
--- /dev/null
+++ b/plugins/oculus/src/OculusPlatformPlugin.cpp
@@ -0,0 +1,109 @@
+//
+// Created by Wayne Chen on 2019/01/08
+// Copyright 2019 High Fidelity, Inc.
+//
+// Distributed under the Apache License, Version 2.0.
+// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+#include "OculusPlatformPlugin.h"
+
+#include
+
+#include
+
+#include "OculusHelpers.h"
+
+QString OculusAPIPlugin::NAME { "Oculus Rift" };
+
+OculusAPIPlugin::OculusAPIPlugin() {
+ _session = hifi::ovr::acquireRenderSession();
+}
+
+OculusAPIPlugin::~OculusAPIPlugin() {
+ hifi::ovr::releaseRenderSession(_session);
+}
+
+bool OculusAPIPlugin::isRunning() const {
+ return (qApp->property(hifi::properties::OCULUS_STORE).toBool());
+}
+
+void OculusAPIPlugin::requestNonceAndUserID(NonceUserIDCallback callback) {
+#ifdef OCULUS_APP_ID
+ _nonceUserIDCallback = callback;
+ ovr_User_GetUserProof();
+ ovr_User_GetLoggedInUser();
+#endif
+}
+
+void OculusAPIPlugin::handleOVREvents() {
+#ifdef OCULUS_APP_ID
+ if (qApp->property(hifi::properties::OCULUS_STORE).toBool()) {
+ // pop messages to see if we got a return for an entitlement check
+ ovrMessageHandle message { nullptr };
+
+ // pop the next message to check, if there is one
+ while ((message = ovr_PopMessage())) {
+ switch (ovr_Message_GetType(message)) {
+ case ovrMessage_Entitlement_GetIsViewerEntitled: {
+ if (!ovr_Message_IsError(message)) {
+ // this viewer is entitled, no need to flag anything
+ qCDebug(oculusLog) << "Oculus Platform entitlement check succeeded, proceeding normally";
+ } else {
+ // we failed the entitlement check, quit
+ qCDebug(oculusLog) << "Oculus Platform entitlement check failed, app will now quit" << OCULUS_APP_ID;
+ QMetaObject::invokeMethod(qApp, "quit");
+ }
+ break;
+ }
+ case ovrMessage_User_Get: {
+ if (!ovr_Message_IsError(message)) {
+ qCDebug(oculusLog) << "Oculus Platform user retrieval succeeded";
+ ovrUserHandle user = ovr_Message_GetUser(message);
+ _user = ovr_User_GetOculusID(user);
+ // went all the way through the `requestNonceAndUserID()` pipeline successfully.
+ } else {
+ qCDebug(oculusLog) << "Oculus Platform user retrieval failed" << QString(ovr_Error_GetMessage(ovr_Message_GetError(message)));
+ // emit the signal so we don't hang for it anywhere else.
+ _user = "";
+ }
+ break;
+ }
+ case ovrMessage_User_GetLoggedInUser: {
+ if (!ovr_Message_IsError(message)) {
+ ovrUserHandle user = ovr_Message_GetUser(message);
+ _userID = ovr_User_GetID(user);
+ ovr_User_Get(_userID);
+ } else {
+ qCDebug(oculusLog) << "Oculus Platform user ID retrieval failed" << QString(ovr_Error_GetMessage(ovr_Message_GetError(message)));
+ // emit the signal so we don't hang for it anywhere else.
+ }
+ _userIDChanged = true;
+ break;
+ }
+ case ovrMessage_User_GetUserProof: {
+ if (!ovr_Message_IsError(message)) {
+ ovrUserProofHandle userProof = ovr_Message_GetUserProof(message);
+ _nonce = ovr_UserProof_GetNonce(userProof);
+ qCDebug(oculusLog) << "Oculus Platform nonce retrieval succeeded: " << _nonce;
+ } else {
+ qCDebug(oculusLog) << "Oculus Platform nonce retrieval failed" << QString(ovr_Error_GetMessage(ovr_Message_GetError(message)));
+ _nonce = "";
+ // emit the signal so we don't hang for it anywhere else.
+ }
+ _nonceChanged = true;
+ break;
+ }
+ }
+
+ if (_nonceChanged && _userIDChanged) {
+ _nonceUserIDCallback(_nonce, QString::number(_userID));
+ _nonceChanged = _userIDChanged = false;
+ }
+
+ // free the message handle to cleanup and not leak
+ ovr_FreeMessage(message);
+ }
+ }
+#endif
+}
diff --git a/plugins/oculus/src/OculusPlatformPlugin.h b/plugins/oculus/src/OculusPlatformPlugin.h
new file mode 100644
index 0000000000..3d80540419
--- /dev/null
+++ b/plugins/oculus/src/OculusPlatformPlugin.h
@@ -0,0 +1,39 @@
+//
+// Created by Wayne Chen on 2019/01/08
+// Copyright 2019 High Fidelity, Inc.
+//
+// Distributed under the Apache License, Version 2.0.
+// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+#pragma once
+
+#include
+
+#include
+
+#define OVRPL_DISABLED
+#include
+
+class OculusAPIPlugin : public OculusPlatformPlugin {
+public:
+ OculusAPIPlugin();
+ virtual ~OculusAPIPlugin();
+ QString getName() const { return NAME; }
+ QString getOculusUserID() const { return _user; };
+
+ bool isRunning() const;
+
+ virtual void requestNonceAndUserID(NonceUserIDCallback callback);
+
+ virtual void handleOVREvents();
+
+private:
+ static QString NAME;
+ NonceUserIDCallback _nonceUserIDCallback;
+ QString _nonce;
+ bool _nonceChanged{ false };
+ bool _userIDChanged{ false };
+ QString _user;
+ ovrID _userID;
+ ovrSession _session;
+};
diff --git a/plugins/oculus/src/OculusProvider.cpp b/plugins/oculus/src/OculusProvider.cpp
index 47ccc5304e..67871b8610 100644
--- a/plugins/oculus/src/OculusProvider.cpp
+++ b/plugins/oculus/src/OculusProvider.cpp
@@ -18,15 +18,18 @@
#include "OculusDisplayPlugin.h"
#include "OculusDebugDisplayPlugin.h"
+#include "OculusPlatformPlugin.h"
#include "OculusControllerManager.h"
-class OculusProvider : public QObject, public DisplayProvider, InputProvider
+class OculusProvider : public QObject, public DisplayProvider, InputProvider, OculusPlatformProvider
{
Q_OBJECT
Q_PLUGIN_METADATA(IID DisplayProvider_iid FILE "oculus.json")
Q_INTERFACES(DisplayProvider)
Q_PLUGIN_METADATA(IID InputProvider_iid FILE "oculus.json")
Q_INTERFACES(InputProvider)
+ Q_PLUGIN_METADATA(IID OculusPlatformProvider_iid FILE "oculus.json")
+ Q_INTERFACES(OculusPlatformProvider)
public:
OculusProvider(QObject* parent = nullptr) : QObject(parent) {}
@@ -62,6 +65,15 @@ public:
return _inputPlugins;
}
+ virtual OculusPlatformPluginPointer getOculusPlatformPlugin() override {
+ static std::once_flag once;
+ std::call_once(once, [&] {
+ _oculusPlatformPlugin = std::make_shared();
+
+ });
+ return _oculusPlatformPlugin;
+ }
+
virtual void destroyInputPlugins() override {
_inputPlugins.clear();
}
@@ -73,6 +85,7 @@ public:
private:
DisplayPluginList _displayPlugins;
InputPluginList _inputPlugins;
+ OculusPlatformPluginPointer _oculusPlatformPlugin;
};
#include "OculusProvider.moc"