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);
 });