From 880bcf3b1ee2558c8053d66615d28f232118977c Mon Sep 17 00:00:00 2001 From: Zach Fox <fox@highfidelity.io> Date: Fri, 21 Apr 2017 15:42:41 -0700 Subject: [PATCH] Checkpoint --- .../src/scripting/WindowScriptingInterface.h | 2 +- interface/src/ui/SnapshotUploader.cpp | 15 +- scripts/system/html/js/SnapshotReview.js | 31 +++- scripts/system/snapshot.js | 138 ++++++++++++------ 4 files changed, 133 insertions(+), 53 deletions(-) diff --git a/interface/src/scripting/WindowScriptingInterface.h b/interface/src/scripting/WindowScriptingInterface.h index eb7dc02627..7641110972 100644 --- a/interface/src/scripting/WindowScriptingInterface.h +++ b/interface/src/scripting/WindowScriptingInterface.h @@ -74,7 +74,7 @@ signals: void svoImportRequested(const QString& url); void domainConnectionRefused(const QString& reasonMessage, int reasonCode, const QString& extraInfo); void stillSnapshotTaken(const QString& pathStillSnapshot, bool notify); - void snapshotShared(const QString& error); + void snapshotShared(bool isError, const QString& reply); void processingGifStarted(const QString& pathStillSnapshot); void processingGifCompleted(const QString& pathAnimatedSnapshot); diff --git a/interface/src/ui/SnapshotUploader.cpp b/interface/src/ui/SnapshotUploader.cpp index 411e892de5..54faa822b8 100644 --- a/interface/src/ui/SnapshotUploader.cpp +++ b/interface/src/ui/SnapshotUploader.cpp @@ -49,6 +49,7 @@ void SnapshotUploader::uploadSuccess(QNetworkReply& reply) { userStoryObject.insert("place_name", placeName); userStoryObject.insert("path", currentPath); userStoryObject.insert("action", "snapshot"); + userStoryObject.insert("audience", "for_url"); rootObject.insert("user_story", userStoryObject); auto accountManager = DependencyManager::get<AccountManager>(); @@ -61,7 +62,7 @@ void SnapshotUploader::uploadSuccess(QNetworkReply& reply) { QJsonDocument(rootObject).toJson()); } else { - emit DependencyManager::get<WindowScriptingInterface>()->snapshotShared(contents); + emit DependencyManager::get<WindowScriptingInterface>()->snapshotShared(true, contents); delete this; } } @@ -72,12 +73,18 @@ void SnapshotUploader::uploadFailure(QNetworkReply& reply) { if (replyString.size() == 0) { replyString = reply.errorString(); } - emit DependencyManager::get<WindowScriptingInterface>()->snapshotShared(replyString); // maybe someday include _inWorldLocation, _filename? + emit DependencyManager::get<WindowScriptingInterface>()->snapshotShared(true, replyString); // maybe someday include _inWorldLocation, _filename? delete this; } void SnapshotUploader::createStorySuccess(QNetworkReply& reply) { - emit DependencyManager::get<WindowScriptingInterface>()->snapshotShared(QString()); + QString replyString = reply.readAll(); + // oh no QT pls + // let's write our own JSON parser??? + QJsonDocument jsonResponse = QJsonDocument::fromJson(replyString.toUtf8()); + QJsonObject object = jsonResponse.object()["user_story"].toObject(); + QString storyId = QString::number(object["id"].toInt()); + emit DependencyManager::get<WindowScriptingInterface>()->snapshotShared(false, storyId); delete this; } @@ -87,7 +94,7 @@ void SnapshotUploader::createStoryFailure(QNetworkReply& reply) { if (replyString.size() == 0) { replyString = reply.errorString(); } - emit DependencyManager::get<WindowScriptingInterface>()->snapshotShared(replyString); + emit DependencyManager::get<WindowScriptingInterface>()->snapshotShared(true, replyString); delete this; } diff --git a/scripts/system/html/js/SnapshotReview.js b/scripts/system/html/js/SnapshotReview.js index 8fffd207ff..042bc55fb5 100644 --- a/scripts/system/html/js/SnapshotReview.js +++ b/scripts/system/html/js/SnapshotReview.js @@ -11,7 +11,7 @@ // var paths = [], idCounter = 0, imageCount = 1; -function addImage(data) { +function addImage(data, isGifLoading) { if (!data.localPath) { return; } @@ -38,12 +38,14 @@ function addImage(data) { img.onload = function () { var shareBar = document.getElementById(id + "shareBar"); shareBar.style.width = img.clientWidth; - shareBar.style.display = "inline"; document.getElementById(id).style.height = img.clientHeight; } } paths.push(data.localPath); + if (!isGifLoading) { + shareForUrl(id); + } } function createShareOverlay(parentID, isGif) { var shareOverlayContainer = document.createElement("DIV"); @@ -99,7 +101,7 @@ function createShareOverlay(parentID, isGif) { '<br/>' + '<div class="shareControls">' + '<div class="hifiShareControls">' + - '<input type="button" class="shareWithEveryone" id="' + shareWithEveryoneButtonID + '" value="SHARE WITH EVERYONE" onclick="shareWithEveryone(parentID)" /><br>' + + '<input type="button" class="shareWithEveryone" id="' + shareWithEveryoneButtonID + '" value="SHARE WITH EVERYONE" onclick="shareWithEveryone(' + parentID + ')" /><br>' + '<input type="checkbox" class="inviteConnections" id="' + inviteConnectionsCheckboxID + '" checked="checked" />' + '<label class="shareButtonLabel" for="' + inviteConnectionsCheckboxID + '">Invite My Connections</label><br>' + '<input type="button" class="cancelShare" value="CANCEL" onclick="cancelSharing(' + parentID + ')" />' + @@ -129,12 +131,19 @@ function selectImageToShare(selectedID) { shareOverlayBackground.style.display = "inline"; shareOverlay.style.display = "inline"; } +function shareForUrl(selectedID) { + EventBridge.emitWebEvent(JSON.stringify({ + type: "snapshot", + action: "shareSnapshotForUrl", + data: paths[parseInt(selectedID.substring(1))] + })); +} function shareWithEveryone(selectedID) { selectedID = selectedID.id; // Why is this necessary? EventBridge.emitWebEvent(JSON.stringify({ type: "snapshot", - action: "shareSnapshot", + action: "shareSnapshotWithEveryone", data: paths[parseInt(selectedID.substring(1))] })); } @@ -204,7 +213,9 @@ window.onload = function () { if (messageOptions.processingGif) { imageCount = message.data.length + 1; // "+1" for the GIF that'll finish processing soon message.data.unshift({ localPath: messageOptions.loadingGifPath }); - message.data.forEach(addImage); + message.data.forEach(function (element, idx, array) { + addImage(element, idx === 0); + }); } else { var gifPath = message.data[0].localPath; var p0img = document.getElementById('p0img'); @@ -213,20 +224,26 @@ window.onload = function () { p0img.onload = function () { var shareBar = document.getElementById("p0shareBar"); shareBar.style.width = p0img.clientWidth; - shareBar.style.display = "inline"; document.getElementById('p0').style.height = p0img.clientHeight; } paths[0] = gifPath; + shareForUrl("p0"); } } else { imageCount = message.data.length; - message.data.forEach(addImage); + message.data.forEach(function (element, idx, array) { + addImage(element, false); + }); } break; case 'captureSettings': handleCaptureSetting(message.setting); break; + case 'enableShareButtons': + var shareBar = document.getElementById("p0shareBar"); + shareBar.style.display = "inline"; + break; default: print("Unknown message action received in SnapshotReview.js."); break; diff --git a/scripts/system/snapshot.js b/scripts/system/snapshot.js index 7f71336dcf..37f3070dc0 100644 --- a/scripts/system/snapshot.js +++ b/scripts/system/snapshot.js @@ -28,25 +28,61 @@ var button = tablet.addButton({ sortOrder: 5 }); -function shouldOpenFeedAfterShare() { - var persisted = Settings.getValue('openFeedAfterShare', true); // might answer true, false, "true", or "false" - return persisted && (persisted !== 'false'); -} -function showFeedWindow() { - if ((HMD.active && Settings.getValue("hmdTabletBecomesToolbar")) - || (!HMD.active && Settings.getValue("desktopTabletBecomesToolbar"))) { - tablet.loadQMLSource("TabletAddressDialog.qml"); - } else { - tablet.initialScreen("TabletAddressDialog.qml"); - HMD.openTablet(); - } -} - -var outstanding; var snapshotOptions; var imageData; var shareAfterLogin = false; -var snapshotToShareAfterLogin; +var snapshotToShareAfterLogin; +var METAVERSE_BASE = location.metaverseServerUrl; + +function request(options, callback) { // cb(error, responseOfCorrectContentType) of url. A subset of npm request. + var httpRequest = new XMLHttpRequest(), key; + // QT bug: apparently doesn't handle onload. Workaround using readyState. + httpRequest.onreadystatechange = function () { + var READY_STATE_DONE = 4; + var HTTP_OK = 200; + if (httpRequest.readyState >= READY_STATE_DONE) { + var error = (httpRequest.status !== HTTP_OK) && httpRequest.status.toString() + ':' + httpRequest.statusText, + response = !error && httpRequest.responseText, + contentType = !error && httpRequest.getResponseHeader('content-type'); + if (!error && contentType.indexOf('application/json') === 0) { // ignoring charset, etc. + try { + response = JSON.parse(response); + } catch (e) { + error = e; + } + } + callback(error, response); + } + }; + if (typeof options === 'string') { + options = { uri: options }; + } + if (options.url) { + options.uri = options.url; + } + if (!options.method) { + options.method = 'GET'; + } + if (options.body && (options.method === 'GET')) { // add query parameters + var params = [], appender = (-1 === options.uri.search('?')) ? '?' : '&'; + for (key in options.body) { + params.push(key + '=' + options.body[key]); + } + options.uri += appender + params.join('&'); + delete options.body; + } + if (options.json) { + options.headers = options.headers || {}; + options.headers["Content-type"] = "application/json"; + options.body = JSON.stringify(options.body); + } + for (key in options.headers || {}) { + httpRequest.setRequestHeader(key, options.headers[key]); + } + httpRequest.open(options.method, options.uri, true); + httpRequest.send(options.body); +} + function onMessage(message) { // Receives message from the html dialog via the qwebchannel EventBridge. This is complicated by the following: // 1. Although we can send POJOs, we cannot receive a toplevel object. (Arrays of POJOs are fine, though.) @@ -73,7 +109,6 @@ function onMessage(message) { options: snapshotOptions, data: imageData })); - outstanding = 0; break; case 'openSettings': if ((HMD.active && Settings.getValue("hmdTabletBecomesToolbar")) @@ -96,18 +131,41 @@ function onMessage(message) { // onClicked(); break; - case 'shareSnapshot': + case 'shareSnapshotForUrl': isLoggedIn = Account.isLoggedIn(); - if (!isLoggedIn) { + if (isLoggedIn) { + print('Sharing snapshot with audience "for_url":', message.data); + Window.shareSnapshot(message.data, message.href || href); + } else { + // TODO? + } + break; + case 'shareSnapshotWithEveryone': + isLoggedIn = Account.isLoggedIn(); + if (isLoggedIn) { + print('sharing', message.data); + request({ + uri: METAVERSE_BASE + '/api/v1/user_stories/' + story_id, + method: 'PUT', + json: true, + body: { + audience: "for_feed", + } + }, function (error, response) { + if (error || (response.status !== 'success')) { + print("Error changing audience: ", error || response.status); + return; + } + }); + } else { + // TODO + /* needsLogin = true; shareAfterLogin = true; snapshotToShareAfterLogin = { path: message.data, href: message.href || href }; - } else { - print('sharing', message.data); - outstanding++; - Window.shareSnapshot(message.data, message.href || href); + */ } - + /* if (needsLogin) { if ((HMD.active && Settings.getValue("hmdTabletBecomesToolbar")) || (!HMD.active && Settings.getValue("desktopTabletBecomesToolbar"))) { @@ -116,7 +174,7 @@ function onMessage(message) { tablet.loadQMLOnTop("../../dialogs/TabletLoginDialog.qml"); HMD.openTablet(); } - } + }*/ break; default: print('Unknown message action received by snapshot.js!'); @@ -133,14 +191,15 @@ function reviewSnapshot() { isInSnapshotReview = true; } -function snapshotShared(errorMessage) { - if (!errorMessage) { - print('snapshot uploaded and shared'); +function snapshotUploaded(isError, reply) { + if (!isError) { + print('SUCCESS: Snapshot uploaded! Story with audience:for_url created! ID:', reply); + tablet.emitScriptEvent(JSON.stringify({ + type: "snapshot", + action: "enableShareButtons" + })); } else { - print(errorMessage); - } - if ((--outstanding <= 0) && shouldOpenFeedAfterShare()) { - showFeedWindow(); + print(reply); } } var href, domainId; @@ -213,8 +272,7 @@ function stillSnapshotTaken(pathStillSnapshot, notify) { snapshotOptions = { containsGif: false, processingGif: false, - canShare: !!isDomainOpen(domainId), - openFeedAfterShare: shouldOpenFeedAfterShare() + canShare: !!isDomainOpen(domainId) }; imageData = [{ localPath: pathStillSnapshot, href: href }]; reviewSnapshot(); @@ -241,8 +299,7 @@ function processingGifStarted(pathStillSnapshot) { containsGif: true, processingGif: true, loadingGifPath: Script.resolvePath(Script.resourcesPath() + 'icons/loadingDark.gif'), - canShare: !!isDomainOpen(domainId), - openFeedAfterShare: shouldOpenFeedAfterShare() + canShare: !!isDomainOpen(domainId) }; imageData = [{ localPath: pathStillSnapshot, href: href }]; reviewSnapshot(); @@ -262,8 +319,7 @@ function processingGifCompleted(pathAnimatedSnapshot) { snapshotOptions = { containsGif: true, processingGif: false, - canShare: !!isDomainOpen(domainId), - openFeedAfterShare: shouldOpenFeedAfterShare() + canShare: !!isDomainOpen(domainId) } imageData = [{ localPath: pathAnimatedSnapshot, href: href }]; @@ -283,7 +339,7 @@ function onTabletScreenChanged(type, url) { } function onConnected() { if (shareAfterLogin && Account.isLoggedIn()) { - print('sharing', snapshotToShareAfterLogin.path); + print('Sharing snapshot after login:', snapshotToShareAfterLogin.path); Window.shareSnapshot(snapshotToShareAfterLogin.path, snapshotToShareAfterLogin.href); shareAfterLogin = false; } @@ -291,7 +347,7 @@ function onConnected() { button.clicked.connect(onClicked); buttonConnected = true; -Window.snapshotShared.connect(snapshotShared); +Window.snapshotShared.connect(snapshotUploaded); tablet.screenChanged.connect(onTabletScreenChanged); Account.usernameChanged.connect(onConnected); Script.scriptEnding.connect(function () { @@ -302,7 +358,7 @@ Script.scriptEnding.connect(function () { if (tablet) { tablet.removeButton(button); } - Window.snapshotShared.disconnect(snapshotShared); + Window.snapshotShared.disconnect(snapshotUploaded); tablet.screenChanged.disconnect(onTabletScreenChanged); });