mirror of
https://github.com/overte-org/overte.git
synced 2025-04-14 08:27:15 +02:00
258 lines
9.2 KiB
JavaScript
258 lines
9.2 KiB
JavaScript
//
|
|
// snapshot.js
|
|
//
|
|
// Created by David Kelly on 1 August 2016
|
|
// 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
|
|
//
|
|
/* globals Tablet, Script, HMD, Settings, DialogsManager, Menu, Reticle, OverlayWebWindow, Desktop, Account, MyAvatar */
|
|
/* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */
|
|
|
|
(function() { // BEGIN LOCAL_SCOPE
|
|
|
|
var SNAPSHOT_DELAY = 500; // 500ms
|
|
var FINISH_SOUND_DELAY = 350;
|
|
var resetOverlays;
|
|
var reticleVisible;
|
|
var clearOverlayWhenMoving;
|
|
|
|
var buttonName = "SNAP";
|
|
var buttonConnected = false;
|
|
|
|
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
|
var button = tablet.addButton({
|
|
icon: "icons/tablet-icons/snap-i.svg",
|
|
text: buttonName,
|
|
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"))) {
|
|
DialogsManager.showFeed();
|
|
} else {
|
|
tablet.loadQMLSource("TabletAddressDialog.qml");
|
|
HMD.openTablet();
|
|
}
|
|
}
|
|
|
|
var outstanding;
|
|
var readyData;
|
|
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.)
|
|
// 2. Although we currently use a single image, we would like to take snapshot, a selfie, a 360 etc. all at the
|
|
// same time, show the user all of them, and have the user deselect any that they do not want to share.
|
|
// So we'll ultimately be receiving a set of objects, perhaps with different post processing for each.
|
|
message = JSON.parse(message);
|
|
if (message.type !== "snapshot") {
|
|
return;
|
|
}
|
|
|
|
var isLoggedIn;
|
|
var needsLogin = false;
|
|
switch (message.action) {
|
|
case 'ready': // Send it.
|
|
tablet.emitScriptEvent(JSON.stringify({
|
|
type: "snapshot",
|
|
action: readyData
|
|
}));
|
|
outstanding = 0;
|
|
break;
|
|
case 'openSettings':
|
|
if ((HMD.active && Settings.getValue("hmdTabletBecomesToolbar"))
|
|
|| (!HMD.active && Settings.getValue("desktopTabletBecomesToolbar"))) {
|
|
Desktop.show("hifi/dialogs/GeneralPreferencesDialog.qml", "General Preferences");
|
|
} else {
|
|
tablet.loadQMLSource("TabletGeneralPreferences.qml");
|
|
}
|
|
break;
|
|
case 'setOpenFeedFalse':
|
|
Settings.setValue('openFeedAfterShare', false);
|
|
break;
|
|
case 'setOpenFeedTrue':
|
|
Settings.setValue('openFeedAfterShare', true);
|
|
break;
|
|
default:
|
|
//tablet.webEventReceived.disconnect(onMessage); // <<< It's probably this that's missing?!
|
|
HMD.closeTablet();
|
|
tablet.gotoHomeScreen();
|
|
isLoggedIn = Account.isLoggedIn();
|
|
message.action.forEach(function (submessage) {
|
|
if (submessage.share && !isLoggedIn) {
|
|
needsLogin = true;
|
|
submessage.share = false;
|
|
}
|
|
if (submessage.share) {
|
|
print('sharing', submessage.localPath);
|
|
outstanding++;
|
|
Window.shareSnapshot(submessage.localPath, submessage.href);
|
|
} else {
|
|
print('not sharing', submessage.localPath);
|
|
}
|
|
});
|
|
if (!outstanding && shouldOpenFeedAfterShare()) {
|
|
//showFeedWindow();
|
|
}
|
|
if (needsLogin) { // after the possible feed, so that the login is on top
|
|
Account.checkAndSignalForAccessToken();
|
|
}
|
|
}
|
|
}
|
|
|
|
var SNAPSHOT_REVIEW_URL = Script.resolvePath("html/SnapshotReview.html");
|
|
var isInSnapshotReview = false;
|
|
function confirmShare(data) {
|
|
tablet.gotoWebScreen(SNAPSHOT_REVIEW_URL);
|
|
readyData = data;
|
|
tablet.webEventReceived.connect(onMessage);
|
|
HMD.openTablet();
|
|
isInSnapshotReview = true;
|
|
}
|
|
|
|
function snapshotShared(errorMessage) {
|
|
if (!errorMessage) {
|
|
print('snapshot uploaded and shared');
|
|
} else {
|
|
print(errorMessage);
|
|
}
|
|
if ((--outstanding <= 0) && shouldOpenFeedAfterShare()) {
|
|
showFeedWindow();
|
|
}
|
|
}
|
|
var href, domainId;
|
|
function onClicked() {
|
|
// Raising the desktop for the share dialog at end will interact badly with clearOverlayWhenMoving.
|
|
// Turn it off now, before we start futzing with things (and possibly moving).
|
|
clearOverlayWhenMoving = MyAvatar.getClearOverlayWhenMoving(); // Do not use Settings. MyAvatar keeps a separate copy.
|
|
MyAvatar.setClearOverlayWhenMoving(false);
|
|
|
|
// We will record snapshots based on the starting location. That could change, e.g., when recording a .gif.
|
|
// Even the domainId could change (e.g., if the user falls into a teleporter while recording).
|
|
href = location.href;
|
|
domainId = location.domainId;
|
|
|
|
// update button states
|
|
resetOverlays = Menu.isOptionChecked("Overlays"); // For completness. Certainly true if the button is visible to be clicke.
|
|
reticleVisible = Reticle.visible;
|
|
Reticle.visible = false;
|
|
Window.snapshotTaken.connect(resetButtons);
|
|
|
|
// hide overlays if they are on
|
|
if (resetOverlays) {
|
|
Menu.setIsOptionChecked("Overlays", false);
|
|
}
|
|
|
|
// take snapshot (with no notification)
|
|
Script.setTimeout(function () {
|
|
HMD.closeTablet();
|
|
Script.setTimeout(function () {
|
|
Window.takeSnapshot(false, true, 1.91);
|
|
}, SNAPSHOT_DELAY);
|
|
}, FINISH_SOUND_DELAY);
|
|
}
|
|
|
|
function isDomainOpen(id) {
|
|
var request = new XMLHttpRequest();
|
|
var options = [
|
|
'now=' + new Date().toISOString(),
|
|
'include_actions=concurrency',
|
|
'domain_id=' + id.slice(1, -1),
|
|
'restriction=open,hifi' // If we're sharing, we're logged in
|
|
// If we're here, protocol matches, and it is online
|
|
];
|
|
var url = location.metaverseServerUrl + "/api/v1/user_stories?" + options.join('&');
|
|
request.open("GET", url, false);
|
|
request.send();
|
|
if (request.status !== 200) {
|
|
return false;
|
|
}
|
|
var response = JSON.parse(request.response); // Not parsed for us.
|
|
return (response.status === 'success') &&
|
|
response.total_entries;
|
|
}
|
|
|
|
function resetButtons(pathStillSnapshot, pathAnimatedSnapshot, notify) {
|
|
// If we're not taking an animated snapshot, we have to show the HUD.
|
|
// If we ARE taking an animated snapshot, we've already re-enabled the HUD by this point.
|
|
if (pathAnimatedSnapshot === "") {
|
|
// show hud
|
|
|
|
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);
|
|
|
|
// 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
|
|
// it records the correct href. (We can also stash in .jpegs, but not .gifs.)
|
|
// last element in data array tells dialog whether we can share or not
|
|
var confirmShareContents = [
|
|
{ localPath: pathStillSnapshot, href: href },
|
|
{
|
|
canShare: !!isDomainOpen(domainId),
|
|
openFeedAfterShare: shouldOpenFeedAfterShare()
|
|
}];
|
|
if (pathAnimatedSnapshot !== "") {
|
|
confirmShareContents.unshift({ localPath: pathAnimatedSnapshot, href: href });
|
|
}
|
|
confirmShare(confirmShareContents);
|
|
if (clearOverlayWhenMoving) {
|
|
MyAvatar.setClearOverlayWhenMoving(true); // not until after the share dialog
|
|
}
|
|
HMD.openTablet();
|
|
}
|
|
|
|
function processingGif() {
|
|
// show hud
|
|
Reticle.visible = reticleVisible;
|
|
button.clicked.disconnect(onClicked);
|
|
buttonConnected = false;
|
|
// show overlays if they were on
|
|
if (resetOverlays) {
|
|
Menu.setIsOptionChecked("Overlays", true);
|
|
}
|
|
}
|
|
|
|
function onTabletScreenChanged(type, url) {
|
|
if (isInSnapshotReview) {
|
|
tablet.webEventReceived.disconnect(onMessage);
|
|
isInSnapshotReview = false;
|
|
}
|
|
}
|
|
|
|
button.clicked.connect(onClicked);
|
|
buttonConnected = true;
|
|
Window.snapshotShared.connect(snapshotShared);
|
|
Window.processingGif.connect(processingGif);
|
|
tablet.screenChanged.connect(onTabletScreenChanged);
|
|
|
|
Script.scriptEnding.connect(function () {
|
|
if (buttonConnected) {
|
|
button.clicked.disconnect(onClicked);
|
|
buttonConnected = false;
|
|
}
|
|
if (tablet) {
|
|
tablet.removeButton(button);
|
|
}
|
|
Window.snapshotShared.disconnect(snapshotShared);
|
|
Window.processingGif.disconnect(processingGif);
|
|
tablet.screenChanged.disconnect(onTabletScreenChanged);
|
|
});
|
|
|
|
}()); // END LOCAL_SCOPE
|