Merge pull request #10207 from zfox23/gifShareImprovements

Snapshot sharing improvements
This commit is contained in:
Zach Fox 2017-04-12 16:33:44 -07:00 committed by GitHub
commit f23f9ec698
7 changed files with 88 additions and 48 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

View file

@ -6417,7 +6417,7 @@ void Application::takeSnapshot(bool notify, bool includeAnimated, float aspectRa
// If we're not doing an animated snapshot as well... // If we're not doing an animated snapshot as well...
if (!includeAnimated || !(SnapshotAnimated::alsoTakeAnimatedSnapshot.get())) { if (!includeAnimated || !(SnapshotAnimated::alsoTakeAnimatedSnapshot.get())) {
// Tell the dependency manager that the capture of the still snapshot has taken place. // Tell the dependency manager that the capture of the still snapshot has taken place.
emit DependencyManager::get<WindowScriptingInterface>()->snapshotTaken(path, "", notify); emit DependencyManager::get<WindowScriptingInterface>()->stillSnapshotTaken(path, notify);
} else { } else {
// Get an animated GIF snapshot and save it // Get an animated GIF snapshot and save it
SnapshotAnimated::saveSnapshotAnimated(path, aspectRatio, qApp, DependencyManager::get<WindowScriptingInterface>()); SnapshotAnimated::saveSnapshotAnimated(path, aspectRatio, qApp, DependencyManager::get<WindowScriptingInterface>());

View file

@ -71,9 +71,10 @@ signals:
void domainChanged(const QString& domainHostname); void domainChanged(const QString& domainHostname);
void svoImportRequested(const QString& url); void svoImportRequested(const QString& url);
void domainConnectionRefused(const QString& reasonMessage, int reasonCode, const QString& extraInfo); void domainConnectionRefused(const QString& reasonMessage, int reasonCode, const QString& extraInfo);
void snapshotTaken(const QString& pathStillSnapshot, const QString& pathAnimatedSnapshot, bool notify); void stillSnapshotTaken(const QString& pathStillSnapshot, bool notify);
void snapshotShared(const QString& error); void snapshotShared(const QString& error);
void processingGif(); void processingGifStarted(const QString& pathStillSnapshot);
void processingGifCompleted(const QString& pathAnimatedSnapshot);
void connectionAdded(const QString& connectionName); void connectionAdded(const QString& connectionName);
void connectionError(const QString& errorString); void connectionError(const QString& errorString);

View file

@ -86,7 +86,8 @@ void SnapshotAnimated::captureFrames() {
SnapshotAnimated::snapshotAnimatedTimerRunning = false; SnapshotAnimated::snapshotAnimatedTimerRunning = false;
// Notify the user that we're processing the snapshot // Notify the user that we're processing the snapshot
emit SnapshotAnimated::snapshotAnimatedDM->processingGif(); // This also pops up the "Share" dialog. The unprocessed GIF will be visualized as a loading icon until processingGifCompleted() is called.
emit SnapshotAnimated::snapshotAnimatedDM->processingGifStarted(SnapshotAnimated::snapshotStillPath);
// Kick off the thread that'll pack the frames into the GIF // Kick off the thread that'll pack the frames into the GIF
QtConcurrent::run(processFrames); QtConcurrent::run(processFrames);
@ -132,7 +133,7 @@ void SnapshotAnimated::processFrames() {
// Reset the current frame timestamp // Reset the current frame timestamp
SnapshotAnimated::snapshotAnimatedTimestamp = 0; SnapshotAnimated::snapshotAnimatedTimestamp = 0;
SnapshotAnimated::snapshotAnimatedFirstFrameTimestamp = 0; SnapshotAnimated::snapshotAnimatedFirstFrameTimestamp = 0;
// Let the window scripting interface know that the snapshots have been taken. // Update the "Share" dialog with the processed GIF.
emit SnapshotAnimated::snapshotAnimatedDM->snapshotTaken(SnapshotAnimated::snapshotStillPath, SnapshotAnimated::snapshotAnimatedPath, false); emit SnapshotAnimated::snapshotAnimatedDM->processingGifCompleted(SnapshotAnimated::snapshotAnimatedPath);
} }

View file

@ -21,6 +21,7 @@ function addImage(data) {
img = document.createElement("IMG"), img = document.createElement("IMG"),
div2 = document.createElement("DIV"), div2 = document.createElement("DIV"),
id = "p" + idCounter++; id = "p" + idCounter++;
img.id = id + "img";
function toggle() { data.share = input.checked; } function toggle() { data.share = input.checked; }
div.style.height = "" + Math.floor(100 / imageCount) + "%"; div.style.height = "" + Math.floor(100 / imageCount) + "%";
if (imageCount > 1) { if (imageCount > 1) {
@ -33,7 +34,7 @@ function addImage(data) {
label.setAttribute('for', id); // cannot do label.for = label.setAttribute('for', id); // cannot do label.for =
input.id = id; input.id = id;
input.type = "checkbox"; input.type = "checkbox";
input.checked = (id === "p0"); input.checked = false;
data.share = input.checked; data.share = input.checked;
input.addEventListener('change', toggle); input.addEventListener('change', toggle);
div2.setAttribute("class", "property checkbox"); div2.setAttribute("class", "property checkbox");
@ -46,9 +47,9 @@ function addImage(data) {
document.getElementById("snapshot-images").appendChild(div); document.getElementById("snapshot-images").appendChild(div);
paths.push(data); paths.push(data);
} }
function handleShareButtons(shareMsg) { function handleShareButtons(messageOptions) {
var openFeed = document.getElementById('openFeed'); var openFeed = document.getElementById('openFeed');
openFeed.checked = shareMsg.openFeedAfterShare; openFeed.checked = messageOptions.openFeedAfterShare;
openFeed.onchange = function () { openFeed.onchange = function () {
EventBridge.emitWebEvent(JSON.stringify({ EventBridge.emitWebEvent(JSON.stringify({
type: "snapshot", type: "snapshot",
@ -56,7 +57,7 @@ function handleShareButtons(shareMsg) {
})); }));
}; };
if (!shareMsg.canShare) { if (!messageOptions.canShare) {
// this means you may or may not be logged in, but can't share // this means you may or may not be logged in, but can't share
// because you are not in a public place. // because you are not in a public place.
document.getElementById("sharing").innerHTML = "<p class='prompt'>Snapshots can be shared when they're taken in shareable places."; document.getElementById("sharing").innerHTML = "<p class='prompt'>Snapshots can be shared when they're taken in shareable places.";
@ -74,13 +75,26 @@ window.onload = function () {
return; return;
} }
// last element of list contains a bool for whether or not we can share stuff // The last element of the message contents list contains a bunch of options,
var shareMsg = message.action.pop(); // including whether or not we can share stuff
handleShareButtons(shareMsg); // The other elements of the list contain image paths.
var messageOptions = message.action.pop();
// rest are image paths which we add handleShareButtons(messageOptions);
imageCount = message.action.length;
message.action.forEach(addImage); if (messageOptions.containsGif) {
if (messageOptions.processingGif) {
imageCount = message.action.length + 1; // "+1" for the GIF that'll finish processing soon
message.action.unshift({ localPath: '../../../resources/icons/loadingDark.gif' });
message.action.forEach(addImage);
document.getElementById('p0').disabled = true;
} else {
document.getElementById('p0').disabled = false;
document.getElementById('p0img').src = message.action[0].localPath;
}
} else {
imageCount = message.action.length;
message.action.forEach(addImage);
}
}); });
EventBridge.emitWebEvent(JSON.stringify({ EventBridge.emitWebEvent(JSON.stringify({
type: "snapshot", type: "snapshot",

View file

@ -532,7 +532,7 @@ function onNotify(msg) {
createNotification(wordWrap(msg), NotificationType.UNKNOWN); // Needs a generic notification system for user feedback, thus using this createNotification(wordWrap(msg), NotificationType.UNKNOWN); // Needs a generic notification system for user feedback, thus using this
} }
function onSnapshotTaken(pathStillSnapshot, pathAnimatedSnapshot, notify) { function onSnapshotTaken(pathStillSnapshot, notify) {
if (notify) { if (notify) {
var imageProperties = { var imageProperties = {
path: "file:///" + pathStillSnapshot, path: "file:///" + pathStillSnapshot,
@ -656,8 +656,8 @@ Script.update.connect(update);
Script.scriptEnding.connect(scriptEnding); Script.scriptEnding.connect(scriptEnding);
Menu.menuItemEvent.connect(menuItemEvent); Menu.menuItemEvent.connect(menuItemEvent);
Window.domainConnectionRefused.connect(onDomainConnectionRefused); Window.domainConnectionRefused.connect(onDomainConnectionRefused);
Window.snapshotTaken.connect(onSnapshotTaken); Window.stillSnapshotTaken.connect(onSnapshotTaken);
Window.processingGif.connect(processingGif); Window.processingGifStarted.connect(processingGif);
Window.connectionAdded.connect(connectionAdded); Window.connectionAdded.connect(connectionAdded);
Window.connectionError.connect(connectionError); Window.connectionError.connect(connectionError);
Window.notifyEditError = onEditError; Window.notifyEditError = onEditError;

View file

@ -157,7 +157,9 @@ function onClicked() {
resetOverlays = Menu.isOptionChecked("Overlays"); // For completness. Certainly true if the button is visible to be clicke. resetOverlays = Menu.isOptionChecked("Overlays"); // For completness. Certainly true if the button is visible to be clicke.
reticleVisible = Reticle.visible; reticleVisible = Reticle.visible;
Reticle.visible = false; Reticle.visible = false;
Window.snapshotTaken.connect(resetButtons); Window.stillSnapshotTaken.connect(stillSnapshotTaken);
Window.processingGifStarted.connect(processingGifStarted);
Window.processingGifCompleted.connect(processingGifCompleted);
// hide overlays if they are on // hide overlays if they are on
if (resetOverlays) { if (resetOverlays) {
@ -193,25 +195,14 @@ function isDomainOpen(id) {
response.total_entries; response.total_entries;
} }
function resetButtons(pathStillSnapshot, pathAnimatedSnapshot, notify) { function stillSnapshotTaken(pathStillSnapshot, notify) {
// If we're not taking an animated snapshot, we have to show the HUD. // show hud
// If we ARE taking an animated snapshot, we've already re-enabled the HUD by this point. Reticle.visible = reticleVisible;
if (pathAnimatedSnapshot === "") { // show overlays if they were on
// show hud if (resetOverlays) {
Menu.setIsOptionChecked("Overlays", true);
Reticle.visible = reticleVisible;
// show overlays if they were on
if (resetOverlays) {
Menu.setIsOptionChecked("Overlays", true);
}
} else {
// Allow the user to click the snapshot HUD button again
if (!buttonConnected) {
button.clicked.connect(onClicked);
buttonConnected = true;
}
} }
Window.snapshotTaken.disconnect(resetButtons); Window.stillSnapshotTaken.disconnect(stillSnapshotTaken);
// A Snapshot Review dialog might be left open indefinitely after taking the picture, // A Snapshot Review dialog might be left open indefinitely after taking the picture,
// during which time the user may have moved. So stash that info in the dialog so that // during which time the user may have moved. So stash that info in the dialog so that
@ -220,12 +211,11 @@ function resetButtons(pathStillSnapshot, pathAnimatedSnapshot, notify) {
var confirmShareContents = [ var confirmShareContents = [
{ localPath: pathStillSnapshot, href: href }, { localPath: pathStillSnapshot, href: href },
{ {
containsGif: false,
processingGif: false,
canShare: !!isDomainOpen(domainId), canShare: !!isDomainOpen(domainId),
openFeedAfterShare: shouldOpenFeedAfterShare() openFeedAfterShare: shouldOpenFeedAfterShare()
}]; }];
if (pathAnimatedSnapshot !== "") {
confirmShareContents.unshift({ localPath: pathAnimatedSnapshot, href: href });
}
confirmShare(confirmShareContents); confirmShare(confirmShareContents);
if (clearOverlayWhenMoving) { if (clearOverlayWhenMoving) {
MyAvatar.setClearOverlayWhenMoving(true); // not until after the share dialog MyAvatar.setClearOverlayWhenMoving(true); // not until after the share dialog
@ -233,15 +223,51 @@ function resetButtons(pathStillSnapshot, pathAnimatedSnapshot, notify) {
HMD.openTablet(); HMD.openTablet();
} }
function processingGif() { function processingGifStarted(pathStillSnapshot) {
// show hud Window.processingGifStarted.disconnect(processingGifStarted);
Reticle.visible = reticleVisible;
button.clicked.disconnect(onClicked); button.clicked.disconnect(onClicked);
buttonConnected = false; buttonConnected = false;
// show hud
Reticle.visible = reticleVisible;
// show overlays if they were on // show overlays if they were on
if (resetOverlays) { if (resetOverlays) {
Menu.setIsOptionChecked("Overlays", true); Menu.setIsOptionChecked("Overlays", true);
} }
var confirmShareContents = [
{ localPath: pathStillSnapshot, href: href },
{
containsGif: true,
processingGif: true,
canShare: !!isDomainOpen(domainId),
openFeedAfterShare: shouldOpenFeedAfterShare()
}];
confirmShare(confirmShareContents);
if (clearOverlayWhenMoving) {
MyAvatar.setClearOverlayWhenMoving(true); // not until after the share dialog
}
HMD.openTablet();
}
function processingGifCompleted(pathAnimatedSnapshot) {
Window.processingGifCompleted.disconnect(processingGifCompleted);
button.clicked.connect(onClicked);
buttonConnected = true;
var confirmShareContents = [
{ localPath: pathAnimatedSnapshot, href: href },
{
containsGif: true,
processingGif: false,
canShare: !!isDomainOpen(domainId),
openFeedAfterShare: shouldOpenFeedAfterShare()
}];
readyData = confirmShareContents;
tablet.emitScriptEvent(JSON.stringify({
type: "snapshot",
action: readyData
}));
} }
function onTabletScreenChanged(type, url) { function onTabletScreenChanged(type, url) {
@ -265,7 +291,6 @@ function onConnected() {
button.clicked.connect(onClicked); button.clicked.connect(onClicked);
buttonConnected = true; buttonConnected = true;
Window.snapshotShared.connect(snapshotShared); Window.snapshotShared.connect(snapshotShared);
Window.processingGif.connect(processingGif);
tablet.screenChanged.connect(onTabletScreenChanged); tablet.screenChanged.connect(onTabletScreenChanged);
Account.usernameChanged.connect(onConnected); Account.usernameChanged.connect(onConnected);
Script.scriptEnding.connect(function () { Script.scriptEnding.connect(function () {
@ -277,7 +302,6 @@ Script.scriptEnding.connect(function () {
tablet.removeButton(button); tablet.removeButton(button);
} }
Window.snapshotShared.disconnect(snapshotShared); Window.snapshotShared.disconnect(snapshotShared);
Window.processingGif.disconnect(processingGif);
tablet.screenChanged.disconnect(onTabletScreenChanged); tablet.screenChanged.disconnect(onTabletScreenChanged);
}); });