Unified · Split
| @@ -120,6 +120,6 @@ FocusScope { · 119 unmodified lines | |||
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | Component.onCompleted: { | 122 | Component.onCompleted: { |
| 123 | bodyLoader.setSource("LoginDialog/LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "linkSteam": false }); | 123 | bodyLoader.setSource("LoginDialog/LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "linkSteam": false, "linkOculus": false }); |
| 124 | } | 124 | } |
| 125 | } | 125 | } |
| @@ -22,11 +22,16 @@ Item { · 21 unmodified lines | |||
| 22 | width: root.width | 22 | width: root.width |
| 23 | height: root.height | 23 | height: root.height |
| 24 | readonly property string termsContainerText: qsTr("By creating this user profile, you agree to High Fidelity's Terms of Service") | 24 | readonly property string termsContainerText: qsTr("By creating this user profile, you agree to High Fidelity's Terms of Service") |
| 25 | readonly property string termsContainerOculusText: qsTr("By signing up, you agree to High Fidelity's Terms of Service") | ||
| 26 | readonly property int textFieldHeight: 31 | ||
| 25 | readonly property string fontFamily: "Raleway" | 27 | readonly property string fontFamily: "Raleway" |
| 26 | readonly property int fontSize: 15 | 28 | readonly property int fontSize: 15 |
| 27 | readonly property bool fontBold: true | 29 | readonly property bool fontBold: true |
| 30 | readonly property int textFieldFontSize: 18 | ||
| 31 | readonly property var passwordImageRatio: 16 / 23 | ||
| 28 | 32 | ||
| 29 | readonly property bool withSteam: withSteam | 33 | property bool withOculus: withOculus |
| 34 | property bool withSteam: withSteam | ||
| 30 | property string errorString: errorString | 35 | property string errorString: errorString |
| 31 | 36 | ||
| 32 | readonly property bool loginDialogPoppedUp: loginDialog.getLoginDialogPoppedUp() | 37 | readonly property bool loginDialogPoppedUp: loginDialog.getLoginDialogPoppedUp() |
| @@ -61,15 +66,20 @@ Item { · 28 unmodified lines | |||
| 61 | 66 | ||
| 62 | Item { | 67 | Item { |
| 63 | id: contentItem | 68 | id: contentItem |
| 64 | anchors.fill: parent | 69 | width: parent.width |
| 70 | height: errorContainer.height + fields.height + buttons.height + additionalTextContainer.height + | ||
| 71 | termsContainer.height | ||
| 72 | anchors.top: parent.top | ||
| 73 | anchors.topMargin: root.bannerHeight + 0.25 * parent.height | ||
| 74 | anchors.left: parent.left | ||
| 65 | 75 | ||
| 66 | Item { | 76 | Item { |
| 67 | id: errorContainer | 77 | id: errorContainer |
| 68 | width: parent.width | 78 | width: root.bannerWidth |
| 69 | height: loginErrorMessageTextMetrics.height | 79 | height: loginErrorMessageTextMetrics.height |
| 70 | anchors { | 80 | anchors { |
| 71 | bottom: buttons.top; | 81 | bottom: completeProfileBody.withOculus ? fields.top : buttons.top; |
| 72 | bottomMargin: hifi.dimensions.contentSpacing.y; | 82 | bottomMargin: 1.5 * hifi.dimensions.contentSpacing.y; |
| 73 | left: buttons.left; | 83 | left: buttons.left; |
| 74 | } | 84 | } |
| 75 | TextMetrics { | 85 | TextMetrics { |
| @@ -79,8 +89,8 @@ Item { · 3 unmodified lines | |||
| 79 | } | 89 | } |
| 80 | Text { | 90 | Text { |
| 81 | id: loginErrorMessage; | 91 | id: loginErrorMessage; |
| 82 | width: root.bannerWidth | ||
| 83 | color: "red"; | 92 | color: "red"; |
| 93 | width: root.bannerWidth; | ||
| 84 | font.family: completeProfileBody.fontFamily | 94 | font.family: completeProfileBody.fontFamily |
| 85 | font.pixelSize: 18 | 95 | font.pixelSize: 18 |
| 86 | font.bold: completeProfileBody.fontBold | 96 | font.bold: completeProfileBody.fontBold |
| @@ -88,13 +98,196 @@ Item { · 1 unmodified line | |||
| 88 | horizontalAlignment: Text.AlignHCenter | 98 | horizontalAlignment: Text.AlignHCenter |
| 89 | text: completeProfileBody.errorString | 99 | text: completeProfileBody.errorString |
| 90 | visible: true | 100 | visible: true |
| 101 | onTextChanged: { | ||
| 102 | mainContainer.recalculateErrorMessage(); | ||
| 103 | } | ||
| 104 | Component.onCompleted: { | ||
| 105 | mainContainer.recalculateErrorMessage(); | ||
| 106 | } | ||
| 107 | } | ||
| 108 | } | ||
| 109 | |||
| 110 | Item { | ||
| 111 | id: fields | ||
| 112 | width: root.bannerWidth | ||
| 113 | height: 3 * completeProfileBody.textFieldHeight + 2 * hifi.dimensions.contentSpacing.y | ||
| 114 | visible: completeProfileBody.withOculus | ||
| 115 | anchors { | ||
| 116 | left: parent.left | ||
| 117 | leftMargin: (parent.width - root.bannerWidth) / 2 | ||
| 118 | bottom: buttons.top | ||
| 119 | bottomMargin: hifi.dimensions.contentSpacing.y | ||
| 120 | } | ||
| 121 | |||
| 122 | HifiControlsUit.TextField { | ||
| 123 | id: usernameField | ||
| 124 | width: root.bannerWidth | ||
| 125 | height: completeProfileBody.textFieldHeight | ||
| 126 | placeholderText: "Username" | ||
| 127 | font.pixelSize: completeProfileBody.textFieldFontSize | ||
| 128 | styleRenderType: Text.QtRendering | ||
| 129 | anchors { | ||
| 130 | top: parent.top | ||
| 131 | } | ||
| 132 | Keys.onPressed: { | ||
| 133 | if (!usernameField.visible) { | ||
| 134 | return; | ||
| 135 | } | ||
| 136 | switch (event.key) { | ||
| 137 | case Qt.Key_Tab: | ||
| 138 | event.accepted = true; | ||
| 139 | if (event.modifiers === Qt.ShiftModifier) { | ||
| 140 | passwordField.focus = true; | ||
| 141 | } else { | ||
| 142 | emailField.focus = true; | ||
| 143 | } | ||
| 144 | break; | ||
| 145 | case Qt.Key_Backtab: | ||
| 146 | event.accepted = true; | ||
| 147 | passwordField.focus = true; | ||
| 148 | break; | ||
| 149 | case Qt.Key_Enter: | ||
| 150 | case Qt.Key_Return: | ||
| 151 | event.accepted = true; | ||
| 152 | loginDialog.createAccountFromOculus(emailField.text, usernameField.text, passwordField.text); | ||
| 153 | bodyLoader.setSource("LoggingInBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": completeProfileBody.withSteam, | ||
| 154 | "linkSteam": false, "withOculus": completeProfileBody.withOculus, "linkOculus": false, "createOculus": true }); | ||
| 155 | break; | ||
| 156 | } | ||
| 157 | } | ||
| 158 | onFocusChanged: { | ||
| 159 | root.text = ""; | ||
| 160 | if (focus) { | ||
| 161 | root.isPassword = false; | ||
| 162 | } | ||
| 163 | } | ||
| 164 | Component.onCompleted: { | ||
| 165 | var userID = ""; | ||
| 166 | if (completeProfileBody.withOculus) { | ||
| 167 | userID = loginDialog.oculusUserID(); | ||
| 168 | } | ||
| 169 | usernameField.text = userID; | ||
| 170 | } | ||
| 171 | } | ||
| 172 | HifiControlsUit.TextField { | ||
| 173 | id: emailField | ||
| 174 | width: root.bannerWidth | ||
| 175 | height: completeProfileBody.textFieldHeight | ||
| 176 | anchors { | ||
| 177 | top: usernameField.bottom | ||
| 178 | topMargin: hifi.dimensions.contentSpacing.y | ||
| 179 | } | ||
| 180 | placeholderText: "Email" | ||
| 181 | font.pixelSize: completeProfileBody.textFieldFontSize | ||
| 182 | styleRenderType: Text.QtRendering | ||
| 183 | activeFocusOnPress: true | ||
| 184 | Keys.onPressed: { | ||
| 185 | switch (event.key) { | ||
| 186 | case Qt.Key_Tab: | ||
| 187 | event.accepted = true; | ||
| 188 | if (event.modifiers === Qt.ShiftModifier) { | ||
| 189 | usernameField.focus = true; | ||
| 190 | } else { | ||
| 191 | passwordField.focus = true; | ||
| 192 | } | ||
| 193 | break; | ||
| 194 | case Qt.Key_Backtab: | ||
| 195 | event.accepted = true; | ||
| 196 | usernameField.focus = true; | ||
| 197 | break; | ||
| 198 | case Qt.Key_Enter: | ||
| 199 | case Qt.Key_Return: | ||
| 200 | event.accepted = true; | ||
| 201 | loginDialog.createAccountFromOculus(emailField.text, usernameField.text, passwordField.text); | ||
| 202 | bodyLoader.setSource("LoggingInBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": completeProfileBody.withSteam, | ||
| 203 | "linkSteam": false, "withOculus": completeProfileBody.withOculus, "linkOculus": false, "createOculus": true }); | ||
| 204 | break; | ||
| 205 | } | ||
| 206 | } | ||
| 207 | onFocusChanged: { | ||
| 208 | root.text = ""; | ||
| 209 | if (focus) { | ||
| 210 | root.isPassword = false; | ||
| 211 | } | ||
| 212 | } | ||
| 91 | } | 213 | } |
| 92 | Component.onCompleted: { | 214 | HifiControlsUit.TextField { |
| 93 | if (loginErrorMessageTextMetrics.width > root.bannerWidth && root.isTablet) { | 215 | id: passwordField |
| 94 | loginErrorMessage.wrapMode = Text.WordWrap; | 216 | width: root.bannerWidth |
| 95 | loginErrorMessage.verticalAlignment = Text.AlignLeft; | 217 | height: completeProfileBody.textFieldHeight |
| 96 | loginErrorMessage.horizontalAlignment = Text.AlignLeft; | 218 | placeholderText: "Password (optional)" |
| 97 | errorContainer.height = 3 * loginErrorMessageTextMetrics.height; | 219 | font.pixelSize: completeProfileBody.textFieldFontSize |
| 220 | styleRenderType: Text.QtRendering | ||
| 221 | activeFocusOnPress: true | ||
| 222 | echoMode: passwordFieldMouseArea.showPassword ? TextInput.Normal : TextInput.Password | ||
| 223 | anchors { | ||
| 224 | top: emailField.bottom | ||
| 225 | topMargin: hifi.dimensions.contentSpacing.y | ||
| 226 | } | ||
| 227 | |||
| 228 | onFocusChanged: { | ||
| 229 | root.text = ""; | ||
| 230 | root.isPassword = focus; | ||
| 231 | } | ||
| 232 | |||
| 233 | Item { | ||
| 234 | id: showPasswordContainer | ||
| 235 | z: 10 | ||
| 236 | // width + image's rightMargin | ||
| 237 | width: showPasswordImage.width + 8 | ||
| 238 | height: parent.height | ||
| 239 | anchors { | ||
| 240 | right: parent.right | ||
| 241 | } | ||
| 242 | |||
| 243 | Image { | ||
| 244 | id: showPasswordImage | ||
| 245 | width: passwordField.height * passwordImageRatio | ||
| 246 | height: passwordField.height * passwordImageRatio | ||
| 247 | anchors { | ||
| 248 | right: parent.right | ||
| 249 | rightMargin: 8 | ||
| 250 | top: parent.top | ||
| 251 | topMargin: passwordFieldMouseArea.showPassword ? 6 : 8 | ||
| 252 | bottom: parent.bottom | ||
| 253 | bottomMargin: passwordFieldMouseArea.showPassword ? 5 : 8 | ||
| 254 | } | ||
| 255 | source: passwordFieldMouseArea.showPassword ? "../../images/eyeClosed.svg" : "../../images/eyeOpen.svg" | ||
| 256 | MouseArea { | ||
| 257 | id: passwordFieldMouseArea | ||
| 258 | anchors.fill: parent | ||
| 259 | acceptedButtons: Qt.LeftButton | ||
| 260 | property bool showPassword: false | ||
| 261 | onClicked: { | ||
| 262 | showPassword = !showPassword; | ||
| 263 | } | ||
| 264 | } | ||
| 265 | } | ||
| 266 | } | ||
| 267 | Keys.onPressed: { | ||
| 268 | switch (event.key) { | ||
| 269 | case Qt.Key_Tab: | ||
| 270 | event.accepted = true; | ||
| 271 | if (event.modifiers === Qt.ShiftModifier) { | ||
| 272 | emailField.focus = true; | ||
| 273 | } else if (usernameField.visible) { | ||
| 274 | usernameField.focus = true; | ||
| 275 | } else { | ||
| 276 | emailField.focus = true; | ||
| 277 | } | ||
| 278 | break; | ||
| 279 | case Qt.Key_Backtab: | ||
| 280 | event.accepted = true; | ||
| 281 | emailField.focus = true; | ||
| 282 | break; | ||
| 283 | case Qt.Key_Enter: | ||
| 284 | case Qt.Key_Return: | ||
| 285 | event.accepted = true; | ||
| 286 | loginDialog.createAccountFromOculus(emailField.text, usernameField.text, passwordField.text); | ||
| 287 | bodyLoader.setSource("LoggingInBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": completeProfileBody.withSteam, | ||
| 288 | "linkSteam": false, "withOculus": completeProfileBody.withOculus, "linkOculus": false, "createOculus": true }); | ||
| 289 | break; | ||
| 290 | } | ||
| 98 | } | 291 | } |
| 99 | } | 292 | } |
| 100 | } | 293 | } |
| @@ -105,7 +298,7 @@ Item { · 4 unmodified lines | |||
| 105 | height: d.minHeightButton | 298 | height: d.minHeightButton |
| 106 | anchors { | 299 | anchors { |
| 107 | top: parent.top | 300 | top: parent.top |
| 108 | topMargin: (parent.height - additionalTextContainer.height) / 2 - hifi.dimensions.contentSpacing.y | 301 | topMargin: (parent.height - additionalTextContainer.height + fields.height) / 2 - hifi.dimensions.contentSpacing.y |
| 109 | left: parent.left | 302 | left: parent.left |
| 110 | leftMargin: (parent.width - root.bannerWidth) / 2 | 303 | leftMargin: (parent.width - root.bannerWidth) / 2 |
| 111 | } | 304 | } |
| @@ -144,7 +337,7 @@ Item { · 32 unmodified lines | |||
| 144 | width: (parent.width - hifi.dimensions.contentSpacing.x) / 2 | 337 | width: (parent.width - hifi.dimensions.contentSpacing.x) / 2 |
| 145 | height: d.minHeightButton | 338 | height: d.minHeightButton |
| 146 | 339 | ||
| 147 | text: qsTr("Create your profile") | 340 | text: completeProfileBody.withOculus ? qsTr("Sign Up") : qsTr("Create your profile") |
| 148 | color: hifi.buttons.blue | 341 | color: hifi.buttons.blue |
| 149 | 342 | ||
| 150 | fontFamily: completeProfileBody.fontFamily | 343 | fontFamily: completeProfileBody.fontFamily |
| @@ -158,116 +351,149 @@ Item { · 7 unmodified lines | |||
| 158 | UserActivityLogger.logAction("encourageLoginDialog", data); | 351 | UserActivityLogger.logAction("encourageLoginDialog", data); |
| 159 | } | 352 | } |
| 160 | loginErrorMessage.visible = false; | 353 | loginErrorMessage.visible = false; |
| 161 | loginDialog.createAccountFromSteam(); | 354 | if (completeProfileBody.withOculus) { |
| 355 | loginDialog.createAccountFromOculus(emailField.text, usernameField.text, passwordField.text); | ||
| 356 | bodyLoader.setSource("LoggingInBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": completeProfileBody.withSteam, | ||
| 357 | "linkSteam": false, "withOculus": completeProfileBody.withOculus, "linkOculus": false, "createOculus": true }); | ||
| 358 | } else if (completeProfileBody.withSteam) { | ||
| 359 | loginDialog.createAccountFromSteam(); | ||
| 360 | } | ||
| 162 | } | 361 | } |
| 163 | } | 362 | } |
| 164 | } | 363 | } |
| 165 | 364 | ||
| 166 | Item { | 365 | Item { |
| 167 | id: additionalTextContainer | 366 | id: termsContainer |
| 168 | width: parent.width | 367 | width: parent.width |
| 169 | height: additionalTextMetrics.height | 368 | height: termsTextMetrics.height |
| 170 | anchors { | 369 | anchors { |
| 171 | top: buttons.bottom | 370 | top: buttons.bottom |
| 172 | horizontalCenter: parent.horizontalCenter | 371 | horizontalCenter: parent.horizontalCenter |
| 173 | topMargin: hifi.dimensions.contentSpacing.y | 372 | topMargin: hifi.dimensions.contentSpacing.y |
| 174 | left: parent.left | 373 | left: parent.left |
| 175 | } | 374 | } |
| 176 | |||
| 177 | TextMetrics { | 375 | TextMetrics { |
| 178 | id: additionalTextMetrics | 376 | id: termsTextMetrics |
| 179 | font: additionalText.font | 377 | font: termsText.font |
| 180 | text: "Already have a High Fidelity profile? Link to an existing profile here." | 378 | text: completeProfileBody.withOculus ? completeProfileBody.termsContainerOculusText : completeProfileBody.termsContainerText |
| 379 | Component.onCompleted: { | ||
| 380 | // with the link. | ||
| 381 | if (completeProfileBody.withOculus) { | ||
| 382 | termsText.text = qsTr("By signing up, you agree to <a href='https://highfidelity.com/terms'>High Fidelity's Terms of Service</a>") | ||
| 383 | } else { | ||
| 384 | termsText.text = qsTr("By creating this user profile, you agree to <a href='https://highfidelity.com/terms'>High Fidelity's Terms of Service</a>") | ||
| 385 | } | ||
| 386 | } | ||
| 181 | } | 387 | } |
| 182 | 388 | ||
| 183 | HifiStylesUit.ShortcutText { | 389 | HifiStylesUit.InfoItem { |
| 184 | id: additionalText | 390 | id: termsText |
| 185 | text: "<a href='https://fake.link'>Already have a High Fidelity profile? Link to an existing profile here.</a>" | 391 | text: completeProfileBody.withOculus ? completeProfileBody.termsContainerOculusText : completeProfileBody.termsContainerText |
| 186 | |||
| 187 | font.family: completeProfileBody.fontFamily | 392 | font.family: completeProfileBody.fontFamily |
| 188 | font.pixelSize: completeProfileBody.fontSize | 393 | font.pixelSize: completeProfileBody.fontSize |
| 189 | font.bold: completeProfileBody.fontBold | 394 | font.bold: completeProfileBody.fontBold |
| 190 | wrapMode: Text.NoWrap | 395 | wrapMode: Text.WordWrap |
| 396 | color: hifi.colors.white | ||
| 397 | linkColor: hifi.colors.blueAccent | ||
| 191 | lineHeight: 1 | 398 | lineHeight: 1 |
| 192 | lineHeightMode: Text.ProportionalHeight | 399 | lineHeightMode: Text.ProportionalHeight |
| 193 | horizontalAlignment: Text.AlignHCenter | ||
| 194 | linkColor: hifi.colors.blueAccent | ||
| 195 | 400 | ||
| 196 | onLinkActivated: { | 401 | onLinkActivated: loginDialog.openUrl(link); |
| 197 | loginDialog.isLogIn = true; | 402 | |
| 198 | bodyLoader.setSource("LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "errorString": "", "withSteam": true, "linkSteam": true }); | ||
| 199 | } | ||
| 200 | Component.onCompleted: { | 403 | Component.onCompleted: { |
| 201 | if (additionalTextMetrics.width > root.bannerWidth && root.isTablet) { | 404 | if (termsTextMetrics.width > root.bannerWidth) { |
| 202 | additionalText.width = root.bannerWidth; | 405 | termsText.width = root.bannerWidth; |
| 203 | additionalText.wrapMode = Text.WordWrap; | 406 | termsText.wrapMode = Text.WordWrap; |
| 204 | additionalText.verticalAlignment = Text.AlignLeft; | 407 | additionalText.verticalAlignment = Text.AlignLeft; |
| 205 | additionalText.horizontalAlignment = Text.AlignLeft; | 408 | additionalText.horizontalAlignment = Text.AlignLeft; |
| 206 | additionalTextContainer.height = (additionalTextMetrics.width / root.bannerWidth) * additionalTextMetrics.height; | 409 | termsContainer.height = (termsTextMetrics.width / root.bannerWidth) * termsTextMetrics.height; |
| 207 | additionalTextContainer.anchors.left = buttons.left; | 410 | termsContainer.anchors.left = buttons.left; |
| 208 | } else { | 411 | } else { |
| 209 | additionalText.anchors.centerIn = additionalTextContainer; | 412 | termsText.anchors.centerIn = termsContainer; |
| 210 | } | 413 | } |
| 211 | } | 414 | } |
| 212 | } | 415 | } |
| 213 | } | 416 | } |
| 214 | 417 | ||
| 215 | Item { | 418 | Item { |
| 216 | id: termsContainer | 419 | id: additionalTextContainer |
| 217 | width: parent.width | 420 | width: parent.width |
| 218 | height: termsTextMetrics.height | 421 | height: additionalTextMetrics.height |
| 219 | anchors { | 422 | anchors { |
| 220 | top: additionalTextContainer.bottom | 423 | top: termsContainer.bottom |
| 221 | horizontalCenter: parent.horizontalCenter | 424 | horizontalCenter: parent.horizontalCenter |
| 222 | topMargin: 2 * hifi.dimensions.contentSpacing.y | 425 | topMargin: 2 * hifi.dimensions.contentSpacing.y |
| 223 | left: parent.left | 426 | left: parent.left |
| 224 | } | 427 | } |
| 428 | |||
| 225 | TextMetrics { | 429 | TextMetrics { |
| 226 | id: termsTextMetrics | 430 | id: additionalTextMetrics |
| 227 | font: termsText.font | 431 | font: additionalText.font |
| 228 | text: completeProfileBody.termsContainerText | 432 | text: "Already have a High Fidelity profile? Link to an existing profile here." |
| 229 | Component.onCompleted: { | ||
| 230 | // with the link. | ||
| 231 | termsText.text = qsTr("By creating this user profile, you agree to <a href='https://highfidelity.com/terms'>High Fidelity's Terms of Service</a>") | ||
| 232 | } | ||
| 233 | } | 433 | } |
| 234 | 434 | ||
| 235 | HifiStylesUit.InfoItem { | 435 | HifiStylesUit.ShortcutText { |
| 236 | id: termsText | 436 | id: additionalText |
| 237 | text: completeProfileBody.termsContainerText | 437 | text: "<a href='https://fake.link'>Already have a High Fidelity profile? Link to an existing profile here.</a>" |
| 438 | width: root.bannerWidth; | ||
| 238 | font.family: completeProfileBody.fontFamily | 439 | font.family: completeProfileBody.fontFamily |
| 239 | font.pixelSize: completeProfileBody.fontSize | 440 | font.pixelSize: completeProfileBody.fontSize |
| 240 | font.bold: completeProfileBody.fontBold | 441 | font.bold: completeProfileBody.fontBold |
| 241 | wrapMode: Text.WordWrap | 442 | wrapMode: Text.NoWrap |
| 242 | color: hifi.colors.lightGray | ||
| 243 | linkColor: hifi.colors.blueAccent | ||
| 244 | lineHeight: 1 | 443 | lineHeight: 1 |
| 245 | lineHeightMode: Text.ProportionalHeight | 444 | lineHeightMode: Text.ProportionalHeight |
| 445 | horizontalAlignment: Text.AlignHCenter | ||
| 446 | linkColor: hifi.colors.blueAccent | ||
| 246 | 447 | ||
| 247 | onLinkActivated: loginDialog.openUrl(link); | 448 | onLinkActivated: { |
| 248 | 449 | bodyLoader.setSource("LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "errorString": "", | |
| 450 | "withSteam": completeProfileBody.withSteam, "linkSteam": completeProfileBody.withSteam, "withOculus": completeProfileBody.withOculus, | ||
| 451 | "linkOculus": completeProfileBody.withOculus }); | ||
| 452 | } | ||
| 249 | Component.onCompleted: { | 453 | Component.onCompleted: { |
| 250 | if (termsTextMetrics.width > root.bannerWidth && root.isTablet) { | 454 | if (additionalTextMetrics.width > root.bannerWidth) { |
| 251 | termsText.width = root.bannerWidth; | 455 | additionalText.wrapMode = Text.WordWrap; |
| 252 | termsText.wrapMode = Text.WordWrap; | ||
| 253 | additionalText.verticalAlignment = Text.AlignLeft; | 456 | additionalText.verticalAlignment = Text.AlignLeft; |
| 254 | additionalText.horizontalAlignment = Text.AlignLeft; | 457 | additionalText.horizontalAlignment = Text.AlignLeft; |
| 255 | termsContainer.height = (termsTextMetrics.width / root.bannerWidth) * termsTextMetrics.height; | 458 | additionalTextContainer.height = (additionalTextMetrics.width / root.bannerWidth) * additionalTextMetrics.height; |
| 256 | termsContainer.anchors.left = buttons.left; | 459 | additionalTextContainer.anchors.left = buttons.left; |
| 257 | } else { | 460 | } else { |
| 258 | termsText.anchors.centerIn = termsContainer; | 461 | additionalText.anchors.centerIn = additionalTextContainer; |
| 259 | } | 462 | } |
| 260 | } | 463 | } |
| 261 | } | 464 | } |
| 262 | } | 465 | } |
| 263 | } | 466 | } |
| 467 | function recalculateErrorMessage() { | ||
| 468 | if (completeProfileBody.errorString !== "") { | ||
| 469 | loginErrorMessage.visible = true; | ||
| 470 | var errorLength = completeProfileBody.errorString.split(/\r\n|\r|\n/).length; | ||
| 471 | var errorStringEdited = completeProfileBody.errorString.replace(/[\n\r]+/g, "\n"); | ||
| 472 | loginErrorMessage.text = errorStringEdited; | ||
| 473 | if (errorLength > 1.0) { | ||
| 474 | loginErrorMessage.wrapMode = Text.WordWrap; | ||
| 475 | loginErrorMessage.verticalAlignment = Text.AlignLeft; | ||
| 476 | loginErrorMessage.horizontalAlignment = Text.AlignLeft; | ||
| 477 | errorContainer.height = errorLength * loginErrorMessageTextMetrics.height; | ||
| 478 | } else if (loginErrorMessageTextMetrics.width > root.bannerWidth) { | ||
| 479 | loginErrorMessage.wrapMode = Text.WordWrap; | ||
| 480 | loginErrorMessage.verticalAlignment = Text.AlignLeft; | ||
| 481 | loginErrorMessage.horizontalAlignment = Text.AlignLeft; | ||
| 482 | errorContainer.height = (loginErrorMessageTextMetrics.width / root.bannerWidth) * loginErrorMessageTextMetrics.height; | ||
| 483 | } else { | ||
| 484 | loginErrorMessage.wrapMode = Text.NoWrap; | ||
| 485 | loginErrorMessage.verticalAlignment = Text.AlignVCenter; | ||
| 486 | loginErrorMessage.horizontalAlignment = Text.AlignHCenter; | ||
| 487 | errorContainer.height = loginErrorMessageTextMetrics.height; | ||
| 488 | } | ||
| 489 | } | ||
| 490 | } | ||
| 264 | } | 491 | } |
| 265 | 492 | ||
| 266 | Connections { | 493 | Connections { |
| 267 | target: loginDialog | 494 | target: loginDialog |
| 268 | onHandleCreateCompleted: { | 495 | onHandleCreateCompleted: { |
| 269 | console.log("Create Succeeded") | 496 | console.log("Create Succeeded"); |
| 270 | |||
| 271 | if (completeProfileBody.withSteam) { | 497 | if (completeProfileBody.withSteam) { |
| 272 | if (completeProfileBody.loginDialogPoppedUp) { | 498 | if (completeProfileBody.loginDialogPoppedUp) { |
| 273 | var data = { | 499 | var data = { |
| @@ -277,20 +503,24 @@ Item { · 3 unmodified lines | |||
| 277 | } | 503 | } |
| 278 | loginDialog.loginThroughSteam(); | 504 | loginDialog.loginThroughSteam(); |
| 279 | } | 505 | } |
| 280 | bodyLoader.setSource("LoggingInBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": completeProfileBody.withSteam, "linkSteam": false }); | 506 | bodyLoader.setSource("LoggingInBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": completeProfileBody.withSteam, "linkSteam": false, |
| 507 | "withOculus": completeProfileBody.withOculus, "linkOculus": false }); | ||
| 281 | } | 508 | } |
| 282 | onHandleCreateFailed: { | 509 | onHandleCreateFailed: { |
| 283 | console.log("Create Failed: " + error); | 510 | console.log("Create Failed: " + error); |
| 284 | if (completeProfileBody.withSteam) { | 511 | if (completeProfileBody.withSteam || completeProfileBody.withOculus) { |
| 285 | if (completeProfileBody.loginDialogPoppedUp) { | 512 | if (completeProfileBody.loginDialogPoppedUp) { |
| 513 | action = completeProfileBody.withSteam ? "Steam" : "Oculus"; | ||
| 286 | var data = { | 514 | var data = { |
| 287 | "action": "user failed to create a profile with Steam from the complete profile screen" | 515 | "action": "user failed to create a profile with " + action + " from the complete profile screen" |
| 288 | } | 516 | } |
| 289 | UserActivityLogger.logAction("encourageLoginDialog", data); | 517 | UserActivityLogger.logAction("encourageLoginDialog", data); |
| 290 | } | 518 | } |
| 291 | } | 519 | } |
| 292 | 520 | if (!completeProfileBody.withOculus) { | |
| 293 | bodyLoader.setSource("UsernameCollisionBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": completeProfileBody.withSteam }); | 521 | bodyLoader.setSource("UsernameCollisionBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": completeProfileBody.withSteam, |
| 522 | "withOculus": completeProfileBody.withOculus }); | ||
| 523 | } | ||
| 294 | } | 524 | } |
| 295 | } | 525 | } |
| 296 | 526 | ||
| @@ -302,5 +532,6 @@ Item { · 5 unmodified lines | |||
| 302 | } | 532 | } |
| 303 | d.resize(); | 533 | d.resize(); |
| 304 | root.text = ""; | 534 | root.text = ""; |
| 535 | usernameField.forceActiveFocus(); | ||
| 305 | } | 536 | } |
| 306 | } | 537 | } |
| @@ -36,9 +36,10 @@ Item { · 35 unmodified lines | |||
| 36 | property bool keyboardRaised: false | 36 | property bool keyboardRaised: false |
| 37 | property bool punctuationMode: false | 37 | property bool punctuationMode: false |
| 38 | 38 | ||
| 39 | property bool withSteam: false | 39 | property bool withSteam: withSteam |
| 40 | property bool linkSteam: linkSteam | 40 | property bool linkSteam: linkSteam |
| 41 | property bool withOculus: false | 41 | property bool withOculus: withOculus |
| 42 | property bool linkOculus: linkOculus | ||
| 42 | property string errorString: errorString | 43 | property string errorString: errorString |
| 43 | property bool lostFocus: false | 44 | property bool lostFocus: false |
| 44 | 45 | ||
| @@ -83,23 +84,24 @@ Item { · 38 unmodified lines | |||
| 83 | } | 84 | } |
| 84 | UserActivityLogger.logAction("encourageLoginDialog", data); | 85 | UserActivityLogger.logAction("encourageLoginDialog", data); |
| 85 | } | 86 | } |
| 86 | 87 | bodyLoader.setSource("LoggingInBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": linkAccountBody.withSteam, | |
| 87 | bodyLoader.setSource("LoggingInBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": linkAccountBody.withSteam, "withOculus": linkAccountBody.withOculus, "linkSteam": linkAccountBody.linkSteam }); | 88 | "withOculus": linkAccountBody.withOculus, "linkSteam": linkAccountBody.linkSteam, "linkOculus": linkAccountBody.linkOculus }); |
| 88 | } | 89 | } |
| 89 | 90 | ||
| 90 | function init() { | 91 | function init() { |
| 91 | // going to/from sign in/up dialog. | 92 | // going to/from sign in/up dialog. |
| 92 | loginDialog.isLogIn = true; | ||
| 93 | loginErrorMessage.text = linkAccountBody.errorString; | 93 | loginErrorMessage.text = linkAccountBody.errorString; |
| 94 | loginErrorMessage.visible = (linkAccountBody.errorString !== ""); | 94 | loginErrorMessage.visible = (linkAccountBody.errorString !== ""); |
| 95 | loginButton.text = !linkAccountBody.linkSteam ? "Log In" : "Link Account"; | 95 | if (loginErrorMessageTextMetrics.width > emailField.width) { |
| 96 | loginErrorMessage.wrapMode = Text.WordWrap; | ||
| 97 | errorContainer.height = (loginErrorMessageTextMetrics.width / emailField.width) * loginErrorMessageTextMetrics.height; | ||
| 98 | } | ||
| 99 | loginButton.text = (!linkAccountBody.linkSteam && !linkAccountBody.linkOculus) ? "Log In" : "Link Account"; | ||
| 96 | loginButton.color = hifi.buttons.blue; | 100 | loginButton.color = hifi.buttons.blue; |
| 97 | emailField.placeholderText = "Username or Email"; | 101 | emailField.placeholderText = "Username or Email"; |
| 98 | var savedUsername = Settings.getValue("keepMeLoggedIn/savedUsername", ""); | 102 | var savedUsername = Settings.getValue("keepMeLoggedIn/savedUsername", ""); |
| 99 | emailField.text = keepMeLoggedInCheckbox.checked ? savedUsername === "Unknown user" ? "" : savedUsername : ""; | 103 | emailField.text = keepMeLoggedInCheckbox.checked ? savedUsername === "Unknown user" ? "" : savedUsername : ""; |
| 100 | if (linkAccountBody.linkSteam) { | 104 | if (linkAccountBody.linkSteam || linkAccountBody.linkOculus) { |
| 101 | steamInfoText.anchors.top = passwordField.bottom; | ||
| 102 | keepMeLoggedInCheckbox.anchors.top = steamInfoText.bottom; | ||
| 103 | loginButton.width = (passwordField.width - hifi.dimensions.contentSpacing.x) / 2; | 105 | loginButton.width = (passwordField.width - hifi.dimensions.contentSpacing.x) / 2; |
| 104 | loginButton.anchors.right = emailField.right; | 106 | loginButton.anchors.right = emailField.right; |
| 105 | } else { | 107 | } else { |
| @@ -125,7 +127,7 @@ Item { · 19 unmodified lines | |||
| 125 | id: loginContainer | 127 | id: loginContainer |
| 126 | width: emailField.width | 128 | width: emailField.width |
| 127 | height: errorContainer.height + emailField.height + passwordField.height + 5.5 * hifi.dimensions.contentSpacing.y + | 129 | height: errorContainer.height + emailField.height + passwordField.height + 5.5 * hifi.dimensions.contentSpacing.y + |
| 128 | keepMeLoggedInCheckbox.height + loginButton.height + cantAccessTextMetrics.height + continueButton.height + steamInfoTextMetrics.height | 130 | keepMeLoggedInCheckbox.height + loginButton.height + cantAccessTextMetrics.height + continueButton.height |
| 129 | anchors { | 131 | anchors { |
| 130 | top: parent.top | 132 | top: parent.top |
| 131 | topMargin: root.bannerHeight + 0.25 * parent.height | 133 | topMargin: root.bannerHeight + 0.25 * parent.height |
| @@ -135,7 +137,7 @@ Item { · 3 unmodified lines | |||
| 135 | 137 | ||
| 136 | Item { | 138 | Item { |
| 137 | id: errorContainer | 139 | id: errorContainer |
| 138 | width: loginErrorMessageTextMetrics.width | 140 | width: parent.width |
| 139 | height: loginErrorMessageTextMetrics.height | 141 | height: loginErrorMessageTextMetrics.height |
| 140 | anchors { | 142 | anchors { |
| 141 | bottom: emailField.top; | 143 | bottom: emailField.top; |
| @@ -304,7 +306,7 @@ Item { · 162 unmodified lines | |||
| 304 | fontSize: linkAccountBody.fontSize | 306 | fontSize: linkAccountBody.fontSize |
| 305 | fontBold: linkAccountBody.fontBold | 307 | fontBold: linkAccountBody.fontBold |
| 306 | color: hifi.buttons.noneBorderlessWhite; | 308 | color: hifi.buttons.noneBorderlessWhite; |
| 307 | visible: linkAccountBody.linkSteam | 309 | visible: linkAccountBody.linkSteam || linkAccountBody.linkOculus |
| 308 | anchors { | 310 | anchors { |
| 309 | top: keepMeLoggedInCheckbox.bottom | 311 | top: keepMeLoggedInCheckbox.bottom |
| 310 | topMargin: hifi.dimensions.contentSpacing.y | 312 | topMargin: hifi.dimensions.contentSpacing.y |
| @@ -315,10 +317,9 @@ Item { · 4 unmodified lines | |||
| 315 | "action": "user clicked cancel at link account screen" | 317 | "action": "user clicked cancel at link account screen" |
| 316 | }; | 318 | }; |
| 317 | UserActivityLogger.logAction("encourageLoginDialog", data); | 319 | UserActivityLogger.logAction("encourageLoginDialog", data); |
| 318 | loginDialog.dismissLoginDialog(); | ||
| 319 | } | 320 | } |
| 320 | 321 | bodyLoader.setSource("CompleteProfileBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": linkAccountBody.withSteam, | |
| 321 | bodyLoader.setSource("CompleteProfileBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": linkAccountBody.withSteam, "errorString": "" }); | 322 | "withOculus": linkAccountBody.withOculus, "errorString": "" }); |
| 322 | } | 323 | } |
| 323 | } | 324 | } |
| 324 | HifiControlsUit.Button { | 325 | HifiControlsUit.Button { |
| @@ -337,33 +338,6 @@ Item { · 12 unmodified lines | |||
| 337 | linkAccountBody.login(); | 338 | linkAccountBody.login(); |
| 338 | } | 339 | } |
| 339 | } | 340 | } |
| 340 | TextMetrics { | ||
| 341 | id: steamInfoTextMetrics | ||
| 342 | font: steamInfoText.font | ||
| 343 | text: steamInfoText.text | ||
| 344 | } | ||
| 345 | Text { | ||
| 346 | id: steamInfoText | ||
| 347 | width: root.bannerWidth | ||
| 348 | visible: linkAccountBody.linkSteam | ||
| 349 | anchors { | ||
| 350 | top: loginButton.bottom | ||
| 351 | topMargin: hifi.dimensions.contentSpacing.y | ||
| 352 | left: emailField.left | ||
| 353 | } | ||
| 354 | |||
| 355 | font.family: linkAccountBody.fontFamily | ||
| 356 | font.pixelSize: linkAccountBody.textFieldFontSize | ||
| 357 | color: "white" | ||
| 358 | text: qsTr("Your Steam account information will not be exposed to others."); | ||
| 359 | verticalAlignment: Text.AlignVCenter | ||
| 360 | horizontalAlignment: Text.AlignHCenter | ||
| 361 | Component.onCompleted: { | ||
| 362 | if (steamInfoTextMetrics.width > root.bannerWidth) { | ||
| 363 | steamInfoText.wrapMode = Text.WordWrap; | ||
| 364 | } | ||
| 365 | } | ||
| 366 | } | ||
| 367 | TextMetrics { | 341 | TextMetrics { |
| 368 | id: cantAccessTextMetrics | 342 | id: cantAccessTextMetrics |
| 369 | font: cantAccessText.font | 343 | font: cantAccessText.font |
| @@ -372,7 +346,7 @@ Item { · 2 unmodified lines | |||
| 372 | HifiStylesUit.ShortcutText { | 346 | HifiStylesUit.ShortcutText { |
| 373 | id: cantAccessText | 347 | id: cantAccessText |
| 374 | z: 10 | 348 | z: 10 |
| 375 | visible: !linkAccountBody.linkSteam | 349 | visible: !linkAccountBody.linkSteam && !linkAccountBody.linkOculus |
| 376 | anchors { | 350 | anchors { |
| 377 | top: loginButton.bottom | 351 | top: loginButton.bottom |
| 378 | topMargin: hifi.dimensions.contentSpacing.y | 352 | topMargin: hifi.dimensions.contentSpacing.y |
| @@ -423,10 +397,10 @@ Item { · 44 unmodified lines | |||
| 423 | buttonGlyphSize: 24 | 397 | buttonGlyphSize: 24 |
| 424 | buttonGlyphRightMargin: 10 | 398 | buttonGlyphRightMargin: 10 |
| 425 | onClicked: { | 399 | onClicked: { |
| 426 | // if (loginDialog.isOculusStoreRunning()) { | 400 | if (loginDialog.isOculusRunning()) { |
| 427 | // linkAccountBody.withOculus = true; | 401 | linkAccountBody.withOculus = true; |
| 428 | // loginDialog.loginThroughSteam(); | 402 | loginDialog.loginThroughOculus(); |
| 429 | // } else | 403 | } else |
| 430 | if (loginDialog.isSteamRunning()) { | 404 | if (loginDialog.isSteamRunning()) { |
| 431 | linkAccountBody.withSteam = true; | 405 | linkAccountBody.withSteam = true; |
| 432 | loginDialog.loginThroughSteam(); | 406 | loginDialog.loginThroughSteam(); |
| @@ -446,18 +420,17 @@ Item { · 13 unmodified lines | |||
| 446 | } | 420 | } |
| 447 | 421 | ||
| 448 | bodyLoader.setSource("LoggingInBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, | 422 | bodyLoader.setSource("LoggingInBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, |
| 449 | "withSteam": linkAccountBody.withSteam, "withOculus": linkAccountBody.withOculus, "linkSteam": linkAccountBody.linkSteam }); | 423 | "withSteam": linkAccountBody.withSteam, "withOculus": linkAccountBody.withOculus, "linkSteam": linkAccountBody.linkSteam, "linkOculus": linkAccountBody.linkOculus }); |
| 450 | } | 424 | } |
| 451 | Component.onCompleted: { | 425 | Component.onCompleted: { |
| 452 | if (linkAccountBody.linkSteam) { | 426 | if (linkAccountBody.linkSteam || linkAccountBody.linkOculus) { |
| 453 | continueButton.visible = false; | 427 | continueButton.visible = false; |
| 454 | return; | 428 | return; |
| 455 | } | 429 | } |
| 456 | // if (loginDialog.isOculusStoreRunning()) { | 430 | if (loginDialog.isOculusRunning()) { |
| 457 | // continueButton.text = qsTr("CONTINUE WITH OCULUS"); | 431 | continueButton.text = qsTr("CONTINUE WITH OCULUS"); |
| 458 | // continueButton.buttonGlyph = hifi.glyphs.oculus; | 432 | continueButton.buttonGlyph = hifi.glyphs.oculus; |
| 459 | // } else | 433 | } else if (loginDialog.isSteamRunning()) { |
| 460 | if (loginDialog.isSteamRunning()) { | ||
| 461 | continueButton.text = qsTr("CONTINUE WITH STEAM"); | 434 | continueButton.text = qsTr("CONTINUE WITH STEAM"); |
| 462 | continueButton.buttonGlyph = hifi.glyphs.steamSquare; | 435 | continueButton.buttonGlyph = hifi.glyphs.steamSquare; |
| 463 | } else { | 436 | } else { |
| @@ -470,7 +443,7 @@ Item { · 6 unmodified lines | |||
| 470 | id: signUpContainer | 443 | id: signUpContainer |
| 471 | width: loginContainer.width | 444 | width: loginContainer.width |
| 472 | height: signUpTextMetrics.height | 445 | height: signUpTextMetrics.height |
| 473 | visible: !linkAccountBody.linkSteam | 446 | visible: !linkAccountBody.linkSteam && !linkAccountBody.linkOculus |
| 474 | anchors { | 447 | anchors { |
| 475 | left: loginContainer.left | 448 | left: loginContainer.left |
| 476 | top: loginContainer.bottom | 449 | top: loginContainer.bottom |
| @@ -519,7 +492,7 @@ Item { · 42 unmodified lines | |||
| 519 | UserActivityLogger.logAction("encourageLoginDialog", data); | 492 | UserActivityLogger.logAction("encourageLoginDialog", data); |
| 520 | } | 493 | } |
| 521 | bodyLoader.setSource("SignUpBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, | 494 | bodyLoader.setSource("SignUpBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, |
| 522 | "errorString": "", "linkSteam": linkAccountBody.linkSteam }); | 495 | "errorString": "" }); |
| 523 | } | 496 | } |
| 524 | } | 497 | } |
| 525 | } | 498 | } |
| @@ -543,7 +516,7 @@ Item { · 17 unmodified lines | |||
| 543 | fontFamily: linkAccountBody.fontFamily | 516 | fontFamily: linkAccountBody.fontFamily |
| 544 | fontSize: linkAccountBody.fontSize | 517 | fontSize: linkAccountBody.fontSize |
| 545 | fontBold: linkAccountBody.fontBold | 518 | fontBold: linkAccountBody.fontBold |
| 546 | visible: linkAccountBody.loginDialogPoppedUp && !linkAccountBody.linkSteam; | 519 | visible: loginDialog.getLoginDialogPoppedUp() && !linkAccountBody.linkSteam && !linkAccountBody.linkOculus; |
| 547 | onClicked: { | 520 | onClicked: { |
| 548 | if (linkAccountBody.loginDialogPoppedUp) { | 521 | if (linkAccountBody.loginDialogPoppedUp) { |
| 549 | var data = { | 522 | var data = { |
| @@ -29,6 +29,8 @@ Item { · 28 unmodified lines | |||
| 29 | property bool withSteam: withSteam | 29 | property bool withSteam: withSteam |
| 30 | property bool withOculus: withOculus | 30 | property bool withOculus: withOculus |
| 31 | property bool linkSteam: linkSteam | 31 | property bool linkSteam: linkSteam |
| 32 | property bool linkOculus: linkOculus | ||
| 33 | property bool createOculus: createOculus | ||
| 32 | 34 | ||
| 33 | readonly property bool loginDialogPoppedUp: loginDialog.getLoginDialogPoppedUp() | 35 | readonly property bool loginDialogPoppedUp: loginDialog.getLoginDialogPoppedUp() |
| 34 | 36 | ||
| @@ -75,15 +77,25 @@ Item { · 40 unmodified lines | |||
| 75 | } | 77 | } |
| 76 | } | 78 | } |
| 77 | 79 | ||
| 80 | Timer { | ||
| 81 | id: oculusSuccessTimer | ||
| 82 | interval: 500; | ||
| 83 | running: false; | ||
| 84 | repeat: false; | ||
| 85 | onTriggered: { | ||
| 86 | loginDialog.loginThroughOculus(); | ||
| 87 | init(); | ||
| 88 | } | ||
| 89 | } | ||
| 90 | |||
| 78 | function init() { | 91 | function init() { |
| 79 | // For the process of logging in. | 92 | // For the process of logging in. |
| 80 | loggingInText.wrapMode = Text.NoWrap; | 93 | loggingInText.wrapMode = Text.NoWrap; |
| 81 | 94 | if (loggingInBody.createOculus) { | |
| 82 | if (loggingInBody.linkSteam) { | 95 | loggingInGlyph.text = hifi.glyphs.oculus; |
| 83 | loggingInGlyph.visible = true; | 96 | loggingInGlyph.visible = true; |
| 84 | loggingInText.text = "Linking to Steam"; | 97 | loggingInText.text = "Creating account with Oculus"; |
| 85 | loggingInText.x = loggingInHeader.width/2 - loggingInTextMetrics.width/2 + loggingInGlyphTextMetrics.width/2; | 98 | loggingInText.x = loggingInHeader.width/2 - loggingInTextMetrics.width/2 + loggingInGlyphTextMetrics.width/2; |
| 86 | loginDialog.linkSteam(); | ||
| 87 | } else if (loggingInBody.withSteam) { | 99 | } else if (loggingInBody.withSteam) { |
| 88 | loggingInGlyph.visible = true; | 100 | loggingInGlyph.visible = true; |
| 89 | loggingInText.text = "Logging in to Steam"; | 101 | loggingInText.text = "Logging in to Steam"; |
| @@ -100,12 +112,18 @@ Item { · 10 unmodified lines | |||
| 100 | loggingInSpinner.visible = true; | 112 | loggingInSpinner.visible = true; |
| 101 | } | 113 | } |
| 102 | function loadingSuccess() { | 114 | function loadingSuccess() { |
| 103 | loggingInSpinner.visible = false; | ||
| 104 | if (loggingInBody.linkSteam) { | 115 | if (loggingInBody.linkSteam) { |
| 105 | loggingInText.text = "Linking to Steam"; | 116 | loggingInText.text = "Linking to Steam"; |
| 117 | loggingInText.x = loggingInHeader.width/2 - loggingInTextMetrics.width/2 + loggingInGlyphTextMetrics.width/2; | ||
| 106 | loginDialog.linkSteam(); | 118 | loginDialog.linkSteam(); |
| 107 | return; | 119 | return; |
| 120 | } else if (loggingInBody.linkOculus) { | ||
| 121 | loggingInText.text = "Linking to Oculus"; | ||
| 122 | loggingInText.x = loggingInHeader.width/2 - loggingInTextMetrics.width/2 + loggingInGlyphTextMetrics.width/2; | ||
| 123 | loginDialog.linkOculus(); | ||
| 124 | return; | ||
| 108 | } | 125 | } |
| 126 | loggingInSpinner.visible = false; | ||
| 109 | if (loggingInBody.withSteam) { | 127 | if (loggingInBody.withSteam) { |
| 110 | // reset the flag. | 128 | // reset the flag. |
| 111 | loggingInGlyph.visible = false; | 129 | loggingInGlyph.visible = false; |
| @@ -246,6 +264,26 @@ Item { · 134 unmodified lines | |||
| 246 | verticalAlignment: Text.AlignVCenter; | 264 | verticalAlignment: Text.AlignVCenter; |
| 247 | visible: false; | 265 | visible: false; |
| 248 | } | 266 | } |
| 267 | HifiControlsUit.Button { | ||
| 268 | id: okButton; | ||
| 269 | width: d.minWidthButton | ||
| 270 | height: d.minHeightButton | ||
| 271 | text: qsTr("OK") | ||
| 272 | color: hifi.buttons.white | ||
| 273 | anchors { | ||
| 274 | top: loggedInGlyph.bottom | ||
| 275 | topMargin: 3 * hifi.dimensions.contentSpacing.y | ||
| 276 | left: parent.left | ||
| 277 | leftMargin: (parent.width - width) / 2; | ||
| 278 | } | ||
| 279 | onClicked: { | ||
| 280 | root.tryDestroy(); | ||
| 281 | if (loginDialog.getLoginDialogPoppedUp()) { | ||
| 282 | loginDialog.dismissLoginDialog(); | ||
| 283 | } | ||
| 284 | } | ||
| 285 | visible: false | ||
| 286 | } | ||
| 249 | } | 287 | } |
| 250 | } | 288 | } |
| 251 | } | 289 | } |
| @@ -257,6 +295,34 @@ Item { · 5 unmodified lines | |||
| 257 | 295 | ||
| 258 | Connections { | 296 | Connections { |
| 259 | target: loginDialog | 297 | target: loginDialog |
| 298 | onHandleCreateCompleted: { | ||
| 299 | console.log("Create Succeeded") | ||
| 300 | if (loggingInBody.withOculus) { | ||
| 301 | if (loggingInBody.loginDialogPoppedUp) { | ||
| 302 | var data = { | ||
| 303 | "action": "user created Oculus account successfully" | ||
| 304 | }; | ||
| 305 | UserActivityLogger.logAction("encourageLoginDialog", data); | ||
| 306 | } | ||
| 307 | loggingInBody.createOculus = false; | ||
| 308 | loggingInText.text = "Account created!"; | ||
| 309 | loggingInText.x = loggingInHeader.width/2 - loggingInTextMetrics.width/2 + loggingInGlyphTextMetrics.width/2; | ||
| 310 | oculusSuccessTimer.start(); | ||
| 311 | } | ||
| 312 | } | ||
| 313 | onHandleCreateFailed: { | ||
| 314 | console.log("Create Failed: " + error); | ||
| 315 | if (loggingInBody.withOculus) { | ||
| 316 | if (loggingInBody.loginDialogPoppedUp) { | ||
| 317 | var data = { | ||
| 318 | "action": "user created Oculus account unsuccessfully" | ||
| 319 | }; | ||
| 320 | UserActivityLogger.logAction("encourageLoginDialog", data); | ||
| 321 | } | ||
| 322 | bodyLoader.setSource("CompleteProfileBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": loggingInBody.withSteam, | ||
| 323 | "withOculus": loggingInBody.withOculus, "errorString": error }); | ||
| 324 | } | ||
| 325 | } | ||
| 260 | onHandleLinkCompleted: { | 326 | onHandleLinkCompleted: { |
| 261 | console.log("Link Succeeded"); | 327 | console.log("Link Succeeded"); |
| 262 | if (loggingInBody.linkSteam) { | 328 | if (loggingInBody.linkSteam) { |
| @@ -267,21 +333,40 @@ Item { · 4 unmodified lines | |||
| 267 | }; | 333 | }; |
| 268 | UserActivityLogger.logAction("encourageLoginDialog", data); | 334 | UserActivityLogger.logAction("encourageLoginDialog", data); |
| 269 | } | 335 | } |
| 270 | 336 | } else if (loggingInBody.linkOculus) { | |
| 271 | loggingInBody.loadingSuccess(); | 337 | loggingInBody.linkOculus = false; |
| 338 | if (loggingInBody.loginDialogPoppedUp) { | ||
| 339 | var data = { | ||
| 340 | "action": "user linked Oculus with their hifi account credentials successfully" | ||
| 341 | }; | ||
| 342 | UserActivityLogger.logAction("encourageLoginDialog", data); | ||
| 343 | } | ||
| 272 | } | 344 | } |
| 345 | loggingInBody.loadingSuccess(); | ||
| 273 | } | 346 | } |
| 274 | onHandleLinkFailed: { | 347 | onHandleLinkFailed: { |
| 275 | console.log("Link Failed: " + error); | 348 | console.log("Link Failed: " + error); |
| 276 | if (loggingInBody.linkSteam) { | 349 | loggingInSpinner.visible = false; |
| 350 | if (loggingInBody.linkOculus) { | ||
| 351 | loggingInText.text = "Oculus failed to link"; | ||
| 352 | if (loggingInBody.loginDialogPoppedUp) { | ||
| 353 | var data = { | ||
| 354 | "action": "user linked Oculus unsuccessfully" | ||
| 355 | }; | ||
| 356 | UserActivityLogger.logAction("encourageLoginDialog", data); | ||
| 357 | } | ||
| 358 | okButton.visible = true; | ||
| 359 | } else if (loggingInBody.linkSteam){ | ||
| 277 | if (loggingInBody.loginDialogPoppedUp) { | 360 | if (loggingInBody.loginDialogPoppedUp) { |
| 278 | var data = { | 361 | var data = { |
| 279 | "action": "user linked Steam unsuccessfully" | 362 | "action": "user linked Steam unsuccessfully" |
| 280 | }; | 363 | }; |
| 281 | UserActivityLogger.logAction("encourageLoginDialog", data); | 364 | UserActivityLogger.logAction("encourageLoginDialog", data); |
| 282 | } | 365 | } |
| 366 | } else { | ||
| 367 | bodyLoader.setSource("LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "linkSteam": loggingInBody.linkSteam, | ||
| 368 | "linkOculus": loggingInBody.linkOculus, "errorString": error }); | ||
| 283 | } | 369 | } |
| 284 | bodyLoader.setSource("LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "linkSteam": true, "errorString": error }); | ||
| 285 | } | 370 | } |
| 286 | 371 | ||
| 287 | onHandleLoginCompleted: { | 372 | onHandleLoginCompleted: { |
| @@ -292,8 +377,19 @@ Item { · 4 unmodified lines | |||
| 292 | onHandleLoginFailed: { | 377 | onHandleLoginFailed: { |
| 293 | console.log("Login Failed") | 378 | console.log("Login Failed") |
| 294 | loggingInSpinner.visible = false; | 379 | loggingInSpinner.visible = false; |
| 380 | loggingInGlyph.visible = false; | ||
| 295 | var errorString = ""; | 381 | var errorString = ""; |
| 296 | if (loggingInBody.linkSteam && loggingInBody.withSteam) { | 382 | if (loggingInBody.linkOculus && loggingInBody.withOculus) { |
| 383 | errorString = "Username or password is incorrect."; | ||
| 384 | if (loggingInBody.loginDialogPoppedUp) { | ||
| 385 | var data = { | ||
| 386 | "action": "user failed to link Oculus with their hifi account credentials" | ||
| 387 | }; | ||
| 388 | UserActivityLogger.logAction("encourageLoginDialog", data); | ||
| 389 | } | ||
| 390 | bodyLoader.setSource("LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": loggingInBody.withSteam, | ||
| 391 | "withOculus": loggingInBody.withOculus, "linkSteam": loggingInBody.linkSteam, "linkOculus": loggingInBody.linkOculus, "errorString": errorString }); | ||
| 392 | } else if (loggingInBody.linkSteam && loggingInBody.withSteam) { | ||
| 297 | errorString = "Username or password is incorrect."; | 393 | errorString = "Username or password is incorrect."; |
| 298 | if (loggingInBody.loginDialogPoppedUp) { | 394 | if (loggingInBody.loginDialogPoppedUp) { |
| 299 | var data = { | 395 | var data = { |
| @@ -301,9 +397,9 @@ Item { · 1 unmodified line | |||
| 301 | }; | 397 | }; |
| 302 | UserActivityLogger.logAction("encourageLoginDialog", data); | 398 | UserActivityLogger.logAction("encourageLoginDialog", data); |
| 303 | } | 399 | } |
| 304 | bodyLoader.setSource("LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": loggingInBody.withSteam, "linkSteam": loggingInBody.linkSteam, "errorString": errorString }); | 400 | bodyLoader.setSource("LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": loggingInBody.withSteam, |
| 401 | "withOculus": loggingInBody.withOculus, "linkSteam": loggingInBody.linkSteam, "linkOculus": loggingInBody.linkOculus, "errorString": errorString }); | ||
| 305 | } else if (loggingInBody.withSteam) { | 402 | } else if (loggingInBody.withSteam) { |
| 306 | loggingInGlyph.visible = false; | ||
| 307 | errorString = "Your Steam authentication has failed. Please make sure you are logged into Steam and try again."; | 403 | errorString = "Your Steam authentication has failed. Please make sure you are logged into Steam and try again."; |
| 308 | if (loggingInBody.loginDialogPoppedUp) { | 404 | if (loggingInBody.loginDialogPoppedUp) { |
| 309 | var data = { | 405 | var data = { |
| @@ -311,19 +407,19 @@ Item { · 1 unmodified line | |||
| 311 | }; | 407 | }; |
| 312 | UserActivityLogger.logAction("encourageLoginDialog", data); | 408 | UserActivityLogger.logAction("encourageLoginDialog", data); |
| 313 | } | 409 | } |
| 314 | bodyLoader.setSource("CompleteProfileBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": loggingInBody.withSteam, "errorString": errorString }); | 410 | bodyLoader.setSource("CompleteProfileBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": loggingInBody.withSteam, |
| 411 | "withOculus": loggingInBody.withOculus, "linkSteam": loggingInBody.linkSteam, "linkOculus": loggingInBody.linkOculus, "errorString": errorString }); | ||
| 315 | } else if (loggingInBody.withOculus) { | 412 | } else if (loggingInBody.withOculus) { |
| 316 | loggingInGlyph.visible = false; | 413 | errorString = "Your Oculus account is not connected to an existing High Fidelity account. Please create a new one." |
| 317 | errorString = "Your Oculus authentication has failed. Please make sure you are logged into Oculus and try again." | ||
| 318 | if (loggingInBody.loginDialogPoppedUp) { | 414 | if (loggingInBody.loginDialogPoppedUp) { |
| 319 | var data = { | 415 | var data = { |
| 320 | "action": "user failed to authenticate with Oculus to log in" | 416 | "action": "user failed to authenticate with Oculus to log in" |
| 321 | }; | 417 | }; |
| 322 | UserActivityLogger.logAction("encourageLoginDialog", data); | 418 | UserActivityLogger.logAction("encourageLoginDialog", data); |
| 323 | } | 419 | } |
| 324 | bodyLoader.setSource("LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "errorString": errorString }); | 420 | bodyLoader.setSource("CompleteProfileBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": loggingInBody.withSteam, |
| 325 | } | 421 | "withOculus": loggingInBody.withOculus, "linkSteam": loggingInBody.linkSteam, "linkOculus": loggingInBody.linkOculus, "errorString": errorString }); |
| 326 | else { | 422 | } else { |
| 327 | errorString = "Username or password is incorrect."; | 423 | errorString = "Username or password is incorrect."; |
| 328 | if (loggingInBody.loginDialogPoppedUp) { | 424 | if (loggingInBody.loginDialogPoppedUp) { |
| 329 | var data = { | 425 | var data = { |
| @@ -23,6 +23,7 @@ Item { · 22 unmodified lines | |||
| 23 | clip: true | 23 | clip: true |
| 24 | height: root.height | 24 | height: root.height |
| 25 | width: root.width | 25 | width: root.width |
| 26 | readonly property string termsContainerText: qsTr("By signing up, you agree to High Fidelity's Terms of Service") | ||
| 26 | property int textFieldHeight: 31 | 27 | property int textFieldHeight: 31 |
| 27 | property string fontFamily: "Raleway" | 28 | property string fontFamily: "Raleway" |
| 28 | property int fontSize: 15 | 29 | property int fontSize: 15 |
| @@ -37,7 +38,6 @@ Item { · 8 unmodified lines | |||
| 37 | onKeyboardRaisedChanged: d.resize(); | 38 | onKeyboardRaisedChanged: d.resize(); |
| 38 | 39 | ||
| 39 | property string errorString: errorString | 40 | property string errorString: errorString |
| 40 | property bool linkSteam: linkSteam | ||
| 41 | property bool lostFocus: false | 41 | property bool lostFocus: false |
| 42 | 42 | ||
| 43 | readonly property bool loginDialogPoppedUp: loginDialog.getLoginDialogPoppedUp() | 43 | readonly property bool loginDialogPoppedUp: loginDialog.getLoginDialogPoppedUp() |
| @@ -73,7 +73,6 @@ Item { · 29 unmodified lines | |||
| 73 | 73 | ||
| 74 | function init() { | 74 | function init() { |
| 75 | // going to/from sign in/up dialog. | 75 | // going to/from sign in/up dialog. |
| 76 | loginDialog.isLogIn = false; | ||
| 77 | emailField.placeholderText = "Email"; | 76 | emailField.placeholderText = "Email"; |
| 78 | emailField.text = ""; | 77 | emailField.text = ""; |
| 79 | emailField.anchors.top = usernameField.bottom; | 78 | emailField.anchors.top = usernameField.bottom; |
| @@ -353,7 +352,7 @@ Item { · 273 unmodified lines | |||
| 353 | } | 352 | } |
| 354 | UserActivityLogger.logAction("encourageLoginDialog", data); | 353 | UserActivityLogger.logAction("encourageLoginDialog", data); |
| 355 | } | 354 | } |
| 356 | bodyLoader.setSource("LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "linkSteam": signUpBody.linkSteam }); | 355 | bodyLoader.setSource("LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "linkSteam": false }); |
| 357 | } | 356 | } |
| 358 | } | 357 | } |
| 359 | HifiControlsUit.Button { | 358 | HifiControlsUit.Button { |
| @@ -380,6 +379,54 @@ Item { · 20 unmodified lines | |||
| 380 | signUpBody.signup(); | 379 | signUpBody.signup(); |
| 381 | } | 380 | } |
| 382 | } | 381 | } |
| 382 | Item { | ||
| 383 | id: termsContainer | ||
| 384 | width: parent.width | ||
| 385 | height: termsTextMetrics.height | ||
| 386 | anchors { | ||
| 387 | top: signUpButton.bottom | ||
| 388 | horizontalCenter: parent.horizontalCenter | ||
| 389 | topMargin: 2 * hifi.dimensions.contentSpacing.y | ||
| 390 | left: parent.left | ||
| 391 | } | ||
| 392 | TextMetrics { | ||
| 393 | id: termsTextMetrics | ||
| 394 | font: termsText.font | ||
| 395 | text: signUpBody.termsContainerText | ||
| 396 | Component.onCompleted: { | ||
| 397 | // with the link. | ||
| 398 | termsText.text = qsTr("By signing up, you agree to <a href='https://highfidelity.com/terms'>High Fidelity's Terms of Service</a>") | ||
| 399 | } | ||
| 400 | } | ||
| 401 | |||
| 402 | HifiStylesUit.InfoItem { | ||
| 403 | id: termsText | ||
| 404 | text: signUpBody.termsContainerText | ||
| 405 | font.family: signUpBody.fontFamily | ||
| 406 | font.pixelSize: signUpBody.fontSize | ||
| 407 | font.bold: signUpBody.fontBold | ||
| 408 | wrapMode: Text.WordWrap | ||
| 409 | color: hifi.colors.white | ||
| 410 | linkColor: hifi.colors.blueAccent | ||
| 411 | lineHeight: 1 | ||
| 412 | lineHeightMode: Text.ProportionalHeight | ||
| 413 | |||
| 414 | onLinkActivated: loginDialog.openUrl(link); | ||
| 415 | |||
| 416 | Component.onCompleted: { | ||
| 417 | if (termsTextMetrics.width > root.bannerWidth) { | ||
| 418 | termsText.width = root.bannerWidth; | ||
| 419 | termsText.wrapMode = Text.WordWrap; | ||
| 420 | additionalText.verticalAlignment = Text.AlignLeft; | ||
| 421 | additionalText.horizontalAlignment = Text.AlignLeft; | ||
| 422 | termsContainer.height = (termsTextMetrics.width / root.bannerWidth) * termsTextMetrics.height; | ||
| 423 | termsContainer.anchors.left = buttons.left; | ||
| 424 | } else { | ||
| 425 | termsText.anchors.centerIn = termsContainer; | ||
| 426 | } | ||
| 427 | } | ||
| 428 | } | ||
| 429 | } | ||
| 383 | } | 430 | } |
| 384 | } | 431 | } |
| 385 | 432 | ||
| @@ -433,14 +480,15 @@ Item { · 47 unmodified lines | |||
| 433 | 480 | ||
| 434 | if (errorString !== "") { | 481 | if (errorString !== "") { |
| 435 | loginErrorMessage.visible = true; | 482 | loginErrorMessage.visible = true; |
| 483 | var errorLength = errorString.split(/\r\n|\r|\n/).length; | ||
| 436 | var errorStringEdited = errorString.replace(/[\n\r]+/g, "\n"); | 484 | var errorStringEdited = errorString.replace(/[\n\r]+/g, "\n"); |
| 437 | loginErrorMessage.text = errorStringEdited; | 485 | loginErrorMessage.text = errorStringEdited; |
| 438 | loginErrorMessageTextMetrics.text = errorString; | 486 | if (errorLength > 1.0) { |
| 439 | if (loginErrorMessageTextMetrics.width > usernameField.width) { | 487 | loginErrorMessage.width = root.bannerWidth; |
| 440 | loginErrorMessage.wrapMode = Text.WordWrap; | 488 | loginErrorMessage.wrapMode = Text.WordWrap; |
| 441 | loginErrorMessage.verticalAlignment = Text.AlignLeft; | 489 | loginErrorMessage.verticalAlignment = Text.AlignLeft; |
| 442 | loginErrorMessage.horizontalAlignment = Text.AlignLeft; | 490 | loginErrorMessage.horizontalAlignment = Text.AlignLeft; |
| 443 | errorContainer.height = (loginErrorMessageTextMetrics.width / usernameField.width) * loginErrorMessageTextMetrics.height; | 491 | errorContainer.height = errorLength * loginErrorMessageTextMetrics.height; |
| 444 | } | 492 | } |
| 445 | errorContainer.anchors.bottom = usernameField.top; | 493 | errorContainer.anchors.bottom = usernameField.top; |
| 446 | errorContainer.anchors.bottomMargin = hifi.dimensions.contentSpacing.y; | 494 | errorContainer.anchors.bottomMargin = hifi.dimensions.contentSpacing.y; |
| @@ -19,6 +19,7 @@ import TabletScriptingInterface 1.0 · 18 unmodified lines | |||
| 19 | Item { | 19 | Item { |
| 20 | id: usernameCollisionBody | 20 | id: usernameCollisionBody |
| 21 | clip: true | 21 | clip: true |
| 22 | readonly property string termsContainerText: qsTr("By creating this user profile, you agree to High Fidelity's Terms of Service") | ||
| 22 | width: root.width | 23 | width: root.width |
| 23 | height: root.height | 24 | height: root.height |
| 24 | readonly property string fontFamily: "Raleway" | 25 | readonly property string fontFamily: "Raleway" |
| @@ -26,13 +27,18 @@ Item { · 1 unmodified line | |||
| 26 | readonly property int textFieldFontSize: 18 | 27 | readonly property int textFieldFontSize: 18 |
| 27 | readonly property bool fontBold: true | 28 | readonly property bool fontBold: true |
| 28 | 29 | ||
| 29 | readonly property bool withSteam: withSteam | 30 | property bool withSteam: withSteam |
| 31 | property bool withOculus: withOculus | ||
| 30 | 32 | ||
| 31 | readonly property bool loginDialogPoppedUp: loginDialog.getLoginDialogPoppedUp() | 33 | readonly property bool loginDialogPoppedUp: loginDialog.getLoginDialogPoppedUp() |
| 32 | 34 | ||
| 33 | function create() { | 35 | function create() { |
| 34 | mainTextContainer.visible = false | 36 | mainTextContainer.visible = false |
| 35 | loginDialog.createAccountFromSteam(textField.text); | 37 | if (usernameCollisionBody.withOculus) { |
| 38 | loginDialog.createAccountFromOculus(textField.text); | ||
| 39 | } else if (usernameCollisionBody.withSteam) { | ||
| 40 | loginDialog.createAccountFromSteam(textField.text); | ||
| 41 | } | ||
| 36 | } | 42 | } |
| 37 | 43 | ||
| 38 | property bool keyboardEnabled: false | 44 | property bool keyboardEnabled: false |
| @@ -90,12 +96,19 @@ Item { · 51 unmodified lines | |||
| 90 | font.family: usernameCollisionBody.fontFamily | 96 | font.family: usernameCollisionBody.fontFamily |
| 91 | font.pixelSize: usernameCollisionBody.fontSize | 97 | font.pixelSize: usernameCollisionBody.fontSize |
| 92 | font.bold: usernameCollisionBody.fontBold | 98 | font.bold: usernameCollisionBody.fontBold |
| 93 | text: qsTr("Your Steam username is not available."); | 99 | text: qsTr(""); |
| 94 | wrapMode: Text.WordWrap | 100 | wrapMode: Text.WordWrap |
| 95 | color: hifi.colors.redAccent | 101 | color: hifi.colors.redAccent |
| 96 | lineHeight: 1 | 102 | lineHeight: 1 |
| 97 | lineHeightMode: Text.ProportionalHeight | 103 | lineHeightMode: Text.ProportionalHeight |
| 98 | horizontalAlignment: Text.AlignHCenter | 104 | horizontalAlignment: Text.AlignHCenter |
| 105 | Component.onCompleted: { | ||
| 106 | if (usernameCollisionBody.withOculus) { | ||
| 107 | text = qsTr("Your Oculus username is not available."); | ||
| 108 | } else if (usernameCollisionBody.withSteam) { | ||
| 109 | text = qsTr("Your Steam username is not available."); | ||
| 110 | } | ||
| 111 | } | ||
| 99 | } | 112 | } |
| 100 | 113 | ||
| 101 | 114 | ||
| @@ -164,7 +177,8 @@ Item { · 62 unmodified lines | |||
| 164 | fontSize: usernameCollisionBody.fontSize | 177 | fontSize: usernameCollisionBody.fontSize |
| 165 | fontBold: usernameCollisionBody.fontBold | 178 | fontBold: usernameCollisionBody.fontBold |
| 166 | onClicked: { | 179 | onClicked: { |
| 167 | bodyLoader.setSource("CompleteProfileBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "errorString": "" }); | 180 | bodyLoader.setSource("CompleteProfileBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": usernameCollisionBody.withSteam, |
| 181 | "withOculus": usernameCollisionBody.withOculus, "errorString": "" }); | ||
| 168 | } | 182 | } |
| 169 | } | 183 | } |
| 170 | HifiControlsUit.Button { | 184 | HifiControlsUit.Button { |
| @@ -187,6 +201,55 @@ Item { · 16 unmodified lines | |||
| 187 | } | 201 | } |
| 188 | } | 202 | } |
| 189 | } | 203 | } |
| 204 | Item { | ||
| 205 | id: termsContainer | ||
| 206 | width: parent.width | ||
| 207 | height: termsTextMetrics.height | ||
| 208 | anchors { | ||
| 209 | top: buttons.bottom | ||
| 210 | horizontalCenter: parent.horizontalCenter | ||
| 211 | topMargin: 2 * hifi.dimensions.contentSpacing.y | ||
| 212 | left: parent.left | ||
| 213 | leftMargin: (parent.width - buttons.width) / 2 | ||
| 214 | } | ||
| 215 | TextMetrics { | ||
| 216 | id: termsTextMetrics | ||
| 217 | font: termsText.font | ||
| 218 | text: usernameCollisionBody.termsContainerText | ||
| 219 | Component.onCompleted: { | ||
| 220 | // with the link. | ||
| 221 | termsText.text = qsTr("By creating this user profile, you agree to <a href='https://highfidelity.com/terms'>High Fidelity's Terms of Service</a>") | ||
| 222 | } | ||
| 223 | } | ||
| 224 | |||
| 225 | HifiStylesUit.InfoItem { | ||
| 226 | id: termsText | ||
| 227 | text: usernameCollisionBody.termsContainerText | ||
| 228 | font.family: usernameCollisionBody.fontFamily | ||
| 229 | font.pixelSize: usernameCollisionBody.fontSize | ||
| 230 | font.bold: usernameCollisionBody.fontBold | ||
| 231 | wrapMode: Text.WordWrap | ||
| 232 | color: hifi.colors.white | ||
| 233 | linkColor: hifi.colors.blueAccent | ||
| 234 | lineHeight: 1 | ||
| 235 | lineHeightMode: Text.ProportionalHeight | ||
| 236 | |||
| 237 | onLinkActivated: loginDialog.openUrl(link); | ||
| 238 | |||
| 239 | Component.onCompleted: { | ||
| 240 | if (termsTextMetrics.width > root.bannerWidth) { | ||
| 241 | termsText.width = root.bannerWidth; | ||
| 242 | termsText.wrapMode = Text.WordWrap; | ||
| 243 | additionalText.verticalAlignment = Text.AlignLeft; | ||
| 244 | additionalText.horizontalAlignment = Text.AlignLeft; | ||
| 245 | termsContainer.height = (termsTextMetrics.width / root.bannerWidth) * termsTextMetrics.height; | ||
| 246 | termsContainer.anchors.left = buttons.left; | ||
| 247 | } else { | ||
| 248 | termsText.anchors.centerIn = termsContainer; | ||
| 249 | } | ||
| 250 | } | ||
| 251 | } | ||
| 252 | } | ||
| 190 | } | 253 | } |
| 191 | 254 | ||
| 192 | Component.onCompleted: { | 255 | Component.onCompleted: { |
| @@ -201,18 +264,25 @@ Item { · 8 unmodified lines | |||
| 201 | target: loginDialog | 264 | target: loginDialog |
| 202 | onHandleCreateCompleted: { | 265 | onHandleCreateCompleted: { |
| 203 | console.log("Create Succeeded"); | 266 | console.log("Create Succeeded"); |
| 204 | if (usernameCollisionBody.withSteam) { | 267 | if (usernameCollisionBody.withOculus) { |
| 268 | if (usernameCollisionBody.loginDialogPoppedUp) { | ||
| 269 | var data = { | ||
| 270 | "action": "user created a profile with Oculus successfully in the username collision screen" | ||
| 271 | } | ||
| 272 | UserActivityLogger.logAction("encourageLoginDialog", data); | ||
| 273 | } | ||
| 274 | loginDialog.loginThroughOculus(); | ||
| 275 | } else if (usernameCollisionBody.withSteam) { | ||
| 205 | if (usernameCollisionBody.loginDialogPoppedUp) { | 276 | if (usernameCollisionBody.loginDialogPoppedUp) { |
| 206 | var data = { | 277 | var data = { |
| 207 | "action": "user created a profile with Steam successfully in the username collision screen" | 278 | "action": "user created a profile with Steam successfully in the username collision screen" |
| 208 | } | 279 | } |
| 209 | UserActivityLogger.logAction("encourageLoginDialog", data); | 280 | UserActivityLogger.logAction("encourageLoginDialog", data); |
| 210 | } | 281 | } |
| 211 | |||
| 212 | loginDialog.loginThroughSteam(); | 282 | loginDialog.loginThroughSteam(); |
| 213 | } | 283 | } |
| 214 | 284 | bodyLoader.setSource("LoggingInBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": usernameCollisionBody.withSteam, | |
| 215 | bodyLoader.setSource("LoggingInBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "withSteam": usernameCollisionBody.withSteam, "linkSteam": false }) | 285 | "withOculus": usernameCollisionBody.withOculus, "linkSteam": false, "linkOculus": false }) |
| 216 | } | 286 | } |
| 217 | onHandleCreateFailed: { | 287 | onHandleCreateFailed: { |
| 218 | console.log("Create Failed: " + error) | 288 | console.log("Create Failed: " + error) |
| @@ -150,6 +150,6 @@ FocusScope { · 149 unmodified lines | |||
| 150 | 150 | ||
| 151 | Component.onCompleted: { | 151 | Component.onCompleted: { |
| 152 | keyboardTimer.start(); | 152 | keyboardTimer.start(); |
| 153 | bodyLoader.setSource("LoginDialog/LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "linkSteam": false }); | 153 | bodyLoader.setSource("LoginDialog/LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "linkSteam": false, "linkOculus": false }); |
| 154 | } | 154 | } |
| 155 | } | 155 | } |
| @@ -14,6 +14,8 @@ import QtQuick 2.5 · 13 unmodified lines | |||
| 14 | import controlsUit 1.0 as HifiControlsUit | 14 | import controlsUit 1.0 as HifiControlsUit |
| 15 | import stylesUit 1.0 as HifiStylesUit | 15 | import stylesUit 1.0 as HifiStylesUit |
| 16 | 16 | ||
| 17 | import TabletScriptingInterface 1.0 | ||
| 18 | |||
| 17 | import "../LoginDialog" | 19 | import "../LoginDialog" |
| 18 | 20 | ||
| 19 | FocusScope { | 21 | FocusScope { |
| @@ -25,10 +27,9 @@ FocusScope { · 5 unmodified lines | |||
| 25 | width: parent.width | 27 | width: parent.width |
| 26 | height: parent.height | 28 | height: parent.height |
| 27 | 29 | ||
| 28 | signal sendToScript(var message); | 30 | property var tabletProxy: Tablet.getTablet("com.highfidelity.interface.tablet.system"); |
| 29 | signal canceled(); | ||
| 30 | 31 | ||
| 31 | property bool isHMD: false | 32 | property bool isHMD: HMD.active |
| 32 | property bool gotoPreviousApp: false; | 33 | property bool gotoPreviousApp: false; |
| 33 | 34 | ||
| 34 | property bool keyboardEnabled: false | 35 | property bool keyboardEnabled: false |
| @@ -52,6 +53,7 @@ FocusScope { · 17 unmodified lines | |||
| 52 | } | 53 | } |
| 53 | 54 | ||
| 54 | function tryDestroy() { | 55 | function tryDestroy() { |
| 56 | tabletProxy.gotoHomeScreen(); | ||
| 55 | } | 57 | } |
| 56 | 58 | ||
| 57 | MouseArea { | 59 | MouseArea { |
| @@ -76,7 +78,7 @@ FocusScope { · 18 unmodified lines | |||
| 76 | interval: 200 | 78 | interval: 200 |
| 77 | 79 | ||
| 78 | onTriggered: { | 80 | onTriggered: { |
| 79 | if (MenuInterface.isOptionChecked("Use 3D Keyboard")) { | 81 | if (MenuInterface.isOptionChecked("Use 3D Keyboard") && root.isHMD) { |
| 80 | KeyboardScriptingInterface.raised = true; | 82 | KeyboardScriptingInterface.raised = true; |
| 81 | } | 83 | } |
| 82 | } | 84 | } |
| @@ -169,11 +171,13 @@ FocusScope { · 86 unmodified lines | |||
| 169 | 171 | ||
| 170 | Component.onDestruction: { | 172 | Component.onDestruction: { |
| 171 | loginKeyboard.raised = false; | 173 | loginKeyboard.raised = false; |
| 172 | KeyboardScriptingInterface.raised = false; | 174 | if (root.isHMD) { |
| 175 | KeyboardScriptingInterface.raised = false; | ||
| 176 | } | ||
| 173 | } | 177 | } |
| 174 | 178 | ||
| 175 | Component.onCompleted: { | 179 | Component.onCompleted: { |
| 176 | keyboardTimer.start(); | 180 | keyboardTimer.start(); |
| 177 | bodyLoader.setSource("../LoginDialog/LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "linkSteam": false }); | 181 | bodyLoader.setSource("../LoginDialog/LinkAccountBody.qml", { "loginDialog": loginDialog, "root": root, "bodyLoader": bodyLoader, "linkSteam": false, "linkOculus": false }); |
| 178 | } | 182 | } |
| 179 | } | 183 | } |
| @@ -120,6 +120,7 @@ · 119 unmodified lines | |||
| 120 | #include <plugins/PluginManager.h> | 120 | #include <plugins/PluginManager.h> |
| 121 | #include <plugins/PluginUtils.h> | 121 | #include <plugins/PluginUtils.h> |
| 122 | #include <plugins/SteamClientPlugin.h> | 122 | #include <plugins/SteamClientPlugin.h> |
| 123 | #include <plugins/OculusPlatformPlugin.h> | ||
| 123 | #include <plugins/InputConfiguration.h> | 124 | #include <plugins/InputConfiguration.h> |
| 124 | #include <RecordingScriptingInterface.h> | 125 | #include <RecordingScriptingInterface.h> |
| 125 | #include <render/EngineStats.h> | 126 | #include <render/EngineStats.h> |
| @@ -800,7 +801,6 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { · 674 unmodified lines | |||
| 800 | if (auto steamClient = pluginManager->getSteamClientPlugin()) { | 801 | if (auto steamClient = pluginManager->getSteamClientPlugin()) { |
| 801 | steamClient->init(); | 802 | steamClient->init(); |
| 802 | } | 803 | } |
| 803 | |||
| 804 | PROFILE_SET_THREAD_NAME("Main Thread"); | 804 | PROFILE_SET_THREAD_NAME("Main Thread"); |
| 805 | 805 | ||
| 806 | #if defined(Q_OS_WIN) | 806 | #if defined(Q_OS_WIN) |
| @@ -2737,6 +2737,7 @@ Application::~Application() { · 1930 unmodified lines | |||
| 2737 | if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) { | 2737 | if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) { |
| 2738 | steamClient->shutdown(); | 2738 | steamClient->shutdown(); |
| 2739 | } | 2739 | } |
| 2740 | |||
| 2740 | DependencyManager::destroy<PluginManager>(); | 2741 | DependencyManager::destroy<PluginManager>(); |
| 2741 | 2742 | ||
| 2742 | DependencyManager::destroy<CompositorHelper>(); // must be destroyed before the FramebufferCache | 2743 | DependencyManager::destroy<CompositorHelper>(); // must be destroyed before the FramebufferCache |
| @@ -4873,6 +4874,10 @@ void Application::idle() { · 2130 unmodified lines | |||
| 4873 | steamClient->runCallbacks(); | 4874 | steamClient->runCallbacks(); |
| 4874 | } | 4875 | } |
| 4875 | 4876 | ||
| 4877 | if (auto oculusPlugin = PluginManager::getInstance()->getOculusPlatformPlugin()) { | ||
| 4878 | oculusPlugin->handleOVREvents(); | ||
| 4879 | } | ||
| 4880 | |||
| 4876 | float secondsSinceLastUpdate = (float)_lastTimeUpdated.nsecsElapsed() / NSECS_PER_MSEC / MSECS_PER_SECOND; | 4881 | float secondsSinceLastUpdate = (float)_lastTimeUpdated.nsecsElapsed() / NSECS_PER_MSEC / MSECS_PER_SECOND; |
| 4877 | _lastTimeUpdated.start(); | 4882 | _lastTimeUpdated.start(); |
| 4878 | 4883 | ||
| @@ -18,6 +18,7 @@ · 17 unmodified lines | |||
| 18 | 18 | ||
| 19 | #include <plugins/PluginManager.h> | 19 | #include <plugins/PluginManager.h> |
| 20 | #include <plugins/SteamClientPlugin.h> | 20 | #include <plugins/SteamClientPlugin.h> |
| 21 | #include <plugins/OculusPlatformPlugin.h> | ||
| 21 | #include <shared/GlobalAppProperties.h> | 22 | #include <shared/GlobalAppProperties.h> |
| 22 | #include <ui/TabletScriptingInterface.h> | 23 | #include <ui/TabletScriptingInterface.h> |
| 23 | #include <UserActivityLogger.h> | 24 | #include <UserActivityLogger.h> |
| @@ -109,8 +110,16 @@ bool LoginDialog::isSteamRunning() const { · 85 unmodified lines | |||
| 109 | return steamClient && steamClient->isRunning(); | 110 | return steamClient && steamClient->isRunning(); |
| 110 | } | 111 | } |
| 111 | 112 | ||
| 112 | bool LoginDialog::isOculusStoreRunning() const { | 113 | bool LoginDialog::isOculusRunning() const { |
| 113 | return qApp->property(hifi::properties::OCULUS_STORE).toBool(); | 114 | auto oculusPlatformPlugin = PluginManager::getInstance()->getOculusPlatformPlugin(); |
| 115 | return (oculusPlatformPlugin && oculusPlatformPlugin->isRunning()); | ||
| 116 | } | ||
| 117 | |||
| 118 | QString LoginDialog::oculusUserID() const { | ||
| 119 | if (auto oculusPlatformPlugin = PluginManager::getInstance()->getOculusPlatformPlugin()) { | ||
| 120 | return oculusPlatformPlugin->getOculusUserID(); | ||
| 121 | } | ||
| 122 | return ""; | ||
| 114 | } | 123 | } |
| 115 | 124 | ||
| 116 | void LoginDialog::dismissLoginDialog() { | 125 | void LoginDialog::dismissLoginDialog() { |
| @@ -126,6 +135,79 @@ void LoginDialog::login(const QString& username, const QString& password) const · 9 unmodified lines | |||
| 126 | DependencyManager::get<AccountManager>()->requestAccessToken(username, password); | 135 | DependencyManager::get<AccountManager>()->requestAccessToken(username, password); |
| 127 | } | 136 | } |
| 128 | 137 | ||
| 138 | void LoginDialog::loginThroughOculus() { | ||
| 139 | qDebug() << "Attempting to login through Oculus"; | ||
| 140 | if (auto oculusPlatformPlugin = PluginManager::getInstance()->getOculusPlatformPlugin()) { | ||
| 141 | oculusPlatformPlugin->requestNonceAndUserID([this] (QString nonce, QString oculusID) { | ||
| 142 | DependencyManager::get<AccountManager>()->requestAccessTokenWithOculus(nonce, oculusID); | ||
| 143 | }); | ||
| 144 | } | ||
| 145 | } | ||
| 146 | |||
| 147 | void LoginDialog::linkOculus() { | ||
| 148 | qDebug() << "Attempting to link Oculus account"; | ||
| 149 | if (auto oculusPlatformPlugin = PluginManager::getInstance()->getOculusPlatformPlugin()) { | ||
| 150 | oculusPlatformPlugin->requestNonceAndUserID([this] (QString nonce, QString oculusID) { | ||
| 151 | if (nonce.isEmpty() || oculusID.isEmpty()) { | ||
| 152 | emit handleLoginFailed(); | ||
| 153 | return; | ||
| 154 | } | ||
| 155 | |||
| 156 | JSONCallbackParameters callbackParams; | ||
| 157 | callbackParams.callbackReceiver = this; | ||
| 158 | callbackParams.jsonCallbackMethod = "linkCompleted"; | ||
| 159 | callbackParams.errorCallbackMethod = "linkFailed"; | ||
| 160 | const QString LINK_OCULUS_PATH = "api/v1/user/oculus/link"; | ||
| 161 | |||
| 162 | QJsonObject payload; | ||
| 163 | payload["oculus_nonce"] = nonce; | ||
| 164 | payload["oculus_id"] = oculusID; | ||
| 165 | |||
| 166 | auto accountManager = DependencyManager::get<AccountManager>(); | ||
| 167 | accountManager->sendRequest(LINK_OCULUS_PATH, AccountManagerAuth::Required, | ||
| 168 | QNetworkAccessManager::PostOperation, callbackParams, | ||
| 169 | QJsonDocument(payload).toJson()); | ||
| 170 | }); | ||
| 171 | } | ||
| 172 | } | ||
| 173 | |||
| 174 | void LoginDialog::createAccountFromOculus(QString email, QString username, QString password) { | ||
| 175 | qDebug() << "Attempting to create account from Oculus info"; | ||
| 176 | if (auto oculusPlatformPlugin = PluginManager::getInstance()->getOculusPlatformPlugin()) { | ||
| 177 | oculusPlatformPlugin->requestNonceAndUserID([this, email, username, password] (QString nonce, QString oculusID) { | ||
| 178 | if (nonce.isEmpty() || oculusID.isEmpty()) { | ||
| 179 | emit handleLoginFailed(); | ||
| 180 | return; | ||
| 181 | } | ||
| 182 | |||
| 183 | JSONCallbackParameters callbackParams; | ||
| 184 | callbackParams.callbackReceiver = this; | ||
| 185 | callbackParams.jsonCallbackMethod = "createCompleted"; | ||
| 186 | callbackParams.errorCallbackMethod = "createFailed"; | ||
| 187 | |||
| 188 | const QString CREATE_ACCOUNT_FROM_OCULUS_PATH = "api/v1/user/oculus/create"; | ||
| 189 | |||
| 190 | QJsonObject payload; | ||
| 191 | payload["oculus_nonce"] = nonce; | ||
| 192 | payload["oculus_id"] = oculusID; | ||
| 193 | if (!email.isEmpty()) { | ||
| 194 | payload["email"] = email; | ||
| 195 | } | ||
| 196 | if (!username.isEmpty()) { | ||
| 197 | payload["username"] = username; | ||
| 198 | } | ||
| 199 | if (!password.isEmpty()) { | ||
| 200 | payload["password"] = password; | ||
| 201 | } | ||
| 202 | |||
| 203 | auto accountManager = DependencyManager::get<AccountManager>(); | ||
| 204 | accountManager->sendRequest(CREATE_ACCOUNT_FROM_OCULUS_PATH, AccountManagerAuth::None, | ||
| 205 | QNetworkAccessManager::PostOperation, callbackParams, | ||
| 206 | QJsonDocument(payload).toJson()); | ||
| 207 | }); | ||
| 208 | } | ||
| 209 | } | ||
| 210 | |||
| 129 | void LoginDialog::loginThroughSteam() { | 211 | void LoginDialog::loginThroughSteam() { |
| 130 | qDebug() << "Attempting to login through Steam"; | 212 | qDebug() << "Attempting to login through Steam"; |
| 131 | if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) { | 213 | if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) { |
| @@ -157,7 +239,7 @@ void LoginDialog::linkSteam() { · 25 unmodified lines | |||
| 157 | const QString LINK_STEAM_PATH = "api/v1/user/steam/link"; | 239 | const QString LINK_STEAM_PATH = "api/v1/user/steam/link"; |
| 158 | 240 | ||
| 159 | QJsonObject payload; | 241 | QJsonObject payload; |
| 160 | payload.insert("steam_auth_ticket", QJsonValue::fromVariant(QVariant(ticket))); | 242 | payload["steam_auth_ticket"] = QJsonValue::fromVariant(QVariant(ticket)); |
| 161 | 243 | ||
| 162 | auto accountManager = DependencyManager::get<AccountManager>(); | 244 | auto accountManager = DependencyManager::get<AccountManager>(); |
| 163 | accountManager->sendRequest(LINK_STEAM_PATH, AccountManagerAuth::Required, | 245 | accountManager->sendRequest(LINK_STEAM_PATH, AccountManagerAuth::Required, |
| @@ -184,9 +266,9 @@ void LoginDialog::createAccountFromSteam(QString username) { · 20 unmodified lines | |||
| 184 | const QString CREATE_ACCOUNT_FROM_STEAM_PATH = "api/v1/user/steam/create"; | 266 | const QString CREATE_ACCOUNT_FROM_STEAM_PATH = "api/v1/user/steam/create"; |
| 185 | 267 | ||
| 186 | QJsonObject payload; | 268 | QJsonObject payload; |
| 187 | payload.insert("steam_auth_ticket", QJsonValue::fromVariant(QVariant(ticket))); | 269 | payload["steam_auth_ticket"] = QJsonValue::fromVariant(QVariant(ticket)); |
| 188 | if (!username.isEmpty()) { | 270 | if (!username.isEmpty()) { |
| 189 | payload.insert("username", QJsonValue::fromVariant(QVariant(username))); | 271 | payload["username"] = username; |
| 190 | } | 272 | } |
| 191 | 273 | ||
| 192 | auto accountManager = DependencyManager::get<AccountManager>(); | 274 | auto accountManager = DependencyManager::get<AccountManager>(); |
| @@ -214,6 +296,45 @@ void LoginDialog::createCompleted(QNetworkReply* reply) { · 21 unmodified lines | |||
| 214 | } | 296 | } |
| 215 | 297 | ||
| 216 | void LoginDialog::createFailed(QNetworkReply* reply) { | 298 | void LoginDialog::createFailed(QNetworkReply* reply) { |
| 299 | if (isOculusRunning()) { | ||
| 300 | auto replyData = reply->readAll(); | ||
| 301 | QJsonParseError parseError; | ||
| 302 | auto doc = QJsonDocument::fromJson(replyData, &parseError); | ||
| 303 | if (parseError.error != QJsonParseError::NoError) { | ||
| 304 | emit handleCreateFailed(reply->errorString()); | ||
| 305 | return; | ||
| 306 | } | ||
| 307 | auto data = doc["data"]; | ||
| 308 | auto error = data["error"]; | ||
| 309 | auto oculusError = data["oculus"]; | ||
| 310 | auto user = error["username"].toArray(); | ||
| 311 | auto uid = error["uid"].toArray(); | ||
| 312 | auto email = error["email"].toArray(); | ||
| 313 | auto password = error["password"].toArray(); | ||
| 314 | QString reply; | ||
| 315 | if (uid[0].isString()) { | ||
| 316 | emit handleCreateFailed("Oculus ID " + uid[0].toString() + "."); | ||
| 317 | return; | ||
| 318 | } | ||
| 319 | if (user[0].isString()) { | ||
| 320 | reply = "Username " + user[0].toString() + "."; | ||
| 321 | } | ||
| 322 | if (email[0].isString()) { | ||
| 323 | reply.append((!reply.isEmpty()) ? "\n" : ""); | ||
| 324 | reply.append("Email " + email[0].toString() + "."); | ||
| 325 | } | ||
| 326 | if (password[0].isString()) { | ||
| 327 | reply.append((!reply.isEmpty()) ? "\n" : ""); | ||
| 328 | reply.append("Password " + password[0].toString() + "."); | ||
| 329 | } | ||
| 330 | if (!oculusError.isNull() && !oculusError.isUndefined()) { | ||
| 331 | emit handleCreateFailed("Could not verify token with Oculus. Please try again."); | ||
| 332 | return; | ||
| 333 | } else { | ||
| 334 | emit handleCreateFailed(reply); | ||
| 335 | return; | ||
| 336 | } | ||
| 337 | } | ||
| 217 | emit handleCreateFailed(reply->errorString()); | 338 | emit handleCreateFailed(reply->errorString()); |
| 218 | } | 339 | } |
| 219 | 340 | ||
| @@ -22,7 +22,6 @@ extern const QUrl OVERLAY_LOGIN_DIALOG; · 21 unmodified lines | |||
| 22 | 22 | ||
| 23 | class LoginDialog : public OffscreenQmlDialog { | 23 | class LoginDialog : public OffscreenQmlDialog { |
| 24 | Q_OBJECT | 24 | Q_OBJECT |
| 25 | Q_PROPERTY(bool isLogIn READ getIsLogIn WRITE setIsLogIn) | ||
| 26 | HIFI_QML_DECL | 25 | HIFI_QML_DECL |
| 27 | 26 | ||
| 28 | public: | 27 | public: |
| @@ -67,24 +66,23 @@ protected slots: · 38 unmodified lines | |||
| 67 | Q_INVOKABLE void dismissLoginDialog(); | 66 | Q_INVOKABLE void dismissLoginDialog(); |
| 68 | 67 | ||
| 69 | Q_INVOKABLE bool isSteamRunning() const; | 68 | Q_INVOKABLE bool isSteamRunning() const; |
| 70 | Q_INVOKABLE bool isOculusStoreRunning() const; | 69 | Q_INVOKABLE bool isOculusRunning() const; |
| 70 | |||
| 71 | Q_INVOKABLE QString oculusUserID() const; | ||
| 71 | 72 | ||
| 72 | Q_INVOKABLE void login(const QString& username, const QString& password) const; | 73 | Q_INVOKABLE void login(const QString& username, const QString& password) const; |
| 73 | Q_INVOKABLE void loginThroughSteam(); | 74 | Q_INVOKABLE void loginThroughSteam(); |
| 74 | Q_INVOKABLE void linkSteam(); | 75 | Q_INVOKABLE void linkSteam(); |
| 75 | Q_INVOKABLE void createAccountFromSteam(QString username = QString()); | 76 | Q_INVOKABLE void createAccountFromSteam(QString username = QString()); |
| 77 | Q_INVOKABLE void loginThroughOculus(); | ||
| 78 | Q_INVOKABLE void linkOculus(); | ||
| 79 | Q_INVOKABLE void createAccountFromOculus(QString email = QString(), QString username = QString(), QString password = QString()); | ||
| 76 | 80 | ||
| 77 | Q_INVOKABLE void signup(const QString& email, const QString& username, const QString& password); | 81 | Q_INVOKABLE void signup(const QString& email, const QString& username, const QString& password); |
| 78 | 82 | ||
| 79 | Q_INVOKABLE void openUrl(const QString& url) const; | 83 | Q_INVOKABLE void openUrl(const QString& url) const; |
| 80 | 84 | ||
| 81 | Q_INVOKABLE bool getLoginDialogPoppedUp() const; | 85 | Q_INVOKABLE bool getLoginDialogPoppedUp() const; |
| 82 | |||
| 83 | private: | ||
| 84 | bool getIsLogIn() const { return _isLogIn; } | ||
| 85 | void setIsLogIn(const bool isLogIn) { _isLogIn = isLogIn; } | ||
| 86 | |||
| 87 | bool _isLogIn{ false }; | ||
| 88 | }; | 86 | }; |
| 89 | 87 | ||
| 90 | #endif // hifi_LoginDialog_h | 88 | #endif // hifi_LoginDialog_h |
| @@ -31,6 +31,8 @@ public: · 30 unmodified lines | |||
| 31 | 31 | ||
| 32 | virtual void compositeExtra() override; | 32 | virtual void compositeExtra() override; |
| 33 | 33 | ||
| 34 | virtual void pluginUpdate() override {}; | ||
| 35 | |||
| 34 | protected: | 36 | protected: |
| 35 | mutable bool _isThrottled = false; | 37 | mutable bool _isThrottled = false; |
| 36 | 38 | ||
| @@ -20,6 +20,7 @@ public: · 19 unmodified lines | |||
| 20 | QImage getScreenshot(float aspectRatio = 0.0f) const override; | 20 | QImage getScreenshot(float aspectRatio = 0.0f) const override; |
| 21 | QImage getSecondaryCameraScreenshot() const override; | 21 | QImage getSecondaryCameraScreenshot() const override; |
| 22 | void copyTextureToQuickFramebuffer(NetworkTexturePointer source, QOpenGLFramebufferObject* target, GLsync* fenceSync) override {}; | 22 | void copyTextureToQuickFramebuffer(NetworkTexturePointer source, QOpenGLFramebufferObject* target, GLsync* fenceSync) override {}; |
| 23 | void pluginUpdate() override {}; | ||
| 23 | private: | 24 | private: |
| 24 | static const QString NAME; | 25 | static const QString NAME; |
| 25 | }; | 26 | }; |
| @@ -46,6 +46,8 @@ public: · 45 unmodified lines | |||
| 46 | 46 | ||
| 47 | virtual bool onDisplayTextureReset() override { _clearPreviewFlag = true; return true; }; | 47 | virtual bool onDisplayTextureReset() override { _clearPreviewFlag = true; return true; }; |
| 48 | 48 | ||
| 49 | void pluginUpdate() override {}; | ||
| 50 | |||
| 49 | signals: | 51 | signals: |
| 50 | void hmdMountedChanged(); | 52 | void hmdMountedChanged(); |
| 51 | void hmdVisibleChanged(bool visible); | 53 | void hmdVisibleChanged(bool visible); |
| @@ -28,6 +28,8 @@ public: · 27 unmodified lines | |||
| 28 | // to the HMD plugins. | 28 | // to the HMD plugins. |
| 29 | //virtual glm::mat4 getEyeToHeadTransform(Eye eye) const override; | 29 | //virtual glm::mat4 getEyeToHeadTransform(Eye eye) const override; |
| 30 | 30 | ||
| 31 | virtual void pluginUpdate() override {}; | ||
| 32 | |||
| 31 | protected: | 33 | protected: |
| 32 | virtual bool internalActivate() override; | 34 | virtual bool internalActivate() override; |
| 33 | virtual void internalDeactivate() override; | 35 | virtual void internalDeactivate() override; |
| @@ -588,6 +588,29 @@ void AccountManager::requestAccessTokenWithSteam(QByteArray authSessionTicket) { · 587 unmodified lines | |||
| 588 | connect(requestReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(requestAccessTokenError(QNetworkReply::NetworkError))); | 588 | connect(requestReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(requestAccessTokenError(QNetworkReply::NetworkError))); |
| 589 | } | 589 | } |
| 590 | 590 | ||
| 591 | void AccountManager::requestAccessTokenWithOculus(const QString& nonce, const QString &oculusID) { | ||
| 592 | QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); | ||
| 593 | |||
| 594 | QNetworkRequest request; | ||
| 595 | request.setHeader(QNetworkRequest::UserAgentHeader, _userAgentGetter()); | ||
| 596 | |||
| 597 | QUrl grantURL = _authURL; | ||
| 598 | grantURL.setPath("/oauth/token"); | ||
| 599 | |||
| 600 | QByteArray postData; | ||
| 601 | postData.append("grant_type=password&"); | ||
| 602 | postData.append("oculus_nonce=" + nonce + "&"); | ||
| 603 | postData.append("oculus_id=" + oculusID + "&"); | ||
| 604 | postData.append("scope=" + ACCOUNT_MANAGER_REQUESTED_SCOPE); | ||
| 605 | |||
| 606 | request.setUrl(grantURL); | ||
| 607 | request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); | ||
| 608 | |||
| 609 | QNetworkReply* requestReply = networkAccessManager.post(request, postData); | ||
| 610 | connect(requestReply, &QNetworkReply::finished, this, &AccountManager::requestAccessTokenFinished); | ||
| 611 | connect(requestReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(requestAccessTokenError(QNetworkReply::NetworkError))); | ||
| 612 | } | ||
| 613 | |||
| 591 | void AccountManager::refreshAccessToken() { | 614 | void AccountManager::refreshAccessToken() { |
| 592 | 615 | ||
| 593 | // we can't refresh our access token if we don't have a refresh token, so check for that first | 616 | // we can't refresh our access token if we don't have a refresh token, so check for that first |
| @@ -106,6 +106,7 @@ public: · 105 unmodified lines | |||
| 106 | public slots: | 106 | public slots: |
| 107 | void requestAccessToken(const QString& login, const QString& password); | 107 | void requestAccessToken(const QString& login, const QString& password); |
| 108 | void requestAccessTokenWithSteam(QByteArray authSessionTicket); | 108 | void requestAccessTokenWithSteam(QByteArray authSessionTicket); |
| 109 | void requestAccessTokenWithOculus(const QString& nonce, const QString& oculusID); | ||
| 109 | void requestAccessTokenWithAuthCode(const QString& authCode, | 110 | void requestAccessTokenWithAuthCode(const QString& authCode, |
| 110 | const QString& clientId, | 111 | const QString& clientId, |
| 111 | const QString& clientSecret, | 112 | const QString& clientSecret, |
| @@ -217,6 +217,9 @@ public: · 216 unmodified lines | |||
| 217 | 217 | ||
| 218 | static const QString& MENU_PATH(); | 218 | static const QString& MENU_PATH(); |
| 219 | 219 | ||
| 220 | // for updating plugin-related commands. Mimics the input plugin. | ||
| 221 | virtual void pluginUpdate() = 0; | ||
| 222 | |||
| 220 | signals: | 223 | signals: |
| 221 | void recommendedFramebufferSizeChanged(const QSize& size); | 224 | void recommendedFramebufferSizeChanged(const QSize& size); |
| 222 | void resetSensorsRequested(); | 225 | void resetSensorsRequested(); |
| @@ -21,6 +21,7 @@ class DisplayPlugin; · 20 unmodified lines | |||
| 21 | class InputPlugin; | 21 | class InputPlugin; |
| 22 | class CodecPlugin; | 22 | class CodecPlugin; |
| 23 | class SteamClientPlugin; | 23 | class SteamClientPlugin; |
| 24 | class OculusPlatformPlugin; | ||
| 24 | class Plugin; | 25 | class Plugin; |
| 25 | class PluginContainer; | 26 | class PluginContainer; |
| 26 | class PluginManager; | 27 | class PluginManager; |
| @@ -35,4 +36,5 @@ using CodecPluginPointer = std::shared_ptr<CodecPlugin>; · 8 unmodified lines | |||
| 35 | using CodecPluginList = std::vector<CodecPluginPointer>; | 36 | using CodecPluginList = std::vector<CodecPluginPointer>; |
| 36 | using CodecPluginProvider = std::function<CodecPluginList()>; | 37 | using CodecPluginProvider = std::function<CodecPluginList()>; |
| 37 | using SteamClientPluginPointer = std::shared_ptr<SteamClientPlugin>; | 38 | using SteamClientPluginPointer = std::shared_ptr<SteamClientPlugin>; |
| 39 | using OculusPlatformPluginPointer = std::shared_ptr<OculusPlatformPlugin>; | ||
| 38 | using InputPluginSettingsPersister = std::function<void(const InputPluginList&)>; | 40 | using InputPluginSettingsPersister = std::function<void(const InputPluginList&)>; |
| @@ -0,0 +1,28 @@ | |||
| 1 | // | ||
| 2 | // Created by Wayne Chen on 2018/12/20 | ||
| 3 | // Copyright 2018 High Fidelity Inc. | ||
| 4 | // | ||
| 5 | // Distributed under the Apache License, Version 2.0. | ||
| 6 | // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2-0.html | ||
| 7 | // | ||
| 8 | #pragma once | ||
| 9 | |||
| 10 | #include <QtCore/QString> | ||
| 11 | |||
| 12 | #include <functional> | ||
| 13 | |||
| 14 | using NonceUserIDCallback = std::function<void(QString, QString)>; | ||
| 15 | |||
| 16 | class OculusPlatformPlugin { | ||
| 17 | public: | ||
| 18 | virtual ~OculusPlatformPlugin() = default; | ||
| 19 | |||
| 20 | virtual QString getName() const = 0; | ||
| 21 | virtual QString getOculusUserID() const = 0; | ||
| 22 | |||
| 23 | virtual bool isRunning() const = 0; | ||
| 24 | |||
| 25 | virtual void requestNonceAndUserID(NonceUserIDCallback callback) = 0; | ||
| 26 | |||
| 27 | virtual void handleOVREvents() = 0; | ||
| 28 | }; | ||
| @@ -188,6 +188,22 @@ const SteamClientPluginPointer PluginManager::getSteamClientPlugin() { · 187 unmodified lines | |||
| 188 | return steamClientPlugin; | 188 | return steamClientPlugin; |
| 189 | } | 189 | } |
| 190 | 190 | ||
| 191 | const OculusPlatformPluginPointer PluginManager::getOculusPlatformPlugin() { | ||
| 192 | static OculusPlatformPluginPointer oculusPlatformPlugin; | ||
| 193 | static std::once_flag once; | ||
| 194 | std::call_once(once, [&] { | ||
| 195 | // Now grab the dynamic plugins | ||
| 196 | for (auto loader : getLoadedPlugins()) { | ||
| 197 | OculusPlatformProvider* oculusPlatformProvider = qobject_cast<OculusPlatformProvider*>(loader->instance()); | ||
| 198 | if (oculusPlatformProvider) { | ||
| 199 | oculusPlatformPlugin = oculusPlatformProvider->getOculusPlatformPlugin(); | ||
| 200 | break; | ||
| 201 | } | ||
| 202 | } | ||
| 203 | }); | ||
| 204 | return oculusPlatformPlugin; | ||
| 205 | } | ||
| 206 | |||
| 191 | const DisplayPluginList& PluginManager::getDisplayPlugins() { | 207 | const DisplayPluginList& PluginManager::getDisplayPlugins() { |
| 192 | static std::once_flag once; | 208 | static std::once_flag once; |
| 193 | static auto deviceAddedCallback = [](QString deviceName) { | 209 | static auto deviceAddedCallback = [](QString deviceName) { |
| @@ -27,6 +27,7 @@ public: · 26 unmodified lines | |||
| 27 | const InputPluginList& getInputPlugins(); | 27 | const InputPluginList& getInputPlugins(); |
| 28 | const CodecPluginList& getCodecPlugins(); | 28 | const CodecPluginList& getCodecPlugins(); |
| 29 | const SteamClientPluginPointer getSteamClientPlugin(); | 29 | const SteamClientPluginPointer getSteamClientPlugin(); |
| 30 | const OculusPlatformPluginPointer getOculusPlatformPlugin(); | ||
| 30 | 31 | ||
| 31 | DisplayPluginList getPreferredDisplayPlugins(); | 32 | DisplayPluginList getPreferredDisplayPlugins(); |
| 32 | void setPreferredDisplayPlugins(const QStringList& displays); | 33 | void setPreferredDisplayPlugins(const QStringList& displays); |
| @@ -51,5 +51,13 @@ public: · 50 unmodified lines | |||
| 51 | virtual SteamClientPluginPointer getSteamClientPlugin() = 0; | 51 | virtual SteamClientPluginPointer getSteamClientPlugin() = 0; |
| 52 | }; | 52 | }; |
| 53 | 53 | ||
| 54 | class OculusPlatformProvider { | ||
| 55 | public: | ||
| 56 | virtual OculusPlatformPluginPointer getOculusPlatformPlugin() = 0; | ||
| 57 | }; | ||
| 58 | |||
| 54 | #define SteamClientProvider_iid "com.highfidelity.plugins.steamclient" | 59 | #define SteamClientProvider_iid "com.highfidelity.plugins.steamclient" |
| 55 | Q_DECLARE_INTERFACE(SteamClientProvider, SteamClientProvider_iid) | 60 | Q_DECLARE_INTERFACE(SteamClientProvider, SteamClientProvider_iid) |
| 61 | |||
| 62 | #define OculusPlatformProvider_iid "com.highfidelity.plugins.oculusplatform" | ||
| 63 | Q_DECLARE_INTERFACE(OculusPlatformProvider, OculusPlatformProvider_iid) | ||
| @@ -12,6 +12,7 @@ · 11 unmodified lines | |||
| 12 | #include <display-plugins/CompositorHelper.h> | 12 | #include <display-plugins/CompositorHelper.h> |
| 13 | #include <gpu/Frame.h> | 13 | #include <gpu/Frame.h> |
| 14 | #include <gl/Config.h> | 14 | #include <gl/Config.h> |
| 15 | #include <shared/GlobalAppProperties.h> | ||
| 15 | 16 | ||
| 16 | #include "OculusHelpers.h" | 17 | #include "OculusHelpers.h" |
| 17 | 18 | ||
| @@ -30,7 +31,7 @@ bool OculusBaseDisplayPlugin::beginFrameRender(uint32_t frameIndex) { · 12 unmodified lines | |||
| 30 | return false; | 31 | return false; |
| 31 | } | 32 | } |
| 32 | 33 | ||
| 33 | if (ovr::quitRequested(status) || ovr::displayLost(status) || !ovr::handleOVREvents()) { | 34 | if (ovr::quitRequested(status) || ovr::displayLost(status)) { |
| 34 | QMetaObject::invokeMethod(qApp, "quit"); | 35 | QMetaObject::invokeMethod(qApp, "quit"); |
| 35 | return false; | 36 | return false; |
| 36 | } | 37 | } |
| @@ -13,6 +13,9 @@ · 12 unmodified lines | |||
| 13 | 13 | ||
| 14 | #include <OVR_CAPI_GL.h> | 14 | #include <OVR_CAPI_GL.h> |
| 15 | 15 | ||
| 16 | #define OVRPL_DISABLED | ||
| 17 | #include <OVR_Platform.h> | ||
| 18 | |||
| 16 | class OculusBaseDisplayPlugin : public HmdDisplayPlugin { | 19 | class OculusBaseDisplayPlugin : public HmdDisplayPlugin { |
| 17 | using Parent = HmdDisplayPlugin; | 20 | using Parent = HmdDisplayPlugin; |
| 18 | public: | 21 | public: |
| @@ -30,7 +33,7 @@ public: · 11 unmodified lines | |||
| 30 | 33 | ||
| 31 | QRectF getPlayAreaRect() override; | 34 | QRectF getPlayAreaRect() override; |
| 32 | QVector<glm::vec3> getSensorPositions() override; | 35 | QVector<glm::vec3> getSensorPositions() override; |
| 33 | 36 | ||
| 34 | protected: | 37 | protected: |
| 35 | void customizeContext() override; | 38 | void customizeContext() override; |
| 36 | void uncustomizeContext() override; | 39 | void uncustomizeContext() override; |
| @@ -296,34 +296,3 @@ controller::Pose hifi::ovr::toControllerPose(ovrHandType hand, · 295 unmodified lines | |||
| 296 | pose.valid = true; | 296 | pose.valid = true; |
| 297 | return pose; | 297 | return pose; |
| 298 | } | 298 | } |
| 299 | |||
| 300 | bool hifi::ovr::handleOVREvents() { | ||
| 301 | #ifdef OCULUS_APP_ID | ||
| 302 | if (qApp->property(hifi::properties::OCULUS_STORE).toBool()) { | ||
| 303 | // pop messages to see if we got a return for an entitlement check | ||
| 304 | ovrMessageHandle message = ovr_PopMessage(); | ||
| 305 | |||
| 306 | while (message) { | ||
| 307 | switch (ovr_Message_GetType(message)) { | ||
| 308 | case ovrMessage_Entitlement_GetIsViewerEntitled: { | ||
| 309 | if (!ovr_Message_IsError(message)) { | ||
| 310 | // this viewer is entitled, no need to flag anything | ||
| 311 | qCDebug(oculusLog) << "Oculus Platform entitlement check succeeded, proceeding normally"; | ||
| 312 | } else { | ||
| 313 | // we failed the entitlement check, quit | ||
| 314 | qCDebug(oculusLog) << "Oculus Platform entitlement check failed, app will now quit" << OCULUS_APP_ID; | ||
| 315 | return false; | ||
| 316 | } | ||
| 317 | } | ||
| 318 | } | ||
| 319 | |||
| 320 | // free the message handle to cleanup and not leak | ||
| 321 | ovr_FreeMessage(message); | ||
| 322 | |||
| 323 | // pop the next message to check, if there is one | ||
| 324 | message = ovr_PopMessage(); | ||
| 325 | } | ||
| 326 | } | ||
| 327 | #endif | ||
| 328 | return true; | ||
| 329 | } | ||
| @@ -30,7 +30,6 @@ struct ovr { · 29 unmodified lines | |||
| 30 | static ovrSessionStatus getStatus(ovrResult& result); | 30 | static ovrSessionStatus getStatus(ovrResult& result); |
| 31 | static ovrTrackingState getTrackingState(double absTime = 0.0, ovrBool latencyMarker = ovrFalse); | 31 | static ovrTrackingState getTrackingState(double absTime = 0.0, ovrBool latencyMarker = ovrFalse); |
| 32 | static QString getError(); | 32 | static QString getError(); |
| 33 | static bool handleOVREvents(); | ||
| 34 | 33 | ||
| 35 | static inline bool quitRequested() { return quitRequested(getStatus()); } | 34 | static inline bool quitRequested() { return quitRequested(getStatus()); } |
| 36 | static inline bool reorientRequested() { return reorientRequested(getStatus()); } | 35 | static inline bool reorientRequested() { return reorientRequested(getStatus()); } |
| @@ -0,0 +1,109 @@ | |||
| 1 | // | ||
| 2 | // Created by Wayne Chen on 2019/01/08 | ||
| 3 | // Copyright 2019 High Fidelity, Inc. | ||
| 4 | // | ||
| 5 | // Distributed under the Apache License, Version 2.0. | ||
| 6 | // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html | ||
| 7 | // | ||
| 8 | |||
| 9 | #include "OculusPlatformPlugin.h" | ||
| 10 | |||
| 11 | #include <shared/GlobalAppProperties.h> | ||
| 12 | |||
| 13 | #include <QMetaObject> | ||
| 14 | |||
| 15 | #include "OculusHelpers.h" | ||
| 16 | |||
| 17 | QString OculusAPIPlugin::NAME { "Oculus Rift" }; | ||
| 18 | |||
| 19 | OculusAPIPlugin::OculusAPIPlugin() { | ||
| 20 | _session = hifi::ovr::acquireRenderSession(); | ||
| 21 | } | ||
| 22 | |||
| 23 | OculusAPIPlugin::~OculusAPIPlugin() { | ||
| 24 | hifi::ovr::releaseRenderSession(_session); | ||
| 25 | } | ||
| 26 | |||
| 27 | bool OculusAPIPlugin::isRunning() const { | ||
| 28 | return (qApp->property(hifi::properties::OCULUS_STORE).toBool()); | ||
| 29 | } | ||
| 30 | |||
| 31 | void OculusAPIPlugin::requestNonceAndUserID(NonceUserIDCallback callback) { | ||
| 32 | #ifdef OCULUS_APP_ID | ||
| 33 | _nonceUserIDCallback = callback; | ||
| 34 | ovr_User_GetUserProof(); | ||
| 35 | ovr_User_GetLoggedInUser(); | ||
| 36 | #endif | ||
| 37 | } | ||
| 38 | |||
| 39 | void OculusAPIPlugin::handleOVREvents() { | ||
| 40 | #ifdef OCULUS_APP_ID | ||
| 41 | if (qApp->property(hifi::properties::OCULUS_STORE).toBool()) { | ||
| 42 | // pop messages to see if we got a return for an entitlement check | ||
| 43 | ovrMessageHandle message { nullptr }; | ||
| 44 | |||
| 45 | // pop the next message to check, if there is one | ||
| 46 | while ((message = ovr_PopMessage())) { | ||
| 47 | switch (ovr_Message_GetType(message)) { | ||
| 48 | case ovrMessage_Entitlement_GetIsViewerEntitled: { | ||
| 49 | if (!ovr_Message_IsError(message)) { | ||
| 50 | // this viewer is entitled, no need to flag anything | ||
| 51 | qCDebug(oculusLog) << "Oculus Platform entitlement check succeeded, proceeding normally"; | ||
| 52 | } else { | ||
| 53 | // we failed the entitlement check, quit | ||
| 54 | qCDebug(oculusLog) << "Oculus Platform entitlement check failed, app will now quit" << OCULUS_APP_ID; | ||
| 55 | QMetaObject::invokeMethod(qApp, "quit"); | ||
| 56 | } | ||
| 57 | break; | ||
| 58 | } | ||
| 59 | case ovrMessage_User_Get: { | ||
| 60 | if (!ovr_Message_IsError(message)) { | ||
| 61 | qCDebug(oculusLog) << "Oculus Platform user retrieval succeeded"; | ||
| 62 | ovrUserHandle user = ovr_Message_GetUser(message); | ||
| 63 | _user = ovr_User_GetOculusID(user); | ||
| 64 | // went all the way through the `requestNonceAndUserID()` pipeline successfully. | ||
| 65 | } else { | ||
| 66 | qCDebug(oculusLog) << "Oculus Platform user retrieval failed" << QString(ovr_Error_GetMessage(ovr_Message_GetError(message))); | ||
| 67 | // emit the signal so we don't hang for it anywhere else. | ||
| 68 | _user = ""; | ||
| 69 | } | ||
| 70 | break; | ||
| 71 | } | ||
| 72 | case ovrMessage_User_GetLoggedInUser: { | ||
| 73 | if (!ovr_Message_IsError(message)) { | ||
| 74 | ovrUserHandle user = ovr_Message_GetUser(message); | ||
| 75 | _userID = ovr_User_GetID(user); | ||
| 76 | ovr_User_Get(_userID); | ||
| 77 | } else { | ||
| 78 | qCDebug(oculusLog) << "Oculus Platform user ID retrieval failed" << QString(ovr_Error_GetMessage(ovr_Message_GetError(message))); | ||
| 79 | // emit the signal so we don't hang for it anywhere else. | ||
| 80 | } | ||
| 81 | _userIDChanged = true; | ||
| 82 | break; | ||
| 83 | } | ||
| 84 | case ovrMessage_User_GetUserProof: { | ||
| 85 | if (!ovr_Message_IsError(message)) { | ||
| 86 | ovrUserProofHandle userProof = ovr_Message_GetUserProof(message); | ||
| 87 | _nonce = ovr_UserProof_GetNonce(userProof); | ||
| 88 | qCDebug(oculusLog) << "Oculus Platform nonce retrieval succeeded: " << _nonce; | ||
| 89 | } else { | ||
| 90 | qCDebug(oculusLog) << "Oculus Platform nonce retrieval failed" << QString(ovr_Error_GetMessage(ovr_Message_GetError(message))); | ||
| 91 | _nonce = ""; | ||
| 92 | // emit the signal so we don't hang for it anywhere else. | ||
| 93 | } | ||
| 94 | _nonceChanged = true; | ||
| 95 | break; | ||
| 96 | } | ||
| 97 | } | ||
| 98 | |||
| 99 | if (_nonceChanged && _userIDChanged) { | ||
| 100 | _nonceUserIDCallback(_nonce, QString::number(_userID)); | ||
| 101 | _nonceChanged = _userIDChanged = false; | ||
| 102 | } | ||
| 103 | |||
| 104 | // free the message handle to cleanup and not leak | ||
| 105 | ovr_FreeMessage(message); | ||
| 106 | } | ||
| 107 | } | ||
| 108 | #endif | ||
| 109 | } | ||
| @@ -0,0 +1,39 @@ | |||
| 1 | // | ||
| 2 | // Created by Wayne Chen on 2019/01/08 | ||
| 3 | // Copyright 2019 High Fidelity, Inc. | ||
| 4 | // | ||
| 5 | // Distributed under the Apache License, Version 2.0. | ||
| 6 | // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html | ||
| 7 | // | ||
| 8 | #pragma once | ||
| 9 | |||
| 10 | #include <plugins/OculusPlatformPlugin.h> | ||
| 11 | |||
| 12 | #include <OVR_CAPI_GL.h> | ||
| 13 | |||
| 14 | #define OVRPL_DISABLED | ||
| 15 | #include <OVR_Platform.h> | ||
| 16 | |||
| 17 | class OculusAPIPlugin : public OculusPlatformPlugin { | ||
| 18 | public: | ||
| 19 | OculusAPIPlugin(); | ||
| 20 | virtual ~OculusAPIPlugin(); | ||
| 21 | QString getName() const { return NAME; } | ||
| 22 | QString getOculusUserID() const { return _user; }; | ||
| 23 | |||
| 24 | bool isRunning() const; | ||
| 25 | |||
| 26 | virtual void requestNonceAndUserID(NonceUserIDCallback callback); | ||
| 27 | |||
| 28 | virtual void handleOVREvents(); | ||
| 29 | |||
| 30 | private: | ||
| 31 | static QString NAME; | ||
| 32 | NonceUserIDCallback _nonceUserIDCallback; | ||
| 33 | QString _nonce; | ||
| 34 | bool _nonceChanged{ false }; | ||
| 35 | bool _userIDChanged{ false }; | ||
| 36 | QString _user; | ||
| 37 | ovrID _userID; | ||
| 38 | ovrSession _session; | ||
| 39 | }; | ||
| @@ -18,15 +18,18 @@ · 17 unmodified lines | |||
| 18 | 18 | ||
| 19 | #include "OculusDisplayPlugin.h" | 19 | #include "OculusDisplayPlugin.h" |
| 20 | #include "OculusDebugDisplayPlugin.h" | 20 | #include "OculusDebugDisplayPlugin.h" |
| 21 | #include "OculusPlatformPlugin.h" | ||
| 21 | #include "OculusControllerManager.h" | 22 | #include "OculusControllerManager.h" |
| 22 | 23 | ||
| 23 | class OculusProvider : public QObject, public DisplayProvider, InputProvider | 24 | class OculusProvider : public QObject, public DisplayProvider, InputProvider, OculusPlatformProvider |
| 24 | { | 25 | { |
| 25 | Q_OBJECT | 26 | Q_OBJECT |
| 26 | Q_PLUGIN_METADATA(IID DisplayProvider_iid FILE "oculus.json") | 27 | Q_PLUGIN_METADATA(IID DisplayProvider_iid FILE "oculus.json") |
| 27 | Q_INTERFACES(DisplayProvider) | 28 | Q_INTERFACES(DisplayProvider) |
| 28 | Q_PLUGIN_METADATA(IID InputProvider_iid FILE "oculus.json") | 29 | Q_PLUGIN_METADATA(IID InputProvider_iid FILE "oculus.json") |
| 29 | Q_INTERFACES(InputProvider) | 30 | Q_INTERFACES(InputProvider) |
| 31 | Q_PLUGIN_METADATA(IID OculusPlatformProvider_iid FILE "oculus.json") | ||
| 32 | Q_INTERFACES(OculusPlatformProvider) | ||
| 30 | 33 | ||
| 31 | public: | 34 | public: |
| 32 | OculusProvider(QObject* parent = nullptr) : QObject(parent) {} | 35 | OculusProvider(QObject* parent = nullptr) : QObject(parent) {} |
| @@ -62,6 +65,15 @@ public: · 29 unmodified lines | |||
| 62 | return _inputPlugins; | 65 | return _inputPlugins; |
| 63 | } | 66 | } |
| 64 | 67 | ||
| 68 | virtual OculusPlatformPluginPointer getOculusPlatformPlugin() override { | ||
| 69 | static std::once_flag once; | ||
| 70 | std::call_once(once, [&] { | ||
| 71 | _oculusPlatformPlugin = std::make_shared<OculusAPIPlugin>(); | ||
| 72 | |||
| 73 | }); | ||
| 74 | return _oculusPlatformPlugin; | ||
| 75 | } | ||
| 76 | |||
| 65 | virtual void destroyInputPlugins() override { | 77 | virtual void destroyInputPlugins() override { |
| 66 | _inputPlugins.clear(); | 78 | _inputPlugins.clear(); |
| 67 | } | 79 | } |
| @@ -73,6 +85,7 @@ public: · 5 unmodified lines | |||
| 73 | private: | 85 | private: |
| 74 | DisplayPluginList _displayPlugins; | 86 | DisplayPluginList _displayPlugins; |
| 75 | InputPluginList _inputPlugins; | 87 | InputPluginList _inputPlugins; |
| 88 | OculusPlatformPluginPointer _oculusPlatformPlugin; | ||
| 76 | }; | 89 | }; |
| 77 | 90 | ||
| 78 | #include "OculusProvider.moc" | 91 | #include "OculusProvider.moc" |