diff --git a/cmake/externals/GifCreator/CMakeLists.txt b/cmake/externals/GifCreator/CMakeLists.txt new file mode 100644 index 0000000000..127bdf28f5 --- /dev/null +++ b/cmake/externals/GifCreator/CMakeLists.txt @@ -0,0 +1,20 @@ +set(EXTERNAL_NAME GifCreator) + +include(ExternalProject) +ExternalProject_Add( + ${EXTERNAL_NAME} + URL https://hifi-public.s3.amazonaws.com/dependencies/GifCreator.zip + URL_MD5 8ac8ef5196f47c658dce784df5ecdb70 + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + LOG_DOWNLOAD 1 +) + +# Hide this external target (for ide users) +set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals") + +ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR) + +string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) +set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${INSTALL_DIR}/src/${EXTERNAL_NAME} CACHE PATH "List of GifCreator include directories") \ No newline at end of file diff --git a/cmake/modules/FindGifCreator.cmake b/cmake/modules/FindGifCreator.cmake new file mode 100644 index 0000000000..def9f1d131 --- /dev/null +++ b/cmake/modules/FindGifCreator.cmake @@ -0,0 +1,26 @@ +# +# FindGifCreator.cmake +# +# Try to find GifCreator include path. +# Once done this will define +# +# GIFCREATOR_INCLUDE_DIRS +# +# Created on 11/15/2016 by Zach Fox +# Copyright 2016 High Fidelity, Inc. +# +# Distributed under the Apache License, Version 2.0. +# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +# + +# setup hints for GifCreator search +include("${MACRO_DIR}/HifiLibrarySearchHints.cmake") +hifi_library_search_hints("GIFCREATOR") + +# locate header +find_path(GIFCREATOR_INCLUDE_DIRS "GifCreator/GifCreator.h" HINTS ${GIFCREATOR_SEARCH_DIRS}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(GIFCREATOR DEFAULT_MSG GIFCREATOR_INCLUDE_DIRS) + +mark_as_advanced(GIFCREATOR_INCLUDE_DIRS GIFCREATOR_SEARCH_DIRS) \ No newline at end of file diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 131c4ee509..e32df6bc62 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -351,3 +351,7 @@ if (ANDROID) qt_create_apk() endif () + +add_dependency_external_projects(GifCreator) +find_package(GifCreator REQUIRED) +target_include_directories(${TARGET_NAME} PUBLIC ${GIFCREATOR_INCLUDE_DIRS}) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 089983d8ca..82007c4f06 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -152,6 +152,7 @@ #include "ui/LoginDialog.h" #include "ui/overlays/Cube3DOverlay.h" #include "ui/Snapshot.h" +#include "ui/SnapshotAnimated.h" #include "ui/StandAloneJSConsole.h" #include "ui/Stats.h" #include "ui/UpdateDialog.h" @@ -5428,19 +5429,27 @@ void Application::toggleLogDialog() { } } -void Application::takeSnapshot(bool notify, float aspectRatio) { - postLambdaEvent([notify, aspectRatio, this] { + +void Application::takeSnapshot(bool notify, bool includeAnimated, float aspectRatio) { + postLambdaEvent([notify, includeAnimated, aspectRatio, this] { QMediaPlayer* player = new QMediaPlayer(); QFileInfo inf = QFileInfo(PathUtils::resourcesPath() + "sounds/snap.wav"); player->setMedia(QUrl::fromLocalFile(inf.absoluteFilePath())); player->play(); + // Get a screenshot and save it QString path = Snapshot::saveSnapshot(getActiveDisplayPlugin()->getScreenshot(aspectRatio)); - emit DependencyManager::get()->snapshotTaken(path, notify); + // If we're not doing an animated snapshot as well... + if (!includeAnimated || !(SnapshotAnimated::alsoTakeAnimatedSnapshot.get())) { + // Tell the dependency manager that the capture of the still snapshot has taken place. + emit DependencyManager::get()->snapshotTaken(path, "", notify); + } else { + // Get an animated GIF snapshot and save it + SnapshotAnimated::saveSnapshotAnimated(path, aspectRatio, qApp, DependencyManager::get()); + } }); } - void Application::shareSnapshot(const QString& path) { postLambdaEvent([path] { // not much to do here, everything is done in snapshot code... diff --git a/interface/src/Application.h b/interface/src/Application.h index 4c98be9c2d..8f8b42d66a 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -266,7 +266,7 @@ public: float getAvatarSimrate() const { return _avatarSimCounter.rate(); } float getAverageSimsPerSecond() const { return _simCounter.rate(); } - void takeSnapshot(bool notify, float aspectRatio = 0.0f); + void takeSnapshot(bool notify, bool includeAnimated = false, float aspectRatio = 0.0f); void shareSnapshot(const QString& filename); model::SkyboxPointer getDefaultSkybox() const { return _defaultSkybox; } diff --git a/interface/src/scripting/WindowScriptingInterface.cpp b/interface/src/scripting/WindowScriptingInterface.cpp index 0f9dd698fd..0cb574c1f6 100644 --- a/interface/src/scripting/WindowScriptingInterface.cpp +++ b/interface/src/scripting/WindowScriptingInterface.cpp @@ -199,8 +199,8 @@ void WindowScriptingInterface::copyToClipboard(const QString& text) { QApplication::clipboard()->setText(text); } -void WindowScriptingInterface::takeSnapshot(bool notify, float aspectRatio) { - qApp->takeSnapshot(notify, aspectRatio); +void WindowScriptingInterface::takeSnapshot(bool notify, bool includeAnimated, float aspectRatio) { + qApp->takeSnapshot(notify, includeAnimated, aspectRatio); } void WindowScriptingInterface::shareSnapshot(const QString& path) { diff --git a/interface/src/scripting/WindowScriptingInterface.h b/interface/src/scripting/WindowScriptingInterface.h index f4a89ae221..7246dc0927 100644 --- a/interface/src/scripting/WindowScriptingInterface.h +++ b/interface/src/scripting/WindowScriptingInterface.h @@ -52,7 +52,7 @@ public slots: QScriptValue save(const QString& title = "", const QString& directory = "", const QString& nameFilter = ""); void showAssetServer(const QString& upload = ""); void copyToClipboard(const QString& text); - void takeSnapshot(bool notify = true, float aspectRatio = 0.0f); + void takeSnapshot(bool notify = true, bool includeAnimated = false, float aspectRatio = 0.0f); void shareSnapshot(const QString& path); bool isPhysicsEnabled(); @@ -60,7 +60,7 @@ signals: void domainChanged(const QString& domainHostname); void svoImportRequested(const QString& url); void domainConnectionRefused(const QString& reasonMessage, int reasonCode, const QString& extraInfo); - void snapshotTaken(const QString& path, bool notify); + void snapshotTaken(const QString& pathStillSnapshot, const QString& pathAnimatedSnapshot, bool notify); void snapshotShared(const QString& error); private: diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index 7d3261aa78..35af1067d8 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -23,6 +23,7 @@ #include "LODManager.h" #include "Menu.h" #include "Snapshot.h" +#include "SnapshotAnimated.h" #include "UserActivityLogger.h" #include "AmbientOcclusionEffect.h" @@ -83,6 +84,20 @@ void setupPreferences() { auto preference = new BrowsePreference(SNAPSHOTS, "Put my snapshots here", getter, setter); preferences->addPreference(preference); } + { + auto getter = []()->bool { return SnapshotAnimated::alsoTakeAnimatedSnapshot.get(); }; + auto setter = [](bool value) { SnapshotAnimated::alsoTakeAnimatedSnapshot.set(value); }; + preferences->addPreference(new CheckPreference(SNAPSHOTS, "Take Animated GIF Snapshot with HUD Button", getter, setter)); + } + { + auto getter = []()->float { return SnapshotAnimated::snapshotAnimatedDuration.get(); }; + auto setter = [](float value) { SnapshotAnimated::snapshotAnimatedDuration.set(value); }; + auto preference = new SpinnerPreference(SNAPSHOTS, "Animated Snapshot Duration", getter, setter); + preference->setMin(3); + preference->setMax(10); + preference->setStep(1); + preferences->addPreference(preference); + } // Scripts { diff --git a/interface/src/ui/Snapshot.cpp b/interface/src/ui/Snapshot.cpp index 1bf5f5de4e..5df0d4575b 100644 --- a/interface/src/ui/Snapshot.cpp +++ b/interface/src/ui/Snapshot.cpp @@ -51,16 +51,24 @@ SnapshotMetaData* Snapshot::parseSnapshotData(QString snapshotPath) { return NULL; } - QImage shot(snapshotPath); + QUrl url; - // no location data stored - if (shot.text(URL).isEmpty()) { + if (snapshotPath.right(3) == "jpg") { + QImage shot(snapshotPath); + + // no location data stored + if (shot.text(URL).isEmpty()) { + return NULL; + } + + // parsing URL + url = QUrl(shot.text(URL), QUrl::ParsingMode::StrictMode); + } else if (snapshotPath.right(3) == "gif") { + url = QUrl(DependencyManager::get()->currentShareableAddress()); + } else { return NULL; } - // parsing URL - QUrl url = QUrl(shot.text(URL), QUrl::ParsingMode::StrictMode); - SnapshotMetaData* data = new SnapshotMetaData(); data->setURL(url); @@ -156,7 +164,11 @@ void Snapshot::uploadSnapshot(const QString& filename) { file->open(QIODevice::ReadOnly); QHttpPart imagePart; - imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg")); + if (filename.right(3) == "gif") { + imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/gif")); + } else { + imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg")); + } imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"image\"; filename=\"" + file->fileName() + "\"")); imagePart.setBodyDevice(file); diff --git a/interface/src/ui/SnapshotAnimated.cpp b/interface/src/ui/SnapshotAnimated.cpp new file mode 100644 index 0000000000..c8edbfc028 --- /dev/null +++ b/interface/src/ui/SnapshotAnimated.cpp @@ -0,0 +1,139 @@ +// +// SnapshotAnimated.cpp +// interface/src/ui +// +// Created by Zach Fox on 11/14/16. +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include +#include +#include +#include + +#include +#include "SnapshotAnimated.h" + +QTimer* SnapshotAnimated::snapshotAnimatedTimer = NULL; +qint64 SnapshotAnimated::snapshotAnimatedTimestamp = 0; +qint64 SnapshotAnimated::snapshotAnimatedFirstFrameTimestamp = 0; +bool SnapshotAnimated::snapshotAnimatedTimerRunning = false; +QString SnapshotAnimated::snapshotAnimatedPath; +QString SnapshotAnimated::snapshotStillPath; +QVector SnapshotAnimated::snapshotAnimatedFrameVector; +QVector SnapshotAnimated::snapshotAnimatedFrameDelayVector; +Application* SnapshotAnimated::app; +float SnapshotAnimated::aspectRatio; +QSharedPointer SnapshotAnimated::snapshotAnimatedDM; +GifWriter SnapshotAnimated::snapshotAnimatedGifWriter; + + +Setting::Handle SnapshotAnimated::alsoTakeAnimatedSnapshot("alsoTakeAnimatedSnapshot", true); +Setting::Handle SnapshotAnimated::snapshotAnimatedDuration("snapshotAnimatedDuration", SNAPSNOT_ANIMATED_DURATION_SECS); + +void SnapshotAnimated::saveSnapshotAnimated(QString pathStill, float aspectRatio, Application* app, QSharedPointer dm) { + // If we're not in the middle of capturing an animated snapshot... + if (SnapshotAnimated::snapshotAnimatedFirstFrameTimestamp == 0) { + SnapshotAnimated::snapshotAnimatedTimer = new QTimer(); + SnapshotAnimated::aspectRatio = aspectRatio; + SnapshotAnimated::app = app; + SnapshotAnimated::snapshotAnimatedDM = dm; + // Define the output location of the still and animated snapshots. + SnapshotAnimated::snapshotStillPath = pathStill; + SnapshotAnimated::snapshotAnimatedPath = pathStill; + SnapshotAnimated::snapshotAnimatedPath.replace("jpg", "gif"); + + // Ensure the snapshot timer is Precise (attempted millisecond precision) + SnapshotAnimated::snapshotAnimatedTimer->setTimerType(Qt::PreciseTimer); + + // Connect the snapshotAnimatedTimer QTimer to the lambda slot function + QObject::connect((SnapshotAnimated::snapshotAnimatedTimer), &QTimer::timeout, captureFrames); + + // Start the snapshotAnimatedTimer QTimer - argument for this is in milliseconds + SnapshotAnimated::snapshotAnimatedTimerRunning = true; + SnapshotAnimated::snapshotAnimatedTimer->start(SNAPSNOT_ANIMATED_FRAME_DELAY_MSEC); + // If we're already in the middle of capturing an animated snapshot... + } else { + // Just tell the dependency manager that the capture of the still snapshot has taken place. + emit dm->snapshotTaken(pathStill, "", false); + } +} + +void SnapshotAnimated::captureFrames() { + if (SnapshotAnimated::snapshotAnimatedTimerRunning) { + // Get a screenshot from the display, then scale the screenshot down, + // then convert it to the image format the GIF library needs, + // then save all that to the QImage named "frame" + QImage frame(SnapshotAnimated::app->getActiveDisplayPlugin()->getScreenshot(SnapshotAnimated::aspectRatio)); + frame = frame.scaledToWidth(SNAPSNOT_ANIMATED_WIDTH); + SnapshotAnimated::snapshotAnimatedFrameVector.append(frame); + + // If that was the first frame... + if (SnapshotAnimated::snapshotAnimatedFirstFrameTimestamp == 0) { + // Record the current frame timestamp + SnapshotAnimated::snapshotAnimatedTimestamp = QDateTime::currentMSecsSinceEpoch(); + // Record the first frame timestamp + SnapshotAnimated::snapshotAnimatedFirstFrameTimestamp = SnapshotAnimated::snapshotAnimatedTimestamp; + SnapshotAnimated::snapshotAnimatedFrameDelayVector.append(SNAPSNOT_ANIMATED_FRAME_DELAY_MSEC / 10); + // If this is an intermediate or the final frame... + } else { + // Push the current frame delay onto the vector + SnapshotAnimated::snapshotAnimatedFrameDelayVector.append(round(((float)(QDateTime::currentMSecsSinceEpoch() - SnapshotAnimated::snapshotAnimatedTimestamp)) / 10)); + // Record the current frame timestamp + SnapshotAnimated::snapshotAnimatedTimestamp = QDateTime::currentMSecsSinceEpoch(); + + // If that was the last frame... + if ((SnapshotAnimated::snapshotAnimatedTimestamp - SnapshotAnimated::snapshotAnimatedFirstFrameTimestamp) >= (SnapshotAnimated::snapshotAnimatedDuration.get() * MSECS_PER_SECOND)) { + SnapshotAnimated::snapshotAnimatedTimerRunning = false; + // Reset the current frame timestamp + SnapshotAnimated::snapshotAnimatedTimestamp = 0; + SnapshotAnimated::snapshotAnimatedFirstFrameTimestamp = 0; + + // Kick off the thread that'll pack the frames into the GIF + QtConcurrent::run(processFrames); + // Stop the snapshot QTimer. This action by itself DOES NOT GUARANTEE + // that the slot will not be called again in the future. + // See: http://lists.qt-project.org/pipermail/qt-interest-old/2009-October/013926.html + SnapshotAnimated::snapshotAnimatedTimer->stop(); + delete SnapshotAnimated::snapshotAnimatedTimer; + } + } + } +} + +void SnapshotAnimated::processFrames() { + uint32_t width = SnapshotAnimated::snapshotAnimatedFrameVector[0].width(); + uint32_t height = SnapshotAnimated::snapshotAnimatedFrameVector[0].height(); + + // Create the GIF from the temporary files + // Write out the header and beginning of the GIF file + GifBegin( + &(SnapshotAnimated::snapshotAnimatedGifWriter), + qPrintable(SnapshotAnimated::snapshotAnimatedPath), + width, + height, + 1); // "1" means "yes there is a delay" with this GifCreator library. + for (int itr = 0; itr < SnapshotAnimated::snapshotAnimatedFrameVector.size(); itr++) { + // Write each frame to the GIF + GifWriteFrame(&(SnapshotAnimated::snapshotAnimatedGifWriter), + (uint8_t*)SnapshotAnimated::snapshotAnimatedFrameVector[itr].convertToFormat(QImage::Format_RGBA8888).bits(), + width, + height, + SnapshotAnimated::snapshotAnimatedFrameDelayVector[itr]); + } + // Write out the end of the GIF + GifEnd(&(SnapshotAnimated::snapshotAnimatedGifWriter)); + + // Clear out the frame and frame delay vectors. + // Also release the memory not required to store the items. + SnapshotAnimated::snapshotAnimatedFrameVector.clear(); + SnapshotAnimated::snapshotAnimatedFrameVector.squeeze(); + SnapshotAnimated::snapshotAnimatedFrameDelayVector.clear(); + SnapshotAnimated::snapshotAnimatedFrameDelayVector.squeeze(); + + // Let the dependency manager know that the snapshots have been taken. + emit SnapshotAnimated::snapshotAnimatedDM->snapshotTaken(SnapshotAnimated::snapshotStillPath, SnapshotAnimated::snapshotAnimatedPath, false); +} diff --git a/interface/src/ui/SnapshotAnimated.h b/interface/src/ui/SnapshotAnimated.h new file mode 100644 index 0000000000..78b1529ab4 --- /dev/null +++ b/interface/src/ui/SnapshotAnimated.h @@ -0,0 +1,58 @@ +// +// SnapshotAnimated.h +// interface/src/ui +// +// Created by Zach Fox on 11/14/16. +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_SnapshotAnimated_h +#define hifi_SnapshotAnimated_h + +#include +#include +#include +#include +#include +#include +#include "scripting/WindowScriptingInterface.h" + +// If the snapshot width or the framerate are too high for the +// application to handle, the framerate of the output GIF will drop. +#define SNAPSNOT_ANIMATED_WIDTH (480) +// This value should divide evenly into 100. Snapshot framerate is NOT guaranteed. +#define SNAPSNOT_ANIMATED_TARGET_FRAMERATE (25) +#define SNAPSNOT_ANIMATED_DURATION_SECS (3) +#define SNAPSNOT_ANIMATED_DURATION_MSEC (SNAPSNOT_ANIMATED_DURATION_SECS*1000) + +#define SNAPSNOT_ANIMATED_FRAME_DELAY_MSEC (1000/SNAPSNOT_ANIMATED_TARGET_FRAMERATE) + +class SnapshotAnimated { +private: + static QTimer* snapshotAnimatedTimer; + static qint64 snapshotAnimatedTimestamp; + static qint64 snapshotAnimatedFirstFrameTimestamp; + static bool snapshotAnimatedTimerRunning; + static QString snapshotStillPath; + + static QString snapshotAnimatedPath; + static QVector snapshotAnimatedFrameVector; + static QVector snapshotAnimatedFrameDelayVector; + static QSharedPointer snapshotAnimatedDM; + static Application* app; + static float aspectRatio; + + static GifWriter snapshotAnimatedGifWriter; + + static void captureFrames(); + static void processFrames(); +public: + static void saveSnapshotAnimated(QString pathStill, float aspectRatio, Application* app, QSharedPointer dm); + static Setting::Handle alsoTakeAnimatedSnapshot; + static Setting::Handle snapshotAnimatedDuration; +}; + +#endif // hifi_SnapshotAnimated_h diff --git a/scripts/system/html/SnapshotReview.html b/scripts/system/html/SnapshotReview.html index db70a1910b..d37afb180c 100644 --- a/scripts/system/html/SnapshotReview.html +++ b/scripts/system/html/SnapshotReview.html @@ -1,48 +1,48 @@ - + Share - + - +
-
-
- -
-
-
-
-
Would you like to share your pic in the Snapshots feed?
-
- - - - +
+
+ +
+
+
+
+
Would you like to share your pics in the Snapshots feed?
+
+ + + + +
+
+
+ +
+
+
+
+ + + + + + + +
-
-
- -
-
-
- - - - - - - - +
-
-
-
- + diff --git a/scripts/system/html/js/SnapshotReview.js b/scripts/system/html/js/SnapshotReview.js index a6515df825..a1bb350789 100644 --- a/scripts/system/html/js/SnapshotReview.js +++ b/scripts/system/html/js/SnapshotReview.js @@ -12,6 +12,9 @@ var paths = [], idCounter = 0, useCheckboxes; function addImage(data) { + if (!data.localPath) { + return; + } var div = document.createElement("DIV"), input = document.createElement("INPUT"), label = document.createElement("LABEL"), @@ -20,21 +23,22 @@ function addImage(data) { function toggle() { data.share = input.checked; } img.src = data.localPath; div.appendChild(img); - data.share = true; if (useCheckboxes) { // I'd rather use css, but the included stylesheet is quite particular. // Our stylesheet(?) requires input.id to match label.for. Otherwise input doesn't display the check state. label.setAttribute('for', id); // cannot do label.for = input.id = id; input.type = "checkbox"; - input.checked = true; + input.checked = (id === "p0"); + data.share = input.checked; input.addEventListener('change', toggle); div.class = "property checkbox"; div.appendChild(input); div.appendChild(label); + } else { + data.share = true; } document.getElementById("snapshot-images").appendChild(div); paths.push(data); - } function handleShareButtons(shareMsg) { var openFeed = document.getElementById('openFeed'); @@ -49,7 +53,7 @@ function handleShareButtons(shareMsg) { window.onload = function () { // Something like the following will allow testing in a browser. //addImage({localPath: 'c:/Users/howar/OneDrive/Pictures/hifi-snap-by--on-2016-07-27_12-58-43.jpg'}); - //addImage({localPath: 'http://lorempixel.com/1512/1680'}); + //addImage({ localPath: 'http://lorempixel.com/1512/1680' }); openEventBridge(function () { // Set up a handler for receiving the data, and tell the .js we are ready to receive it. EventBridge.scriptEventReceived.connect(function (message) { diff --git a/scripts/system/notifications.js b/scripts/system/notifications.js index d89b532f31..d2589cb72f 100644 --- a/scripts/system/notifications.js +++ b/scripts/system/notifications.js @@ -522,13 +522,13 @@ function onEditError(msg) { } -function onSnapshotTaken(path, notify) { +function onSnapshotTaken(pathStillSnapshot, pathAnimatedSnapshot, notify) { if (notify) { var imageProperties = { - path: "file:///" + path, + path: "file:///" + pathStillSnapshot, aspectRatio: Window.innerWidth / Window.innerHeight }; - createNotification(wordWrap("Snapshot saved to " + path), NotificationType.SNAPSHOT, imageProperties); + createNotification(wordWrap("Snapshot saved to " + pathStillSnapshot), NotificationType.SNAPSHOT, imageProperties); } } diff --git a/scripts/system/snapshot.js b/scripts/system/snapshot.js index 5eebadd02f..b4ebb99ef0 100644 --- a/scripts/system/snapshot.js +++ b/scripts/system/snapshot.js @@ -36,7 +36,7 @@ var SNAPSHOT_REVIEW_URL = Script.resolvePath("html/SnapshotReview.html"); var outstanding; function confirmShare(data) { - var dialog = new OverlayWebWindow('Snapshot Review', SNAPSHOT_REVIEW_URL, 800, 320); + var dialog = new OverlayWebWindow('Snapshot Review', SNAPSHOT_REVIEW_URL, 800, 520); 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.) @@ -120,11 +120,11 @@ function onClicked() { // take snapshot (with no notification) Script.setTimeout(function () { - Window.takeSnapshot(false, 1.91); + Window.takeSnapshot(false, true, 1.91); }, SNAPSHOT_DELAY); } -function resetButtons(path, notify) { +function resetButtons(pathStillSnapshot, pathAnimatedSnapshot, notify) { // show overlays if they were on if (resetOverlays) { Menu.setIsOptionChecked("Overlays", true); @@ -141,7 +141,8 @@ function resetButtons(path, notify) { // last element in data array tells dialog whether we can share or not confirmShare([ - { localPath: path }, + { localPath: pathAnimatedSnapshot }, + { localPath: pathStillSnapshot }, { canShare: !!location.placename, openFeedAfterShare: shouldOpenFeedAfterShare()