mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-29 20:23:04 +02:00
Merge pull request #10278 from zfox23/newSnapshotReview
New Snapshot Review Dialog
This commit is contained in:
commit
a2721d21ef
18 changed files with 1163 additions and 354 deletions
|
@ -535,6 +535,7 @@ bool setupEssentials(int& argc, char** argv) {
|
||||||
DependencyManager::set<OctreeStatsProvider>(nullptr, qApp->getOcteeSceneStats());
|
DependencyManager::set<OctreeStatsProvider>(nullptr, qApp->getOcteeSceneStats());
|
||||||
DependencyManager::set<AvatarBookmarks>();
|
DependencyManager::set<AvatarBookmarks>();
|
||||||
DependencyManager::set<LocationBookmarks>();
|
DependencyManager::set<LocationBookmarks>();
|
||||||
|
DependencyManager::set<Snapshot>();
|
||||||
|
|
||||||
return previousSessionCrashed;
|
return previousSessionCrashed;
|
||||||
}
|
}
|
||||||
|
@ -2052,6 +2053,7 @@ void Application::initializeUi() {
|
||||||
rootContext->setContextProperty("Scene", DependencyManager::get<SceneScriptingInterface>().data());
|
rootContext->setContextProperty("Scene", DependencyManager::get<SceneScriptingInterface>().data());
|
||||||
rootContext->setContextProperty("Render", _renderEngine->getConfiguration().get());
|
rootContext->setContextProperty("Render", _renderEngine->getConfiguration().get());
|
||||||
rootContext->setContextProperty("Reticle", getApplicationCompositor().getReticleInterface());
|
rootContext->setContextProperty("Reticle", getApplicationCompositor().getReticleInterface());
|
||||||
|
rootContext->setContextProperty("Snapshot", DependencyManager::get<Snapshot>().data());
|
||||||
|
|
||||||
rootContext->setContextProperty("ApplicationCompositor", &getApplicationCompositor());
|
rootContext->setContextProperty("ApplicationCompositor", &getApplicationCompositor());
|
||||||
|
|
||||||
|
@ -5504,6 +5506,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri
|
||||||
scriptEngine->registerGlobalObject("Menu", MenuScriptingInterface::getInstance());
|
scriptEngine->registerGlobalObject("Menu", MenuScriptingInterface::getInstance());
|
||||||
scriptEngine->registerGlobalObject("Stats", Stats::getInstance());
|
scriptEngine->registerGlobalObject("Stats", Stats::getInstance());
|
||||||
scriptEngine->registerGlobalObject("Settings", SettingsScriptingInterface::getInstance());
|
scriptEngine->registerGlobalObject("Settings", SettingsScriptingInterface::getInstance());
|
||||||
|
scriptEngine->registerGlobalObject("Snapshot", DependencyManager::get<Snapshot>().data());
|
||||||
scriptEngine->registerGlobalObject("AudioDevice", AudioDeviceScriptingInterface::getInstance());
|
scriptEngine->registerGlobalObject("AudioDevice", AudioDeviceScriptingInterface::getInstance());
|
||||||
scriptEngine->registerGlobalObject("AudioStats", DependencyManager::get<AudioClient>()->getStats().data());
|
scriptEngine->registerGlobalObject("AudioStats", DependencyManager::get<AudioClient>()->getStats().data());
|
||||||
scriptEngine->registerGlobalObject("AudioScope", DependencyManager::get<AudioScope>().data());
|
scriptEngine->registerGlobalObject("AudioScope", DependencyManager::get<AudioScope>().data());
|
||||||
|
@ -6448,7 +6451,7 @@ void Application::takeSnapshot(bool notify, bool includeAnimated, float aspectRa
|
||||||
// Get a screenshot and save it
|
// Get a screenshot and save it
|
||||||
QString path = Snapshot::saveSnapshot(getActiveDisplayPlugin()->getScreenshot(aspectRatio));
|
QString path = Snapshot::saveSnapshot(getActiveDisplayPlugin()->getScreenshot(aspectRatio));
|
||||||
// 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) {
|
||||||
// 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>()->stillSnapshotTaken(path, notify);
|
emit DependencyManager::get<WindowScriptingInterface>()->stillSnapshotTaken(path, notify);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -168,6 +168,28 @@ void WindowScriptingInterface::ensureReticleVisible() const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Display a "browse to directory" dialog. If `directory` is an invalid file or directory the browser will start at the current
|
||||||
|
/// working directory.
|
||||||
|
/// \param const QString& title title of the window
|
||||||
|
/// \param const QString& directory directory to start the file browser at
|
||||||
|
/// \param const QString& nameFilter filter to filter filenames by - see `QFileDialog`
|
||||||
|
/// \return QScriptValue file path as a string if one was selected, otherwise `QScriptValue::NullValue`
|
||||||
|
QScriptValue WindowScriptingInterface::browseDir(const QString& title, const QString& directory) {
|
||||||
|
ensureReticleVisible();
|
||||||
|
QString path = directory;
|
||||||
|
if (path.isEmpty()) {
|
||||||
|
path = getPreviousBrowseLocation();
|
||||||
|
}
|
||||||
|
#ifndef Q_OS_WIN
|
||||||
|
path = fixupPathForMac(directory);
|
||||||
|
#endif
|
||||||
|
QString result = OffscreenUi::getExistingDirectory(nullptr, title, path);
|
||||||
|
if (!result.isEmpty()) {
|
||||||
|
setPreviousBrowseLocation(QFileInfo(result).absolutePath());
|
||||||
|
}
|
||||||
|
return result.isEmpty() ? QScriptValue::NullValue : QScriptValue(result);
|
||||||
|
}
|
||||||
|
|
||||||
/// Display an open file dialog. If `directory` is an invalid file or directory the browser will start at the current
|
/// Display an open file dialog. If `directory` is an invalid file or directory the browser will start at the current
|
||||||
/// working directory.
|
/// working directory.
|
||||||
/// \param const QString& title title of the window
|
/// \param const QString& title title of the window
|
||||||
|
|
|
@ -51,6 +51,7 @@ public slots:
|
||||||
QScriptValue confirm(const QString& message = "");
|
QScriptValue confirm(const QString& message = "");
|
||||||
QScriptValue prompt(const QString& message = "", const QString& defaultText = "");
|
QScriptValue prompt(const QString& message = "", const QString& defaultText = "");
|
||||||
CustomPromptResult customPrompt(const QVariant& config);
|
CustomPromptResult customPrompt(const QVariant& config);
|
||||||
|
QScriptValue browseDir(const QString& title = "", const QString& directory = "");
|
||||||
QScriptValue browse(const QString& title = "", const QString& directory = "", const QString& nameFilter = "");
|
QScriptValue browse(const QString& title = "", const QString& directory = "", const QString& nameFilter = "");
|
||||||
QScriptValue save(const QString& title = "", const QString& directory = "", const QString& nameFilter = "");
|
QScriptValue save(const QString& title = "", const QString& directory = "", const QString& nameFilter = "");
|
||||||
QScriptValue browseAssets(const QString& title = "", const QString& directory = "", const QString& nameFilter = "");
|
QScriptValue browseAssets(const QString& title = "", const QString& directory = "", const QString& nameFilter = "");
|
||||||
|
@ -74,7 +75,7 @@ signals:
|
||||||
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 stillSnapshotTaken(const QString& pathStillSnapshot, bool notify);
|
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 processingGifStarted(const QString& pathStillSnapshot);
|
||||||
void processingGifCompleted(const QString& pathAnimatedSnapshot);
|
void processingGifCompleted(const QString& pathAnimatedSnapshot);
|
||||||
|
|
||||||
|
|
|
@ -116,11 +116,6 @@ void setupPreferences() {
|
||||||
auto preference = new BrowsePreference(SNAPSHOTS, "Put my snapshots here", getter, setter);
|
auto preference = new BrowsePreference(SNAPSHOTS, "Put my snapshots here", getter, setter);
|
||||||
preferences->addPreference(preference);
|
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", getter, setter));
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
auto getter = []()->float { return SnapshotAnimated::snapshotAnimatedDuration.get(); };
|
auto getter = []()->float { return SnapshotAnimated::snapshotAnimatedDuration.get(); };
|
||||||
auto setter = [](float value) { SnapshotAnimated::snapshotAnimatedDuration.set(value); };
|
auto setter = [](float value) { SnapshotAnimated::snapshotAnimatedDuration.set(value); };
|
||||||
|
|
|
@ -194,3 +194,10 @@ void Snapshot::uploadSnapshot(const QString& filename, const QUrl& href) {
|
||||||
multiPart);
|
multiPart);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString Snapshot::getSnapshotsLocation() {
|
||||||
|
return snapshotsLocation.get("");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Snapshot::setSnapshotsLocation(const QString& location) {
|
||||||
|
snapshotsLocation.set(location);
|
||||||
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
|
|
||||||
#include <SettingHandle.h>
|
#include <SettingHandle.h>
|
||||||
|
#include <DependencyManager.h>
|
||||||
|
|
||||||
class QFile;
|
class QFile;
|
||||||
class QTemporaryFile;
|
class QTemporaryFile;
|
||||||
|
@ -32,7 +33,9 @@ private:
|
||||||
QUrl _URL;
|
QUrl _URL;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Snapshot {
|
class Snapshot : public QObject, public Dependency {
|
||||||
|
Q_OBJECT
|
||||||
|
SINGLETON_DEPENDENCY
|
||||||
public:
|
public:
|
||||||
static QString saveSnapshot(QImage image);
|
static QString saveSnapshot(QImage image);
|
||||||
static QTemporaryFile* saveTempSnapshot(QImage image);
|
static QTemporaryFile* saveTempSnapshot(QImage image);
|
||||||
|
@ -40,6 +43,10 @@ public:
|
||||||
|
|
||||||
static Setting::Handle<QString> snapshotsLocation;
|
static Setting::Handle<QString> snapshotsLocation;
|
||||||
static void uploadSnapshot(const QString& filename, const QUrl& href = QUrl(""));
|
static void uploadSnapshot(const QString& filename, const QUrl& href = QUrl(""));
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
Q_INVOKABLE QString getSnapshotsLocation();
|
||||||
|
Q_INVOKABLE void setSnapshotsLocation(const QString& location);
|
||||||
private:
|
private:
|
||||||
static QFile* savedFileForSnapshot(QImage & image, bool isTemporary);
|
static QFile* savedFileForSnapshot(QImage & image, bool isTemporary);
|
||||||
};
|
};
|
||||||
|
|
|
@ -49,6 +49,7 @@ void SnapshotUploader::uploadSuccess(QNetworkReply& reply) {
|
||||||
userStoryObject.insert("place_name", placeName);
|
userStoryObject.insert("place_name", placeName);
|
||||||
userStoryObject.insert("path", currentPath);
|
userStoryObject.insert("path", currentPath);
|
||||||
userStoryObject.insert("action", "snapshot");
|
userStoryObject.insert("action", "snapshot");
|
||||||
|
userStoryObject.insert("audience", "for_url");
|
||||||
rootObject.insert("user_story", userStoryObject);
|
rootObject.insert("user_story", userStoryObject);
|
||||||
|
|
||||||
auto accountManager = DependencyManager::get<AccountManager>();
|
auto accountManager = DependencyManager::get<AccountManager>();
|
||||||
|
@ -61,7 +62,7 @@ void SnapshotUploader::uploadSuccess(QNetworkReply& reply) {
|
||||||
QJsonDocument(rootObject).toJson());
|
QJsonDocument(rootObject).toJson());
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
emit DependencyManager::get<WindowScriptingInterface>()->snapshotShared(contents);
|
emit DependencyManager::get<WindowScriptingInterface>()->snapshotShared(true, contents);
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,12 +73,13 @@ void SnapshotUploader::uploadFailure(QNetworkReply& reply) {
|
||||||
if (replyString.size() == 0) {
|
if (replyString.size() == 0) {
|
||||||
replyString = reply.errorString();
|
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;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SnapshotUploader::createStorySuccess(QNetworkReply& reply) {
|
void SnapshotUploader::createStorySuccess(QNetworkReply& reply) {
|
||||||
emit DependencyManager::get<WindowScriptingInterface>()->snapshotShared(QString());
|
QString replyString = reply.readAll();
|
||||||
|
emit DependencyManager::get<WindowScriptingInterface>()->snapshotShared(false, replyString);
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +89,7 @@ void SnapshotUploader::createStoryFailure(QNetworkReply& reply) {
|
||||||
if (replyString.size() == 0) {
|
if (replyString.size() == 0) {
|
||||||
replyString = reply.errorString();
|
replyString = reply.errorString();
|
||||||
}
|
}
|
||||||
emit DependencyManager::get<WindowScriptingInterface>()->snapshotShared(replyString);
|
emit DependencyManager::get<WindowScriptingInterface>()->snapshotShared(true, replyString);
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
#include "ui/AvatarInputs.h"
|
#include "ui/AvatarInputs.h"
|
||||||
#include "avatar/AvatarManager.h"
|
#include "avatar/AvatarManager.h"
|
||||||
#include "scripting/GlobalServicesScriptingInterface.h"
|
#include "scripting/GlobalServicesScriptingInterface.h"
|
||||||
|
#include "ui/Snapshot.h"
|
||||||
|
|
||||||
static const float DPI = 30.47f;
|
static const float DPI = 30.47f;
|
||||||
static const float INCHES_TO_METERS = 1.0f / 39.3701f;
|
static const float INCHES_TO_METERS = 1.0f / 39.3701f;
|
||||||
|
@ -177,6 +178,7 @@ void Web3DOverlay::loadSourceURL() {
|
||||||
_webSurface->getRootContext()->setContextProperty("Quat", new Quat());
|
_webSurface->getRootContext()->setContextProperty("Quat", new Quat());
|
||||||
_webSurface->getRootContext()->setContextProperty("MyAvatar", DependencyManager::get<AvatarManager>()->getMyAvatar().get());
|
_webSurface->getRootContext()->setContextProperty("MyAvatar", DependencyManager::get<AvatarManager>()->getMyAvatar().get());
|
||||||
_webSurface->getRootContext()->setContextProperty("Entities", DependencyManager::get<EntityScriptingInterface>().data());
|
_webSurface->getRootContext()->setContextProperty("Entities", DependencyManager::get<EntityScriptingInterface>().data());
|
||||||
|
_webSurface->getRootContext()->setContextProperty("Snapshot", DependencyManager::get<Snapshot>().data());
|
||||||
|
|
||||||
if (_webSurface->getRootItem() && _webSurface->getRootItem()->objectName() == "tabletRoot") {
|
if (_webSurface->getRootItem() && _webSurface->getRootItem()->objectName() == "tabletRoot") {
|
||||||
auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
|
auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Share</title>
|
<title>Share</title>
|
||||||
<link rel="stylesheet" type="text/css" href="css/edit-style.css">
|
<link rel="stylesheet" type="text/css" href="css/hifi-style.css">
|
||||||
<link rel="stylesheet" type="text/css" href="css/SnapshotReview.css">
|
<link rel="stylesheet" type="text/css" href="css/SnapshotReview.css">
|
||||||
<script type="text/javascript" src="js/eventBridgeLoader.js"></script>
|
<script type="text/javascript" src="js/eventBridgeLoader.js"></script>
|
||||||
<script type="text/javascript" src="js/SnapshotReview.js"></script>
|
<script type="text/javascript" src="js/SnapshotReview.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div class="snapsection title">
|
<div class="title">
|
||||||
<label>Snap</label>
|
<label>Snapshots</label>
|
||||||
|
<label id="settingsLabel" for="snapshotSettings">Settings</label>
|
||||||
|
<input type="button" class="hifi-glyph naked" id="snapshotSettings" value="@" onclick="snapshotSettings()" />
|
||||||
</div>
|
</div>
|
||||||
<hr />
|
<hr />
|
||||||
<div id="snapshot-pane">
|
<div id="snapshot-pane">
|
||||||
|
@ -17,30 +19,16 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="snapshot-controls">
|
<div id="snapshot-controls">
|
||||||
<div class="snapsection" id="snap-buttons">
|
<div id="snap-settings">
|
||||||
<div id="sharing">
|
<label>CAMERA CAPTURES</label><br />
|
||||||
<div class="button">
|
<form action="">
|
||||||
<span class="compound-button">
|
<input type="radio" name="cameraCaptures" id="stillAndGif" value="stillAndGif" /><label for="stillAndGif"><span><span></span></span>Still + GIF</label>
|
||||||
<input type="button" class="blue" id="share" value="Share in Feed" onclick="shareSelected()" />
|
<br />
|
||||||
<span class="glyph"></span>
|
<input type="radio" name="cameraCaptures" id="stillOnly" value="stillOnly" /><label for="stillOnly"><span><span></span></span>Still Only</label>
|
||||||
</span>
|
</form>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="button">
|
|
||||||
<input type="button" class="black" id="close" value="Don't Share" onclick="doNotShare()" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<hr />
|
|
||||||
<div class="snapsection" id="snap-settings">
|
|
||||||
<span class="setting">
|
|
||||||
<input type="button" class="glyph naked" id="snapshotSettings" value="@" onclick="snapshotSettings()" />
|
|
||||||
<label for="snapshotSettings">Settings</label>
|
|
||||||
</span>
|
|
||||||
<span class="setting checkbox">
|
|
||||||
<input id="openFeed" type="checkbox" checked />
|
|
||||||
<label for="openFeed">Open feed after</label>
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
|
<input type="button" id="snap-button" onclick="takeSnapshot()" />
|
||||||
|
<div id="snap-settings-right"></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -8,142 +8,280 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
*/
|
*/
|
||||||
|
|
||||||
body {
|
/*
|
||||||
padding-top: 0;
|
// START styling of top bar and its contents
|
||||||
padding-bottom: 14px;
|
*/
|
||||||
}
|
|
||||||
|
|
||||||
.snapsection {
|
.title {
|
||||||
padding-top: 14px;
|
padding: 6px 10px;
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.snapsection.title {
|
|
||||||
padding-top: 0;
|
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
height: 26px;
|
||||||
|
line-height: 26px;
|
||||||
|
clear: both;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title label {
|
.title label {
|
||||||
font-size: 18px;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
top: 12px;
|
font-size: 18px;
|
||||||
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#snapshotSettings {
|
||||||
|
position: relative;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
#settingsLabel {
|
||||||
|
position: relative;
|
||||||
|
float: right;
|
||||||
|
font-family: Raleway-SemiBold;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.hifi-glyph {
|
||||||
|
font-size: 30px;
|
||||||
|
top: -4px;
|
||||||
|
}
|
||||||
|
input[type=button].naked {
|
||||||
|
color: #afafaf;
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
input[type=button].naked:hover {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
input[type=button].naked:active {
|
||||||
|
color: #afafaf;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
// END styling of top bar and its contents
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
// START styling of snapshot instructions panel
|
||||||
|
*/
|
||||||
|
.snapshotInstructions {
|
||||||
|
font-family: Raleway-Regular;
|
||||||
|
margin: 0 20px;
|
||||||
|
width: 100%;
|
||||||
|
height: 50%;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
// END styling of snapshot instructions panel
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
// START styling of snapshot pane and its contents
|
||||||
|
*/
|
||||||
#snapshot-pane {
|
#snapshot-pane {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 560px;
|
||||||
position: absolute;
|
display: flex;
|
||||||
top: 0;
|
justify-content: center;
|
||||||
left: 0;
|
align-items: center;
|
||||||
box-sizing: border-box;
|
|
||||||
padding-top: 56px;
|
|
||||||
padding-bottom: 175px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#snapshot-images {
|
#snapshot-images {
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
#snapshot-images > div {
|
|
||||||
position: relative;
|
|
||||||
text-align: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#snapshot-images img {
|
#snapshot-images img {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gifLabel {
|
||||||
|
position:absolute;
|
||||||
|
left: 15px;
|
||||||
|
top: 10px;
|
||||||
|
font-family: Raleway-SemiBold;
|
||||||
|
font-size: 18px;
|
||||||
|
color: white;
|
||||||
|
text-shadow: 2px 2px 3px #000000;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
// END styling of snapshot pane and its contents
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
// START styling of share bar
|
||||||
|
*/
|
||||||
|
.shareControls {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
height: 50px;
|
||||||
|
line-height: 60px;
|
||||||
|
width: calc(100% - 8px);
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%;
|
bottom: 4px;
|
||||||
left: 50%;
|
left: 4px;
|
||||||
transform: translate(-50%, -50%);
|
right: 4px;
|
||||||
vertical-align: middle;
|
|
||||||
}
|
}
|
||||||
|
.shareButtons {
|
||||||
#snapshot-images div.property {
|
display: flex;
|
||||||
margin-top: 0;
|
align-items: center;
|
||||||
|
margin-left: 30px;
|
||||||
|
height: 100%;
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
.blastToConnections {
|
||||||
|
text-align: left;
|
||||||
|
margin-right: 25px;
|
||||||
|
height: 29px;
|
||||||
|
}
|
||||||
|
.shareWithEveryone {
|
||||||
|
background: #DDDDDD url(../img/shareToFeed.png) no-repeat scroll center;
|
||||||
|
border-width: 0px;
|
||||||
|
text-align: left;
|
||||||
|
margin-right: 8px;
|
||||||
|
height: 29px;
|
||||||
|
width: 30px;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
.facebookButton {
|
||||||
|
background-image: url(../img/fb_logo.png);
|
||||||
|
width: 29px;
|
||||||
|
height: 29px;
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
.twitterButton {
|
||||||
|
background-image: url(../img/twitter_logo.png);
|
||||||
|
width: 29px;
|
||||||
|
height: 29px;
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 8px;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
.showShareButtonsButtonDiv {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
font-family: Raleway-SemiBold;
|
||||||
|
font-size: 14px;
|
||||||
|
color: white;
|
||||||
|
text-shadow: 2px 2px 3px #000000;
|
||||||
|
height: 100%;
|
||||||
|
margin-right: 10px;
|
||||||
|
width: 20%;
|
||||||
|
}
|
||||||
|
.showShareButton {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 50%;
|
||||||
|
border-width: 0;
|
||||||
|
margin-left: 5px;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
.showShareButton.active {
|
||||||
|
border-color: #00b4ef;
|
||||||
|
border-width: 3px;
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
.showShareButton.active:hover {
|
||||||
|
background-color: #afafaf;
|
||||||
|
}
|
||||||
|
.showShareButton.active:active {
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
.showShareButton.inactive {
|
||||||
|
border-width: 0;
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
.showShareButton.inactive:hover {
|
||||||
|
background-color: #afafaf;
|
||||||
|
}
|
||||||
|
.showShareButton.inactive:active {
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
.showShareButtonDots {
|
||||||
|
display: flex;
|
||||||
|
width: 32px;
|
||||||
|
height: 40px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%;
|
top: 5px;
|
||||||
left: 7px;
|
right: 14px;
|
||||||
transform: translate(0%, -50%);
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
.showShareButtonDots > span {
|
||||||
#snapshot-images img {
|
width: 10px;
|
||||||
box-sizing: border-box;
|
height: 10px;
|
||||||
padding: 0 7px 0 7px;
|
margin: auto;
|
||||||
}
|
background-color: #0093C5;
|
||||||
|
border-radius: 50%;
|
||||||
#snapshot-images img.multiple {
|
border-width: 0;
|
||||||
padding-left: 28px;
|
display: inline;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
// END styling of share overlay
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
// START styling of snapshot controls (bottom panel) and its contents
|
||||||
|
*/
|
||||||
#snapshot-controls {
|
#snapshot-controls {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
bottom: 14px;
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
#snap-settings {
|
||||||
|
display: inline;
|
||||||
|
width: 150px;
|
||||||
|
margin: 2px auto 0 auto;
|
||||||
|
}
|
||||||
|
#snap-settings form input {
|
||||||
|
margin-bottom: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.prompt {
|
#snap-button {
|
||||||
font-family: Raleway-SemiBold;
|
width: 72px;
|
||||||
font-size: 14px;
|
height: 72px;
|
||||||
}
|
|
||||||
|
|
||||||
div.button {
|
|
||||||
padding-top: 21px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.compound-button {
|
|
||||||
position: relative;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.compound-button input {
|
|
||||||
padding-left: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.compound-button .glyph {
|
|
||||||
display: inline-block;
|
|
||||||
position: absolute;
|
|
||||||
left: 12px;
|
|
||||||
top: 16px;
|
|
||||||
width: 23px;
|
|
||||||
height: 23px;
|
|
||||||
background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgaGVpZ2h0PSI0MCIKICAgd2lkdGg9IjQwIgogICBpZD0ic3ZnMiIKICAgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIKICAgdmlld0JveD0iMCAwIDQwIDQwIgogICB5PSIwcHgiCiAgIHg9IjBweCIKICAgdmVyc2lvbj0iMS4xIj48bWV0YWRhdGEKICAgICBpZD0ibWV0YWRhdGEzNCI+PHJkZjpSREY+PGNjOldvcmsKICAgICAgICAgcmRmOmFib3V0PSIiPjxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PjxkYzp0eXBlCiAgICAgICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIgLz48ZGM6dGl0bGU+PC9kYzp0aXRsZT48L2NjOldvcms+PC9yZGY6UkRGPjwvbWV0YWRhdGE+PGRlZnMKICAgICBpZD0iZGVmczMyIiAvPjxzdHlsZQogICAgIGlkPSJzdHlsZTQiCiAgICAgdHlwZT0idGV4dC9jc3MiPgoJLnN0MHtmaWxsOiM0MTQwNDI7fQoJLnN0MXtmaWxsOiNDQ0NDQ0M7fQoJLnN0MntmaWxsOiMxMzk4QkI7fQoJLnN0M3tmaWxsOiMzMUQ4RkY7fQo8L3N0eWxlPjxnCiAgICAgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwtMTEwKSIKICAgICBpZD0iTGF5ZXJfMSI+PGNpcmNsZQogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtmaWxsLW9wYWNpdHk6MSIKICAgICAgIGlkPSJjaXJjbGUxMyIKICAgICAgIHI9IjQuNDQwMDAwMSIKICAgICAgIGN5PSIxMjYuMTciCiAgICAgICBjeD0iMjAuNTQwMDAxIgogICAgICAgY2xhc3M9InN0MSIgLz48cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtmaWxsLW9wYWNpdHk6MSIKICAgICAgIGlkPSJwYXRoMTUiCiAgICAgICBkPSJtIDI4Ljg3LDEzOS4yNiBjIDAuMDEsLTAuMDEgMC4wMiwtMC4wMiAwLjAzLC0wLjAzIGwgMCwtMS44NiBjIDAsLTIuNjggLTIuMzMsLTQuNzcgLTUsLTQuNzcgbCAtNi40MiwwIGMgLTIuNjgsMCAtNC44NSwyLjA5IC00Ljg1LDQuNzcgbCAwLDEuODggMTYuMjQsMCB6IgogICAgICAgY2xhc3M9InN0MSIgLz48cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtmaWxsLW9wYWNpdHk6MSIKICAgICAgIGlkPSJwYXRoMTciCiAgICAgICBkPSJtIDM4LjE3LDEyMy40MiBjIDAsLTMuOTcgLTMuMjIsLTcuMTkgLTcuMTksLTcuMTkgbCAtMjAuMzEsMCBjIC0zLjk3LDAgLTcuMTksMy4yMiAtNy4xOSw3LjE5IGwgMCwxNC4xOCBjIDAsMy45NyAzLjIyLDcuMTkgNy4xOSw3LjE5IGwgMjAuMzEsMCBjIDMuOTcsMCA3LjE5LC0zLjIyIDcuMTksLTcuMTkgbCAwLC0xNC4xOCB6IG0gLTEuNzgsMTQuMjcgYyAwLDMuMDMgLTIuNDYsNS40OSAtNS40OSw1LjQ5IGwgLTIwLjMyLDAgYyAtMy4wMywwIC01LjQ5LC0yLjQ2IC01LjQ5LC01LjQ5IGwgMCwtMTQuMTkgYyAwLC0zLjAzIDIuNDYsLTUuNDkgNS40OSwtNS40OSBsIDIwLjMzLDAgYyAzLjAzLDAgNS40OSwyLjQ2IDUuNDksNS40OSBsIDAsMTQuMTkgeiIKICAgICAgIGNsYXNzPSJzdDEiIC8+PC9nPjxnCiAgICAgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwtMTEwKSIKICAgICBpZD0iTGF5ZXJfMiIgLz48L3N2Zz4=);
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-size: 23px 23px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.setting {
|
|
||||||
display: inline-table;
|
|
||||||
height: 28px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.setting label {
|
|
||||||
display: table-cell;
|
|
||||||
vertical-align: middle;
|
|
||||||
font-family: Raleway-SemiBold;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.setting + .setting {
|
|
||||||
margin-left: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type=button].naked {
|
|
||||||
font-size: 40px;
|
|
||||||
line-height: 40px;
|
|
||||||
width: 30px;
|
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0 0 -6px 0;
|
border-radius: 50%;
|
||||||
position: relative;
|
background: #EA4C5F;
|
||||||
top: -6px;
|
border: 3px solid white;
|
||||||
left: -8px;
|
margin: 2px auto 0 auto;
|
||||||
background: none;
|
box-sizing: content-box;
|
||||||
|
display: inline;
|
||||||
|
outline:none;
|
||||||
}
|
}
|
||||||
|
#snap-button:disabled {
|
||||||
|
background: gray;
|
||||||
|
}
|
||||||
|
#snap-button:hover:enabled {
|
||||||
|
background: #C62147;
|
||||||
|
}
|
||||||
|
#snap-button:active:enabled {
|
||||||
|
background: #EA4C5F;
|
||||||
|
}
|
||||||
|
#snap-settings-right {
|
||||||
|
display: inline;
|
||||||
|
width: 150px;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
// END styling of snapshot controls (bottom panel) and its contents
|
||||||
|
*/
|
||||||
|
|
||||||
input[type=button].naked:hover {
|
/*
|
||||||
color: #00b4ef;
|
// START misc styling
|
||||||
background: none;
|
*/
|
||||||
|
body {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
p {
|
||||||
|
margin: 2px 0;
|
||||||
|
}
|
||||||
|
h4 {
|
||||||
|
margin: 14px 0 0 0;
|
||||||
|
}
|
||||||
|
.centeredImage {
|
||||||
|
margin: 0 auto;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
// END misc styling
|
||||||
|
*/
|
||||||
|
|
170
scripts/system/html/css/hifi-style.css
Normal file
170
scripts/system/html/css/hifi-style.css
Normal file
|
@ -0,0 +1,170 @@
|
||||||
|
/*
|
||||||
|
// hifi-style.css
|
||||||
|
//
|
||||||
|
// Created by Zach Fox on 2017-04-18
|
||||||
|
// Copyright 2017 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: Raleway-Regular;
|
||||||
|
src: url(../../../../resources/fonts/Raleway-Regular.ttf), /* Windows production */
|
||||||
|
url(../../../../fonts/Raleway-Regular.ttf), /* OSX production */
|
||||||
|
url(../../../../interface/resources/fonts/Raleway-Regular.ttf); /* Development, running script in /HiFi/examples */
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: Raleway-Light;
|
||||||
|
src: url(../../../../resources/fonts/Raleway-Light.ttf),
|
||||||
|
url(../../../../fonts/Raleway-Light.ttf),
|
||||||
|
url(../../../../interface/resources/fonts/Raleway-Light.ttf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: Raleway-Bold;
|
||||||
|
src: url(../../../../resources/fonts/Raleway-Bold.ttf),
|
||||||
|
url(../../../../fonts/Raleway-Bold.ttf),
|
||||||
|
url(../../../../interface/resources/fonts/Raleway-Bold.ttf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: Raleway-SemiBold;
|
||||||
|
src: url(../../../../resources/fonts/Raleway-SemiBold.ttf),
|
||||||
|
url(../../../../fonts/Raleway-SemiBold.ttf),
|
||||||
|
url(../../../../interface/resources/fonts/Raleway-SemiBold.ttf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: FiraSans-SemiBold;
|
||||||
|
src: url(../../../../resources/fonts/FiraSans-SemiBold.ttf),
|
||||||
|
url(../../../../fonts/FiraSans-SemiBold.ttf),
|
||||||
|
url(../../../../interface/resources/fonts/FiraSans-SemiBold.ttf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: AnonymousPro-Regular;
|
||||||
|
src: url(../../../../resources/fonts/AnonymousPro-Regular.ttf),
|
||||||
|
url(../../../../fonts/AnonymousPro-Regular.ttf),
|
||||||
|
url(../../../../interface/resources/fonts/AnonymousPro-Regular.ttf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: HiFi-Glyphs;
|
||||||
|
src: url(../../../../resources/fonts/hifi-glyphs.ttf),
|
||||||
|
url(../../../../fonts/hifi-glyphs.ttf),
|
||||||
|
url(../../../../interface/resources/fonts/hifi-glyphs.ttf);
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
color: #afafaf;
|
||||||
|
background-color: #404040;
|
||||||
|
font-family: Raleway-Regular;
|
||||||
|
font-size: 15px;
|
||||||
|
|
||||||
|
-webkit-touch-callout: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-khtml-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
border: none;
|
||||||
|
background: #404040 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAYAAACp8Z5+AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAAjSURBVBhXY1RVVf3PgARYjIyMoEwIYHRwcEBRwQSloYCBAQCwjgPMiI7W2QAAAABJRU5ErkJggg==) repeat-x top left;
|
||||||
|
padding: 1px;
|
||||||
|
-webkit-margin-before: 0;
|
||||||
|
-webkit-margin-after: 0;
|
||||||
|
-webkit-margin-start: 0;
|
||||||
|
-webkit-margin-end: 0;
|
||||||
|
width: 100%;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hifi-glyph {
|
||||||
|
font-family: HiFi-Glyphs;
|
||||||
|
border: none;
|
||||||
|
//margin: -10px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=radio] {
|
||||||
|
width: 2em;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-size: 1em;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
input[type=radio] + label{
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: -2em;
|
||||||
|
line-height: 2em;
|
||||||
|
}
|
||||||
|
input[type=radio] + label > span{
|
||||||
|
display: inline-block;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
margin: 5px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #6B6A6B;
|
||||||
|
background-image: linear-gradient(#7D7D7D, #6B6A6B);
|
||||||
|
vertical-align: bottom;
|
||||||
|
}
|
||||||
|
input[type=radio]:checked + label > span{
|
||||||
|
background-image: linear-gradient(#7D7D7D, #6B6A6B);
|
||||||
|
}
|
||||||
|
input[type=radio]:active + label > span,
|
||||||
|
input[type=radio]:hover + label > span{
|
||||||
|
background-image: linear-gradient(#FFFFFF, #AFAFAF);
|
||||||
|
}
|
||||||
|
input[type=radio]:checked + label > span > span,
|
||||||
|
input[type=radio]:active + label > span > span{
|
||||||
|
display: block;
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
margin: 3px;
|
||||||
|
border: 2px solid #36CDFF;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #00B4EF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grayButton {
|
||||||
|
font-family: FiraSans-SemiBold;
|
||||||
|
color: white;
|
||||||
|
padding: 0px 10px;
|
||||||
|
border-width: 0px;
|
||||||
|
background-image: linear-gradient(#FFFFFF, #AFAFAF);
|
||||||
|
}
|
||||||
|
.grayButton:hover {
|
||||||
|
background-image: linear-gradient(#FFFFFF, #FFFFFF);
|
||||||
|
}
|
||||||
|
.grayButton:active {
|
||||||
|
background-image: linear-gradient(#AFAFAF, #AFAFAF);
|
||||||
|
}
|
||||||
|
.grayButton:disabled {
|
||||||
|
background-image: linear-gradient(#FFFFFF, ##AFAFAF);
|
||||||
|
}
|
||||||
|
.blueButton {
|
||||||
|
font-family: FiraSans-SemiBold;
|
||||||
|
color: white;
|
||||||
|
padding: 0px 10px;
|
||||||
|
border-radius: 3px;
|
||||||
|
border-width: 0px;
|
||||||
|
background-image: linear-gradient(#00B4EF, #1080B8);
|
||||||
|
min-height: 30px;
|
||||||
|
|
||||||
|
}
|
||||||
|
.blueButton:hover {
|
||||||
|
background-image: linear-gradient(#00B4EF, #00B4EF);
|
||||||
|
}
|
||||||
|
.blueButton:active {
|
||||||
|
background-image: linear-gradient(#1080B8, #1080B8);
|
||||||
|
}
|
||||||
|
.blueButton:disabled {
|
||||||
|
background-image: linear-gradient(#FFFFFF, #AFAFAF);
|
||||||
|
}
|
BIN
scripts/system/html/img/fb_logo.png
Normal file
BIN
scripts/system/html/img/fb_logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
BIN
scripts/system/html/img/shareIcon.png
Normal file
BIN
scripts/system/html/img/shareIcon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
BIN
scripts/system/html/img/shareToFeed.png
Normal file
BIN
scripts/system/html/img/shareToFeed.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
BIN
scripts/system/html/img/snapshotIcon.png
Normal file
BIN
scripts/system/html/img/snapshotIcon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
BIN
scripts/system/html/img/twitter_logo.png
Normal file
BIN
scripts/system/html/img/twitter_logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 552 B |
|
@ -10,117 +10,325 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
var paths = [], idCounter = 0, imageCount;
|
var paths = [];
|
||||||
function addImage(data) {
|
var idCounter = 0;
|
||||||
if (!data.localPath) {
|
var imageCount = 0;
|
||||||
|
function showSetupInstructions() {
|
||||||
|
var snapshotImagesDiv = document.getElementById("snapshot-images");
|
||||||
|
snapshotImagesDiv.className = "snapshotInstructions";
|
||||||
|
snapshotImagesDiv.innerHTML = '<img class="centeredImage" src="./img/snapshotIcon.png" alt="Snapshot Instructions" width="64" height="64"/>' +
|
||||||
|
'<br/>' +
|
||||||
|
'<p>This app lets you take and share snaps and GIFs with your connections in High Fidelity.</p>' +
|
||||||
|
"<h4>Setup Instructions</h4>" +
|
||||||
|
"<p>Before you can begin taking snaps, please choose where you'd like to save snaps on your computer:</p>" +
|
||||||
|
'<br/>' +
|
||||||
|
'<div style="text-align:center;">' +
|
||||||
|
'<input class="blueButton" style="margin-left:auto;margin-right:auto;width:130px;" type="button" value="CHOOSE" onclick="chooseSnapshotLocation()" />' +
|
||||||
|
'</div>';
|
||||||
|
document.getElementById("snap-button").disabled = true;
|
||||||
|
}
|
||||||
|
function showSetupComplete() {
|
||||||
|
var snapshotImagesDiv = document.getElementById("snapshot-images");
|
||||||
|
snapshotImagesDiv.className = "snapshotInstructions";
|
||||||
|
snapshotImagesDiv.innerHTML = '<img class="centeredImage" src="./img/snapshotIcon.png" alt="Snapshot Instructions" width="64" height="64"/>' +
|
||||||
|
'<br/>' +
|
||||||
|
"<h4>You're all set!</h4>" +
|
||||||
|
'<p>Try taking a snapshot by pressing the red button below.</p>';
|
||||||
|
}
|
||||||
|
function chooseSnapshotLocation() {
|
||||||
|
EventBridge.emitWebEvent(JSON.stringify({
|
||||||
|
type: "snapshot",
|
||||||
|
action: "chooseSnapshotLocation"
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
function clearImages() {
|
||||||
|
document.getElementById("snap-button").disabled = false;
|
||||||
|
var snapshotImagesDiv = document.getElementById("snapshot-images");
|
||||||
|
snapshotImagesDiv.classList.remove("snapshotInstructions");
|
||||||
|
while (snapshotImagesDiv.hasChildNodes()) {
|
||||||
|
snapshotImagesDiv.removeChild(snapshotImagesDiv.lastChild);
|
||||||
|
}
|
||||||
|
paths = [];
|
||||||
|
imageCount = 0;
|
||||||
|
idCounter = 0;
|
||||||
|
}
|
||||||
|
function addImage(image_data, isGifLoading, isShowingPreviousImages, canSharePreviousImages, hifiShareButtonsDisabled) {
|
||||||
|
if (!image_data.localPath) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var div = document.createElement("DIV"),
|
var id = "p" + idCounter++;
|
||||||
input = document.createElement("INPUT"),
|
// imageContainer setup
|
||||||
label = document.createElement("LABEL"),
|
var imageContainer = document.createElement("DIV");
|
||||||
img = document.createElement("IMG"),
|
imageContainer.id = id;
|
||||||
div2 = document.createElement("DIV"),
|
imageContainer.style.width = "100%";
|
||||||
id = "p" + idCounter++;
|
imageContainer.style.height = "251px";
|
||||||
img.id = id + "img";
|
imageContainer.style.display = "flex";
|
||||||
function toggle() { data.share = input.checked; }
|
imageContainer.style.justifyContent = "center";
|
||||||
div.style.height = "" + Math.floor(100 / imageCount) + "%";
|
imageContainer.style.alignItems = "center";
|
||||||
|
imageContainer.style.position = "relative";
|
||||||
|
// img setup
|
||||||
|
var img = document.createElement("IMG");
|
||||||
|
img.id = id + "img";
|
||||||
if (imageCount > 1) {
|
if (imageCount > 1) {
|
||||||
img.setAttribute("class", "multiple");
|
img.setAttribute("class", "multiple");
|
||||||
}
|
}
|
||||||
img.src = data.localPath;
|
img.src = image_data.localPath;
|
||||||
div.appendChild(img);
|
imageContainer.appendChild(img);
|
||||||
if (imageCount > 1) { // I'd rather use css, but the included stylesheet is quite particular.
|
document.getElementById("snapshot-images").appendChild(imageContainer);
|
||||||
// Our stylesheet(?) requires input.id to match label.for. Otherwise input doesn't display the check state.
|
paths.push(image_data.localPath);
|
||||||
label.setAttribute('for', id); // cannot do label.for =
|
var isGif = img.src.split('.').pop().toLowerCase() === "gif";
|
||||||
input.id = id;
|
if (isGif) {
|
||||||
input.type = "checkbox";
|
imageContainer.innerHTML += '<span class="gifLabel">GIF</span>';
|
||||||
input.checked = false;
|
}
|
||||||
data.share = input.checked;
|
if (!isGifLoading && !isShowingPreviousImages) {
|
||||||
input.addEventListener('change', toggle);
|
shareForUrl(id);
|
||||||
div2.setAttribute("class", "property checkbox");
|
} else if (isShowingPreviousImages && canSharePreviousImages) {
|
||||||
div2.appendChild(input);
|
appendShareBar(id, image_data.story_id, isGif, hifiShareButtonsDisabled)
|
||||||
div2.appendChild(label);
|
|
||||||
div.appendChild(div2);
|
|
||||||
} else {
|
|
||||||
data.share = true;
|
|
||||||
}
|
}
|
||||||
document.getElementById("snapshot-images").appendChild(div);
|
|
||||||
paths.push(data);
|
|
||||||
}
|
}
|
||||||
function handleShareButtons(messageOptions) {
|
function appendShareBar(divID, story_id, isGif, hifiShareButtonsDisabled) {
|
||||||
var openFeed = document.getElementById('openFeed');
|
var story_url = "https://highfidelity.com/user_stories/" + story_id;
|
||||||
openFeed.checked = messageOptions.openFeedAfterShare;
|
var parentDiv = document.getElementById(divID);
|
||||||
openFeed.onchange = function () {
|
parentDiv.setAttribute('data-story-id', story_id);
|
||||||
|
document.getElementById(divID).appendChild(createShareBar(divID, isGif, story_url, hifiShareButtonsDisabled));
|
||||||
|
if (divID === "p0") {
|
||||||
|
selectImageToShare(divID, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function createShareBar(parentID, isGif, shareURL, hifiShareButtonsDisabled) {
|
||||||
|
var shareBar = document.createElement("div");
|
||||||
|
shareBar.id = parentID + "shareBar";
|
||||||
|
shareBar.className = "shareControls";
|
||||||
|
var shareButtonsDivID = parentID + "shareButtonsDiv";
|
||||||
|
var showShareButtonsButtonDivID = parentID + "showShareButtonsButtonDiv";
|
||||||
|
var showShareButtonsButtonID = parentID + "showShareButtonsButton";
|
||||||
|
var showShareButtonsLabelID = parentID + "showShareButtonsLabel";
|
||||||
|
var blastToConnectionsButtonID = parentID + "blastToConnectionsButton";
|
||||||
|
var shareWithEveryoneButtonID = parentID + "shareWithEveryoneButton";
|
||||||
|
var facebookButtonID = parentID + "facebookButton";
|
||||||
|
var twitterButtonID = parentID + "twitterButton";
|
||||||
|
shareBar.innerHTML += '' +
|
||||||
|
'<div class="shareButtons" id="' + shareButtonsDivID + '" style="visibility:hidden">' +
|
||||||
|
'<input type="button"' + (hifiShareButtonsDisabled ? ' disabled' : '') + ' class="blastToConnections blueButton" id="' + blastToConnectionsButtonID + '" value="BLAST TO MY CONNECTIONS" onclick="blastToConnections(' + parentID + ', ' + isGif + ')" />' +
|
||||||
|
'<input type="button"' + (hifiShareButtonsDisabled ? ' disabled' : '') + ' class="shareWithEveryone" id="' + shareWithEveryoneButtonID + '" onclick="shareWithEveryone(' + parentID + ', ' + isGif + ')" />' +
|
||||||
|
'<a class="facebookButton" id="' + facebookButtonID + '" onclick="shareButtonClicked(' + parentID + ')" target="_blank" href="https://www.facebook.com/dialog/feed?app_id=1585088821786423&link=' + shareURL + '"></a>' +
|
||||||
|
'<a class="twitterButton" id="' + twitterButtonID + '" onclick="shareButtonClicked(' + parentID + ')" target="_blank" href="https://twitter.com/intent/tweet?text=I%20just%20took%20a%20snapshot!&url=' + shareURL + '&via=highfidelity&hashtags=VR,HiFi"></a>' +
|
||||||
|
'</div>' +
|
||||||
|
'<div class="showShareButtonsButtonDiv" id="' + showShareButtonsButtonDivID + '">' +
|
||||||
|
'<label id="' + showShareButtonsLabelID + '" for="' + showShareButtonsButtonID + '">SHARE</label>' +
|
||||||
|
'<input type="button" class="showShareButton inactive" id="' + showShareButtonsButtonID + '" onclick="selectImageToShare(' + parentID + ', true)" />' +
|
||||||
|
'<div class="showShareButtonDots">' +
|
||||||
|
'<span></span><span></span><span></span>' +
|
||||||
|
'</div>' +
|
||||||
|
'</div>';
|
||||||
|
|
||||||
|
// Add onclick handler to parent DIV's img to toggle share buttons
|
||||||
|
document.getElementById(parentID + 'img').onclick = function () { selectImageToShare(parentID, true) };
|
||||||
|
|
||||||
|
return shareBar;
|
||||||
|
}
|
||||||
|
function selectImageToShare(selectedID, isSelected) {
|
||||||
|
if (selectedID.id) {
|
||||||
|
selectedID = selectedID.id; // sometimes (?), `selectedID` is passed as an HTML object to these functions; we just want the ID
|
||||||
|
}
|
||||||
|
var imageContainer = document.getElementById(selectedID);
|
||||||
|
var image = document.getElementById(selectedID + 'img');
|
||||||
|
var shareBar = document.getElementById(selectedID + "shareBar");
|
||||||
|
var shareButtonsDiv = document.getElementById(selectedID + "shareButtonsDiv");
|
||||||
|
var showShareButtonsButton = document.getElementById(selectedID + "showShareButtonsButton");
|
||||||
|
|
||||||
|
if (isSelected) {
|
||||||
|
showShareButtonsButton.onclick = function () { selectImageToShare(selectedID, false) };
|
||||||
|
showShareButtonsButton.classList.remove("inactive");
|
||||||
|
showShareButtonsButton.classList.add("active");
|
||||||
|
|
||||||
|
image.onclick = function () { selectImageToShare(selectedID, false) };
|
||||||
|
imageContainer.style.outline = "4px solid #00b4ef";
|
||||||
|
imageContainer.style.outlineOffset = "-4px";
|
||||||
|
|
||||||
|
shareBar.style.backgroundColor = "rgba(0, 0, 0, 0.5)";
|
||||||
|
|
||||||
|
shareButtonsDiv.style.visibility = "visible";
|
||||||
|
} else {
|
||||||
|
showShareButtonsButton.onclick = function () { selectImageToShare(selectedID, true) };
|
||||||
|
showShareButtonsButton.classList.remove("active");
|
||||||
|
showShareButtonsButton.classList.add("inactive");
|
||||||
|
|
||||||
|
image.onclick = function () { selectImageToShare(selectedID, true) };
|
||||||
|
imageContainer.style.outline = "none";
|
||||||
|
|
||||||
|
shareBar.style.backgroundColor = "rgba(0, 0, 0, 0.0)";
|
||||||
|
|
||||||
|
shareButtonsDiv.style.visibility = "hidden";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function shareForUrl(selectedID) {
|
||||||
|
EventBridge.emitWebEvent(JSON.stringify({
|
||||||
|
type: "snapshot",
|
||||||
|
action: "shareSnapshotForUrl",
|
||||||
|
data: paths[parseInt(selectedID.substring(1))]
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
function blastToConnections(selectedID, isGif) {
|
||||||
|
selectedID = selectedID.id; // `selectedID` is passed as an HTML object to these functions; we just want the ID
|
||||||
|
|
||||||
|
document.getElementById(selectedID + "blastToConnectionsButton").disabled = true;
|
||||||
|
document.getElementById(selectedID + "shareWithEveryoneButton").disabled = true;
|
||||||
|
|
||||||
|
EventBridge.emitWebEvent(JSON.stringify({
|
||||||
|
type: "snapshot",
|
||||||
|
action: "blastToConnections",
|
||||||
|
story_id: document.getElementById(selectedID).getAttribute("data-story-id"),
|
||||||
|
isGif: isGif
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
function shareWithEveryone(selectedID, isGif) {
|
||||||
|
selectedID = selectedID.id; // `selectedID` is passed as an HTML object to these functions; we just want the ID
|
||||||
|
|
||||||
|
document.getElementById(selectedID + "blastToConnectionsButton").disabled = true;
|
||||||
|
document.getElementById(selectedID + "shareWithEveryoneButton").disabled = true;
|
||||||
|
|
||||||
|
EventBridge.emitWebEvent(JSON.stringify({
|
||||||
|
type: "snapshot",
|
||||||
|
action: "shareSnapshotWithEveryone",
|
||||||
|
story_id: document.getElementById(selectedID).getAttribute("data-story-id"),
|
||||||
|
isGif: isGif
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
function shareButtonClicked(selectedID) {
|
||||||
|
selectedID = selectedID.id; // `selectedID` is passed as an HTML object to these functions; we just want the ID
|
||||||
|
EventBridge.emitWebEvent(JSON.stringify({
|
||||||
|
type: "snapshot",
|
||||||
|
action: "shareButtonClicked",
|
||||||
|
story_id: document.getElementById(selectedID).getAttribute("data-story-id")
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
function cancelSharing(selectedID) {
|
||||||
|
selectedID = selectedID.id; // `selectedID` is passed as an HTML object to these functions; we just want the ID
|
||||||
|
var shareBar = document.getElementById(selectedID + "shareBar");
|
||||||
|
|
||||||
|
shareBar.style.display = "inline";
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleCaptureSetting(setting) {
|
||||||
|
var stillAndGif = document.getElementById('stillAndGif');
|
||||||
|
var stillOnly = document.getElementById('stillOnly');
|
||||||
|
stillAndGif.checked = setting;
|
||||||
|
stillOnly.checked = !setting;
|
||||||
|
|
||||||
|
stillAndGif.onclick = function () {
|
||||||
EventBridge.emitWebEvent(JSON.stringify({
|
EventBridge.emitWebEvent(JSON.stringify({
|
||||||
type: "snapshot",
|
type: "snapshot",
|
||||||
action: (openFeed.checked ? "setOpenFeedTrue" : "setOpenFeedFalse")
|
action: "captureStillAndGif"
|
||||||
}));
|
}));
|
||||||
};
|
|
||||||
|
|
||||||
if (!messageOptions.canShare) {
|
|
||||||
// this means you may or may not be logged in, but can't share
|
|
||||||
// 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.";
|
|
||||||
}
|
}
|
||||||
|
stillOnly.onclick = function () {
|
||||||
|
EventBridge.emitWebEvent(JSON.stringify({
|
||||||
|
type: "snapshot",
|
||||||
|
action: "captureStillOnly"
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
window.onload = function () {
|
window.onload = function () {
|
||||||
// Something like the following will allow testing in a browser.
|
// Uncomment the line below to test functionality in a browser.
|
||||||
//addImage({localPath: 'c:/Users/howar/OneDrive/Pictures/hifi-snap-by--on-2016-07-27_12-58-43.jpg'});
|
// See definition of "testInBrowser()" to modify tests.
|
||||||
//addImage({ localPath: 'http://lorempixel.com/1512/1680' });
|
//testInBrowser(true);
|
||||||
openEventBridge(function () {
|
openEventBridge(function () {
|
||||||
// Set up a handler for receiving the data, and tell the .js we are ready to receive it.
|
// Set up a handler for receiving the data, and tell the .js we are ready to receive it.
|
||||||
EventBridge.scriptEventReceived.connect(function (message) {
|
EventBridge.scriptEventReceived.connect(function (message) {
|
||||||
|
|
||||||
message = JSON.parse(message);
|
message = JSON.parse(message);
|
||||||
|
|
||||||
if (message.type !== "snapshot") {
|
if (message.type !== "snapshot") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (message.action) {
|
||||||
|
case 'showSetupInstructions':
|
||||||
|
showSetupInstructions();
|
||||||
|
break;
|
||||||
|
case 'snapshotLocationChosen':
|
||||||
|
clearImages();
|
||||||
|
showSetupComplete();
|
||||||
|
break;
|
||||||
|
case 'clearPreviousImages':
|
||||||
|
clearImages();
|
||||||
|
break;
|
||||||
|
case 'showPreviousImages':
|
||||||
|
clearImages();
|
||||||
|
var messageOptions = message.options;
|
||||||
|
imageCount = message.image_data.length;
|
||||||
|
message.image_data.forEach(function (element, idx, array) {
|
||||||
|
addImage(element, true, true, message.canShare, message.image_data[idx].buttonDisabled);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 'addImages':
|
||||||
|
// The last element of the message contents list contains a bunch of options,
|
||||||
|
// including whether or not we can share stuff
|
||||||
|
// The other elements of the list contain image paths.
|
||||||
|
var messageOptions = message.options;
|
||||||
|
|
||||||
// The last element of the message contents list contains a bunch of options,
|
if (messageOptions.containsGif) {
|
||||||
// including whether or not we can share stuff
|
if (messageOptions.processingGif) {
|
||||||
// The other elements of the list contain image paths.
|
imageCount = message.image_data.length + 1; // "+1" for the GIF that'll finish processing soon
|
||||||
var messageOptions = message.action.pop();
|
message.image_data.unshift({ localPath: messageOptions.loadingGifPath });
|
||||||
handleShareButtons(messageOptions);
|
message.image_data.forEach(function (element, idx, array) {
|
||||||
|
addImage(element, idx === 0, false, false);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
var gifPath = message.image_data[0].localPath;
|
||||||
|
var p0img = document.getElementById('p0img');
|
||||||
|
p0img.src = gifPath;
|
||||||
|
|
||||||
if (messageOptions.containsGif) {
|
paths[0] = gifPath;
|
||||||
if (messageOptions.processingGif) {
|
shareForUrl("p0");
|
||||||
imageCount = message.action.length + 1; // "+1" for the GIF that'll finish processing soon
|
}
|
||||||
message.action.unshift({ localPath: messageOptions.loadingGifPath });
|
} else {
|
||||||
message.action.forEach(addImage);
|
imageCount = message.image_data.length;
|
||||||
document.getElementById('p0').disabled = true;
|
message.image_data.forEach(function (element, idx, array) {
|
||||||
} else {
|
addImage(element, false, false, false);
|
||||||
var gifPath = message.action[0].localPath;
|
});
|
||||||
document.getElementById('p0').disabled = false;
|
}
|
||||||
document.getElementById('p0img').src = gifPath;
|
break;
|
||||||
paths[0].localPath = gifPath;
|
case 'captureSettings':
|
||||||
}
|
handleCaptureSetting(message.setting);
|
||||||
} else {
|
break;
|
||||||
imageCount = message.action.length;
|
case 'snapshotUploadComplete':
|
||||||
message.action.forEach(addImage);
|
var isGif = message.image_url.split('.').pop().toLowerCase() === "gif";
|
||||||
|
appendShareBar(isGif || imageCount === 1 ? "p0" : "p1", message.story_id, isGif);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.log("Unknown message action received in SnapshotReview.js.");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
EventBridge.emitWebEvent(JSON.stringify({
|
EventBridge.emitWebEvent(JSON.stringify({
|
||||||
type: "snapshot",
|
type: "snapshot",
|
||||||
action: "ready"
|
action: "ready"
|
||||||
}));
|
}));
|
||||||
});
|
});;
|
||||||
|
|
||||||
};
|
};
|
||||||
// beware of bug: Cannot send objects at top level. (Nested in arrays is fine.)
|
|
||||||
function shareSelected() {
|
|
||||||
EventBridge.emitWebEvent(JSON.stringify({
|
|
||||||
type: "snapshot",
|
|
||||||
action: paths
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
function doNotShare() {
|
|
||||||
EventBridge.emitWebEvent(JSON.stringify({
|
|
||||||
type: "snapshot",
|
|
||||||
action: []
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
function snapshotSettings() {
|
function snapshotSettings() {
|
||||||
EventBridge.emitWebEvent(JSON.stringify({
|
EventBridge.emitWebEvent(JSON.stringify({
|
||||||
type: "snapshot",
|
type: "snapshot",
|
||||||
action: "openSettings"
|
action: "openSettings"
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
function takeSnapshot() {
|
||||||
|
EventBridge.emitWebEvent(JSON.stringify({
|
||||||
|
type: "snapshot",
|
||||||
|
action: "takeSnapshot"
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
function testInBrowser(isTestingSetupInstructions) {
|
||||||
|
if (isTestingSetupInstructions) {
|
||||||
|
showSetupInstructions();
|
||||||
|
} else {
|
||||||
|
imageCount = 1;
|
||||||
|
//addImage({ localPath: 'http://lorempixel.com/553/255' });
|
||||||
|
addImage({ localPath: 'C:/Users/valef/Desktop/hifi-snap-by-zfox-on-2017-04-26_10-26-53.gif' }, false, true, true, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
// Distributed under the Apache License, Version 2.0
|
// Distributed under the Apache License, Version 2.0
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// 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 */
|
/* globals Tablet, Script, HMD, Settings, DialogsManager, Menu, Reticle, OverlayWebWindow, Desktop, Account, MyAvatar, Snapshot */
|
||||||
/* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */
|
/* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */
|
||||||
|
|
||||||
(function() { // BEGIN LOCAL_SCOPE
|
(function() { // BEGIN LOCAL_SCOPE
|
||||||
|
@ -24,28 +24,79 @@ var buttonConnected = false;
|
||||||
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
||||||
var button = tablet.addButton({
|
var button = tablet.addButton({
|
||||||
icon: "icons/tablet-icons/snap-i.svg",
|
icon: "icons/tablet-icons/snap-i.svg",
|
||||||
|
activeIcon: "icons/tablet-icons/snap-a.svg",
|
||||||
text: buttonName,
|
text: buttonName,
|
||||||
sortOrder: 5
|
sortOrder: 5
|
||||||
});
|
});
|
||||||
|
|
||||||
function shouldOpenFeedAfterShare() {
|
var snapshotOptions;
|
||||||
var persisted = Settings.getValue('openFeedAfterShare', true); // might answer true, false, "true", or "false"
|
var imageData = [];
|
||||||
return persisted && (persisted !== 'false');
|
var storyIDsToMaybeDelete = [];
|
||||||
|
var shareAfterLogin = false;
|
||||||
|
var snapshotToShareAfterLogin;
|
||||||
|
var METAVERSE_BASE = location.metaverseServerUrl;
|
||||||
|
|
||||||
|
// It's totally unnecessary to return to C++ to perform many of these requests, such as DELETEing an old story,
|
||||||
|
// POSTING a new one, PUTTING a new audience, or GETTING story data. It's far more efficient to do all of that within JS
|
||||||
|
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 showFeedWindow() {
|
|
||||||
if ((HMD.active && Settings.getValue("hmdTabletBecomesToolbar"))
|
function openLoginWindow() {
|
||||||
|| (!HMD.active && Settings.getValue("desktopTabletBecomesToolbar"))) {
|
if ((HMD.active && Settings.getValue("hmdTabletBecomesToolbar", false))
|
||||||
tablet.loadQMLSource("TabletAddressDialog.qml");
|
|| (!HMD.active && Settings.getValue("desktopTabletBecomesToolbar", true))) {
|
||||||
|
Menu.triggerOption("Login / Sign Up");
|
||||||
} else {
|
} else {
|
||||||
tablet.initialScreen("TabletAddressDialog.qml");
|
tablet.loadQMLOnTop("../../dialogs/TabletLoginDialog.qml");
|
||||||
HMD.openTablet();
|
HMD.openTablet();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var outstanding;
|
|
||||||
var readyData;
|
|
||||||
var shareAfterLogin = false;
|
|
||||||
var snapshotToShareAfterLogin;
|
|
||||||
function onMessage(message) {
|
function onMessage(message) {
|
||||||
// Receives message from the html dialog via the qwebchannel EventBridge. This is complicated by the following:
|
// 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.)
|
// 1. Although we can send POJOs, we cannot receive a toplevel object. (Arrays of POJOs are fine, though.)
|
||||||
|
@ -58,91 +109,257 @@ function onMessage(message) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var isLoggedIn;
|
var isLoggedIn;
|
||||||
var needsLogin = false;
|
|
||||||
switch (message.action) {
|
switch (message.action) {
|
||||||
case 'ready': // Send it.
|
case 'ready': // DOM is ready and page has loaded
|
||||||
tablet.emitScriptEvent(JSON.stringify({
|
tablet.emitScriptEvent(JSON.stringify({
|
||||||
type: "snapshot",
|
type: "snapshot",
|
||||||
action: readyData
|
action: "captureSettings",
|
||||||
|
setting: Settings.getValue("alsoTakeAnimatedSnapshot", true)
|
||||||
}));
|
}));
|
||||||
outstanding = 0;
|
if (Snapshot.getSnapshotsLocation() !== "") {
|
||||||
|
tablet.emitScriptEvent(JSON.stringify({
|
||||||
|
type: "snapshot",
|
||||||
|
action: "showPreviousImages",
|
||||||
|
options: snapshotOptions,
|
||||||
|
image_data: imageData,
|
||||||
|
canShare: !isDomainOpen(Settings.getValue("previousSnapshotDomainID"))
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
tablet.emitScriptEvent(JSON.stringify({
|
||||||
|
type: "snapshot",
|
||||||
|
action: "showSetupInstructions"
|
||||||
|
}));
|
||||||
|
Settings.setValue("previousStillSnapPath", "");
|
||||||
|
Settings.setValue("previousStillSnapStoryID", "");
|
||||||
|
Settings.setValue("previousStillSnapSharingDisabled", false);
|
||||||
|
Settings.setValue("previousAnimatedSnapPath", "");
|
||||||
|
Settings.setValue("previousAnimatedSnapStoryID", "");
|
||||||
|
Settings.setValue("previousAnimatedSnapSharingDisabled", false);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'chooseSnapshotLocation':
|
||||||
|
var snapshotPath = Window.browseDir("Choose Snapshots Directory", "", "");
|
||||||
|
|
||||||
|
if (snapshotPath) { // not cancelled
|
||||||
|
Snapshot.setSnapshotsLocation(snapshotPath);
|
||||||
|
tablet.emitScriptEvent(JSON.stringify({
|
||||||
|
type: "snapshot",
|
||||||
|
action: "snapshotLocationChosen"
|
||||||
|
}));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'openSettings':
|
case 'openSettings':
|
||||||
if ((HMD.active && Settings.getValue("hmdTabletBecomesToolbar"))
|
if ((HMD.active && Settings.getValue("hmdTabletBecomesToolbar", false))
|
||||||
|| (!HMD.active && Settings.getValue("desktopTabletBecomesToolbar"))) {
|
|| (!HMD.active && Settings.getValue("desktopTabletBecomesToolbar", true))) {
|
||||||
Desktop.show("hifi/dialogs/GeneralPreferencesDialog.qml", "General Preferences");
|
Desktop.show("hifi/dialogs/GeneralPreferencesDialog.qml", "General Preferences");
|
||||||
} else {
|
} else {
|
||||||
tablet.loadQMLOnTop("TabletGeneralPreferences.qml");
|
tablet.loadQMLOnTop("TabletGeneralPreferences.qml");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'setOpenFeedFalse':
|
case 'captureStillAndGif':
|
||||||
Settings.setValue('openFeedAfterShare', false);
|
print("Changing Snapshot Capture Settings to Capture Still + GIF");
|
||||||
|
Settings.setValue("alsoTakeAnimatedSnapshot", true);
|
||||||
break;
|
break;
|
||||||
case 'setOpenFeedTrue':
|
case 'captureStillOnly':
|
||||||
Settings.setValue('openFeedAfterShare', true);
|
print("Changing Snapshot Capture Settings to Capture Still Only");
|
||||||
|
Settings.setValue("alsoTakeAnimatedSnapshot", false);
|
||||||
|
break;
|
||||||
|
case 'takeSnapshot':
|
||||||
|
takeSnapshot();
|
||||||
|
break;
|
||||||
|
case 'shareSnapshotForUrl':
|
||||||
|
isLoggedIn = Account.isLoggedIn();
|
||||||
|
if (isLoggedIn) {
|
||||||
|
print('Sharing snapshot with audience "for_url":', message.data);
|
||||||
|
Window.shareSnapshot(message.data, message.href || href);
|
||||||
|
} else {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'blastToConnections':
|
||||||
|
isLoggedIn = Account.isLoggedIn();
|
||||||
|
storyIDsToMaybeDelete.splice(storyIDsToMaybeDelete.indexOf(message.story_id), 1);
|
||||||
|
if (message.isGif) {
|
||||||
|
Settings.setValue("previousAnimatedSnapSharingDisabled", true);
|
||||||
|
} else {
|
||||||
|
Settings.setValue("previousStillSnapSharingDisabled", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isLoggedIn) {
|
||||||
|
print('Uploading new story for announcement!');
|
||||||
|
|
||||||
|
request({
|
||||||
|
uri: METAVERSE_BASE + '/api/v1/user_stories/' + message.story_id,
|
||||||
|
method: 'GET'
|
||||||
|
}, function (error, response) {
|
||||||
|
if (error || (response.status !== 'success')) {
|
||||||
|
print("ERROR getting details about existing snapshot story:", error || response.status);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
var requestBody = {
|
||||||
|
user_story: {
|
||||||
|
audience: "for_connections",
|
||||||
|
action: "announcement",
|
||||||
|
path: response.user_story.path,
|
||||||
|
place_name: response.user_story.place_name,
|
||||||
|
thumbnail_url: response.user_story.thumbnail_url,
|
||||||
|
// For historical reasons, the server doesn't take nested JSON objects.
|
||||||
|
// Thus, I'm required to STRINGIFY what should be a nested object.
|
||||||
|
details: JSON.stringify({
|
||||||
|
shareable_url: response.user_story.details.shareable_url,
|
||||||
|
image_url: response.user_story.details.image_url
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
request({
|
||||||
|
uri: METAVERSE_BASE + '/api/v1/user_stories',
|
||||||
|
method: 'POST',
|
||||||
|
json: true,
|
||||||
|
body: requestBody
|
||||||
|
}, function (error, response) {
|
||||||
|
if (error || (response.status !== 'success')) {
|
||||||
|
print("ERROR uploading announcement story: ", error || response.status);
|
||||||
|
if (message.isGif) {
|
||||||
|
Settings.setValue("previousAnimatedSnapSharingDisabled", false);
|
||||||
|
} else {
|
||||||
|
Settings.setValue("previousStillSnapSharingDisabled", false);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
print("SUCCESS uploading announcement story! Story ID:", response.user_story.id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
openLoginWindow();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'shareSnapshotWithEveryone':
|
||||||
|
isLoggedIn = Account.isLoggedIn();
|
||||||
|
storyIDsToMaybeDelete.splice(storyIDsToMaybeDelete.indexOf(message.story_id), 1);
|
||||||
|
if (message.isGif) {
|
||||||
|
Settings.setValue("previousAnimatedSnapSharingDisabled", true);
|
||||||
|
} else {
|
||||||
|
Settings.setValue("previousStillSnapSharingDisabled", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isLoggedIn) {
|
||||||
|
print('Modifying audience of story ID', message.story_id, "to 'for_feed'");
|
||||||
|
var requestBody = {
|
||||||
|
audience: "for_feed"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.isAnnouncement) {
|
||||||
|
requestBody.action = "announcement";
|
||||||
|
print('...Also announcing!');
|
||||||
|
}
|
||||||
|
request({
|
||||||
|
uri: METAVERSE_BASE + '/api/v1/user_stories/' + message.story_id,
|
||||||
|
method: 'PUT',
|
||||||
|
json: true,
|
||||||
|
body: requestBody
|
||||||
|
}, function (error, response) {
|
||||||
|
if (error || (response.status !== 'success')) {
|
||||||
|
print("ERROR changing audience: ", error || response.status);
|
||||||
|
if (message.isGif) {
|
||||||
|
Settings.setValue("previousAnimatedSnapSharingDisabled", false);
|
||||||
|
} else {
|
||||||
|
Settings.setValue("previousStillSnapSharingDisabled", false);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
print("SUCCESS changing audience" + (message.isAnnouncement ? " and posting announcement!" : "!"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
openLoginWindow();
|
||||||
|
shareAfterLogin = true;
|
||||||
|
snapshotToShareAfterLogin = { path: message.data, href: message.href || href };
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'shareButtonClicked':
|
||||||
|
print('Twitter or FB "Share" button clicked! Removing ID', message.story_id, 'from storyIDsToMaybeDelete[].');
|
||||||
|
storyIDsToMaybeDelete.splice(storyIDsToMaybeDelete.indexOf(message.story_id), 1);
|
||||||
|
print('storyIDsToMaybeDelete[] now:', JSON.stringify(storyIDsToMaybeDelete));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
//tablet.webEventReceived.disconnect(onMessage); // <<< It's probably this that's missing?!
|
print('Unknown message action received by snapshot.js!');
|
||||||
HMD.closeTablet();
|
break;
|
||||||
isLoggedIn = Account.isLoggedIn();
|
|
||||||
message.action.forEach(function (submessage) {
|
|
||||||
if (submessage.share && !isLoggedIn) {
|
|
||||||
needsLogin = true;
|
|
||||||
submessage.share = false;
|
|
||||||
shareAfterLogin = true;
|
|
||||||
snapshotToShareAfterLogin = {path: submessage.localPath, href: submessage.href || href};
|
|
||||||
}
|
|
||||||
if (submessage.share) {
|
|
||||||
print('sharing', submessage.localPath);
|
|
||||||
outstanding = true;
|
|
||||||
Window.shareSnapshot(submessage.localPath, submessage.href || href);
|
|
||||||
} else {
|
|
||||||
print('not sharing', submessage.localPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
if (outstanding && shouldOpenFeedAfterShare()) {
|
|
||||||
showFeedWindow();
|
|
||||||
outstanding = false;
|
|
||||||
}
|
|
||||||
if (needsLogin) { // after the possible feed, so that the login is on top
|
|
||||||
var isLoggedIn = Account.isLoggedIn();
|
|
||||||
|
|
||||||
if (!isLoggedIn) {
|
|
||||||
if ((HMD.active && Settings.getValue("hmdTabletBecomesToolbar"))
|
|
||||||
|| (!HMD.active && Settings.getValue("desktopTabletBecomesToolbar"))) {
|
|
||||||
Menu.triggerOption("Login / Sign Up");
|
|
||||||
} else {
|
|
||||||
tablet.loadQMLOnTop("../../dialogs/TabletLoginDialog.qml");
|
|
||||||
HMD.openTablet();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var SNAPSHOT_REVIEW_URL = Script.resolvePath("html/SnapshotReview.html");
|
var SNAPSHOT_REVIEW_URL = Script.resolvePath("html/SnapshotReview.html");
|
||||||
var isInSnapshotReview = false;
|
var isInSnapshotReview = false;
|
||||||
function confirmShare(data) {
|
var shouldActivateButton = false;
|
||||||
tablet.gotoWebScreen(SNAPSHOT_REVIEW_URL);
|
function onButtonClicked() {
|
||||||
readyData = data;
|
if (isInSnapshotReview){
|
||||||
tablet.webEventReceived.connect(onMessage);
|
// for toolbar-mode: go back to home screen, this will close the window.
|
||||||
HMD.openTablet();
|
tablet.gotoHomeScreen();
|
||||||
isInSnapshotReview = true;
|
} else {
|
||||||
|
shouldActivateButton = true;
|
||||||
|
var previousStillSnapPath = Settings.getValue("previousStillSnapPath");
|
||||||
|
var previousStillSnapStoryID = Settings.getValue("previousStillSnapStoryID");
|
||||||
|
var previousStillSnapSharingDisabled = Settings.getValue("previousStillSnapSharingDisabled");
|
||||||
|
var previousAnimatedSnapPath = Settings.getValue("previousAnimatedSnapPath");
|
||||||
|
var previousAnimatedSnapStoryID = Settings.getValue("previousAnimatedSnapStoryID");
|
||||||
|
var previousAnimatedSnapSharingDisabled = Settings.getValue("previousAnimatedSnapSharingDisabled");
|
||||||
|
snapshotOptions = {
|
||||||
|
containsGif: previousAnimatedSnapPath !== "",
|
||||||
|
processingGif: false,
|
||||||
|
shouldUpload: false
|
||||||
|
}
|
||||||
|
imageData = [];
|
||||||
|
if (previousAnimatedSnapPath !== "") {
|
||||||
|
imageData.push({ localPath: previousAnimatedSnapPath, story_id: previousAnimatedSnapStoryID, buttonDisabled: previousAnimatedSnapSharingDisabled });
|
||||||
|
}
|
||||||
|
if (previousStillSnapPath !== "") {
|
||||||
|
imageData.push({ localPath: previousStillSnapPath, story_id: previousStillSnapStoryID, buttonDisabled: previousStillSnapSharingDisabled });
|
||||||
|
}
|
||||||
|
tablet.gotoWebScreen(SNAPSHOT_REVIEW_URL);
|
||||||
|
tablet.webEventReceived.connect(onMessage);
|
||||||
|
HMD.openTablet();
|
||||||
|
isInSnapshotReview = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function snapshotShared(errorMessage) {
|
function snapshotUploaded(isError, reply) {
|
||||||
if (!errorMessage) {
|
if (!isError) {
|
||||||
print('snapshot uploaded and shared');
|
var replyJson = JSON.parse(reply);
|
||||||
|
var storyID = replyJson.user_story.id;
|
||||||
|
storyIDsToMaybeDelete.push(storyID);
|
||||||
|
var imageURL = replyJson.user_story.details.image_url;
|
||||||
|
var isGif = imageURL.split('.').pop().toLowerCase() === "gif";
|
||||||
|
print('SUCCESS: Snapshot uploaded! Story with audience:for_url created! ID:', storyID);
|
||||||
|
tablet.emitScriptEvent(JSON.stringify({
|
||||||
|
type: "snapshot",
|
||||||
|
action: "snapshotUploadComplete",
|
||||||
|
story_id: storyID,
|
||||||
|
image_url: imageURL,
|
||||||
|
}));
|
||||||
|
if (isGif) {
|
||||||
|
Settings.setValue("previousAnimatedSnapStoryID", storyID);
|
||||||
|
} else {
|
||||||
|
Settings.setValue("previousStillSnapStoryID", storyID);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
print(errorMessage);
|
print(reply);
|
||||||
}
|
|
||||||
if ((--outstanding <= 0) && shouldOpenFeedAfterShare()) {
|
|
||||||
showFeedWindow();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var href, domainId;
|
var href, domainId;
|
||||||
function onClicked() {
|
function takeSnapshot() {
|
||||||
|
tablet.emitScriptEvent(JSON.stringify({
|
||||||
|
type: "snapshot",
|
||||||
|
action: "clearPreviousImages"
|
||||||
|
}));
|
||||||
|
Settings.setValue("previousStillSnapPath", "");
|
||||||
|
Settings.setValue("previousStillSnapStoryID", "");
|
||||||
|
Settings.setValue("previousStillSnapSharingDisabled", false);
|
||||||
|
Settings.setValue("previousAnimatedSnapPath", "");
|
||||||
|
Settings.setValue("previousAnimatedSnapStoryID", "");
|
||||||
|
Settings.setValue("previousAnimatedSnapSharingDisabled", false);
|
||||||
|
|
||||||
// Raising the desktop for the share dialog at end will interact badly with clearOverlayWhenMoving.
|
// 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).
|
// 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.
|
clearOverlayWhenMoving = MyAvatar.getClearOverlayWhenMoving(); // Do not use Settings. MyAvatar keeps a separate copy.
|
||||||
|
@ -152,14 +369,25 @@ function onClicked() {
|
||||||
// Even the domainId could change (e.g., if the user falls into a teleporter while recording).
|
// Even the domainId could change (e.g., if the user falls into a teleporter while recording).
|
||||||
href = location.href;
|
href = location.href;
|
||||||
domainId = location.domainId;
|
domainId = location.domainId;
|
||||||
|
Settings.setValue("previousSnapshotDomainID", domainId);
|
||||||
|
|
||||||
|
maybeDeleteSnapshotStories();
|
||||||
|
|
||||||
// update button states
|
// update button states
|
||||||
resetOverlays = Menu.isOptionChecked("Overlays"); // For completness. Certainly true if the button is visible to be clicke.
|
resetOverlays = Menu.isOptionChecked("Overlays"); // For completeness. Certainly true if the button is visible to be clicked.
|
||||||
reticleVisible = Reticle.visible;
|
reticleVisible = Reticle.visible;
|
||||||
Reticle.visible = false;
|
Reticle.visible = false;
|
||||||
Window.stillSnapshotTaken.connect(stillSnapshotTaken);
|
|
||||||
Window.processingGifStarted.connect(processingGifStarted);
|
var includeAnimated = Settings.getValue("alsoTakeAnimatedSnapshot", true);
|
||||||
Window.processingGifCompleted.connect(processingGifCompleted);
|
if (includeAnimated) {
|
||||||
|
Window.processingGifStarted.connect(processingGifStarted);
|
||||||
|
} else {
|
||||||
|
Window.stillSnapshotTaken.connect(stillSnapshotTaken);
|
||||||
|
}
|
||||||
|
if (buttonConnected) {
|
||||||
|
button.clicked.disconnect(onButtonClicked);
|
||||||
|
buttonConnected = false;
|
||||||
|
}
|
||||||
|
|
||||||
// hide overlays if they are on
|
// hide overlays if they are on
|
||||||
if (resetOverlays) {
|
if (resetOverlays) {
|
||||||
|
@ -170,13 +398,17 @@ function onClicked() {
|
||||||
Script.setTimeout(function () {
|
Script.setTimeout(function () {
|
||||||
HMD.closeTablet();
|
HMD.closeTablet();
|
||||||
Script.setTimeout(function () {
|
Script.setTimeout(function () {
|
||||||
Window.takeSnapshot(false, true, 1.91);
|
Window.takeSnapshot(false, includeAnimated, 1.91);
|
||||||
}, SNAPSHOT_DELAY);
|
}, SNAPSHOT_DELAY);
|
||||||
}, FINISH_SOUND_DELAY);
|
}, FINISH_SOUND_DELAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isDomainOpen(id) {
|
function isDomainOpen(id) {
|
||||||
var request = new XMLHttpRequest();
|
print("Checking open status of domain with ID:", id);
|
||||||
|
if (!id) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
var options = [
|
var options = [
|
||||||
'now=' + new Date().toISOString(),
|
'now=' + new Date().toISOString(),
|
||||||
'include_actions=concurrency',
|
'include_actions=concurrency',
|
||||||
|
@ -184,15 +416,19 @@ function isDomainOpen(id) {
|
||||||
'restriction=open,hifi' // If we're sharing, we're logged in
|
'restriction=open,hifi' // If we're sharing, we're logged in
|
||||||
// If we're here, protocol matches, and it is online
|
// If we're here, protocol matches, and it is online
|
||||||
];
|
];
|
||||||
var url = location.metaverseServerUrl + "/api/v1/user_stories?" + options.join('&');
|
var url = METAVERSE_BASE + "/api/v1/user_stories?" + options.join('&');
|
||||||
request.open("GET", url, false);
|
|
||||||
request.send();
|
return request({
|
||||||
if (request.status !== 200) {
|
uri: url,
|
||||||
return false;
|
method: 'GET'
|
||||||
}
|
}, function (error, response) {
|
||||||
var response = JSON.parse(request.response); // Not parsed for us.
|
if (error || (response.status !== 'success')) {
|
||||||
return (response.status === 'success') &&
|
print("ERROR getting open status of domain: ", error || response.status);
|
||||||
response.total_entries;
|
return false;
|
||||||
|
} else {
|
||||||
|
return response.total_entries;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function stillSnapshotTaken(pathStillSnapshot, notify) {
|
function stillSnapshotTaken(pathStillSnapshot, notify) {
|
||||||
|
@ -203,20 +439,30 @@ function stillSnapshotTaken(pathStillSnapshot, notify) {
|
||||||
Menu.setIsOptionChecked("Overlays", true);
|
Menu.setIsOptionChecked("Overlays", true);
|
||||||
}
|
}
|
||||||
Window.stillSnapshotTaken.disconnect(stillSnapshotTaken);
|
Window.stillSnapshotTaken.disconnect(stillSnapshotTaken);
|
||||||
|
if (!buttonConnected) {
|
||||||
|
button.clicked.connect(onButtonClicked);
|
||||||
|
buttonConnected = true;
|
||||||
|
}
|
||||||
|
|
||||||
// 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
|
||||||
// it records the correct href. (We can also stash in .jpegs, but not .gifs.)
|
// 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
|
// last element in data array tells dialog whether we can share or not
|
||||||
var confirmShareContents = [
|
snapshotOptions = {
|
||||||
{ localPath: pathStillSnapshot, href: href },
|
containsGif: false,
|
||||||
{
|
processingGif: false,
|
||||||
containsGif: false,
|
canShare: !isDomainOpen(domainId)
|
||||||
processingGif: false,
|
};
|
||||||
canShare: !!isDomainOpen(domainId),
|
imageData = [{ localPath: pathStillSnapshot, href: href }];
|
||||||
openFeedAfterShare: shouldOpenFeedAfterShare()
|
Settings.setValue("previousStillSnapPath", pathStillSnapshot);
|
||||||
}];
|
|
||||||
confirmShare(confirmShareContents);
|
tablet.emitScriptEvent(JSON.stringify({
|
||||||
|
type: "snapshot",
|
||||||
|
action: "addImages",
|
||||||
|
options: snapshotOptions,
|
||||||
|
image_data: imageData
|
||||||
|
}));
|
||||||
|
|
||||||
if (clearOverlayWhenMoving) {
|
if (clearOverlayWhenMoving) {
|
||||||
MyAvatar.setClearOverlayWhenMoving(true); // not until after the share dialog
|
MyAvatar.setClearOverlayWhenMoving(true); // not until after the share dialog
|
||||||
}
|
}
|
||||||
|
@ -225,8 +471,7 @@ function stillSnapshotTaken(pathStillSnapshot, notify) {
|
||||||
|
|
||||||
function processingGifStarted(pathStillSnapshot) {
|
function processingGifStarted(pathStillSnapshot) {
|
||||||
Window.processingGifStarted.disconnect(processingGifStarted);
|
Window.processingGifStarted.disconnect(processingGifStarted);
|
||||||
button.clicked.disconnect(onClicked);
|
Window.processingGifCompleted.connect(processingGifCompleted);
|
||||||
buttonConnected = false;
|
|
||||||
// show hud
|
// show hud
|
||||||
Reticle.visible = reticleVisible;
|
Reticle.visible = reticleVisible;
|
||||||
// show overlays if they were on
|
// show overlays if they were on
|
||||||
|
@ -234,16 +479,22 @@ function processingGifStarted(pathStillSnapshot) {
|
||||||
Menu.setIsOptionChecked("Overlays", true);
|
Menu.setIsOptionChecked("Overlays", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
var confirmShareContents = [
|
snapshotOptions = {
|
||||||
{ localPath: pathStillSnapshot, href: href },
|
containsGif: true,
|
||||||
{
|
processingGif: true,
|
||||||
containsGif: true,
|
loadingGifPath: Script.resolvePath(Script.resourcesPath() + 'icons/loadingDark.gif'),
|
||||||
processingGif: true,
|
canShare: !isDomainOpen(domainId)
|
||||||
loadingGifPath: Script.resolvePath(Script.resourcesPath() + 'icons/loadingDark.gif'),
|
};
|
||||||
canShare: !!isDomainOpen(domainId),
|
imageData = [{ localPath: pathStillSnapshot, href: href }];
|
||||||
openFeedAfterShare: shouldOpenFeedAfterShare()
|
Settings.setValue("previousStillSnapPath", pathStillSnapshot);
|
||||||
}];
|
|
||||||
confirmShare(confirmShareContents);
|
tablet.emitScriptEvent(JSON.stringify({
|
||||||
|
type: "snapshot",
|
||||||
|
action: "addImages",
|
||||||
|
options: snapshotOptions,
|
||||||
|
image_data: imageData
|
||||||
|
}));
|
||||||
|
|
||||||
if (clearOverlayWhenMoving) {
|
if (clearOverlayWhenMoving) {
|
||||||
MyAvatar.setClearOverlayWhenMoving(true); // not until after the share dialog
|
MyAvatar.setClearOverlayWhenMoving(true); // not until after the share dialog
|
||||||
}
|
}
|
||||||
|
@ -252,57 +503,72 @@ function processingGifStarted(pathStillSnapshot) {
|
||||||
|
|
||||||
function processingGifCompleted(pathAnimatedSnapshot) {
|
function processingGifCompleted(pathAnimatedSnapshot) {
|
||||||
Window.processingGifCompleted.disconnect(processingGifCompleted);
|
Window.processingGifCompleted.disconnect(processingGifCompleted);
|
||||||
button.clicked.connect(onClicked);
|
if (!buttonConnected) {
|
||||||
buttonConnected = true;
|
button.clicked.connect(onButtonClicked);
|
||||||
|
buttonConnected = true;
|
||||||
|
}
|
||||||
|
|
||||||
var confirmShareContents = [
|
snapshotOptions = {
|
||||||
{ localPath: pathAnimatedSnapshot, href: href },
|
containsGif: true,
|
||||||
{
|
processingGif: false,
|
||||||
containsGif: true,
|
canShare: !isDomainOpen(domainId)
|
||||||
processingGif: false,
|
}
|
||||||
canShare: !!isDomainOpen(domainId),
|
imageData = [{ localPath: pathAnimatedSnapshot, href: href }];
|
||||||
openFeedAfterShare: shouldOpenFeedAfterShare()
|
Settings.setValue("previousAnimatedSnapPath", pathAnimatedSnapshot);
|
||||||
}];
|
|
||||||
readyData = confirmShareContents;
|
|
||||||
|
|
||||||
tablet.emitScriptEvent(JSON.stringify({
|
tablet.emitScriptEvent(JSON.stringify({
|
||||||
type: "snapshot",
|
type: "snapshot",
|
||||||
action: readyData
|
action: "addImages",
|
||||||
|
options: snapshotOptions,
|
||||||
|
image_data: imageData
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
function maybeDeleteSnapshotStories() {
|
||||||
|
storyIDsToMaybeDelete.forEach(function (element, idx, array) {
|
||||||
|
request({
|
||||||
|
uri: METAVERSE_BASE + '/api/v1/user_stories/' + element,
|
||||||
|
method: 'DELETE'
|
||||||
|
}, function (error, response) {
|
||||||
|
if (error || (response.status !== 'success')) {
|
||||||
|
print("ERROR deleting snapshot story: ", error || response.status);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
print("SUCCESS deleting snapshot story with ID", element);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
storyIDsToMaybeDelete = [];
|
||||||
|
}
|
||||||
function onTabletScreenChanged(type, url) {
|
function onTabletScreenChanged(type, url) {
|
||||||
|
button.editProperties({ isActive: shouldActivateButton });
|
||||||
|
shouldActivateButton = false;
|
||||||
if (isInSnapshotReview) {
|
if (isInSnapshotReview) {
|
||||||
tablet.webEventReceived.disconnect(onMessage);
|
tablet.webEventReceived.disconnect(onMessage);
|
||||||
isInSnapshotReview = false;
|
isInSnapshotReview = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function onConnected() {
|
function onUsernameChanged() {
|
||||||
if (shareAfterLogin && Account.isLoggedIn()) {
|
if (shareAfterLogin && Account.isLoggedIn()) {
|
||||||
print('sharing', snapshotToShareAfterLogin.path);
|
print('Sharing snapshot after login:', snapshotToShareAfterLogin.path);
|
||||||
Window.shareSnapshot(snapshotToShareAfterLogin.path, snapshotToShareAfterLogin.href);
|
Window.shareSnapshot(snapshotToShareAfterLogin.path, snapshotToShareAfterLogin.href);
|
||||||
shareAfterLogin = false;
|
shareAfterLogin = false;
|
||||||
if (shouldOpenFeedAfterShare()) {
|
|
||||||
showFeedWindow();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
button.clicked.connect(onClicked);
|
button.clicked.connect(onButtonClicked);
|
||||||
buttonConnected = true;
|
buttonConnected = true;
|
||||||
Window.snapshotShared.connect(snapshotShared);
|
Window.snapshotShared.connect(snapshotUploaded);
|
||||||
tablet.screenChanged.connect(onTabletScreenChanged);
|
tablet.screenChanged.connect(onTabletScreenChanged);
|
||||||
Account.usernameChanged.connect(onConnected);
|
Account.usernameChanged.connect(onUsernameChanged);
|
||||||
Script.scriptEnding.connect(function () {
|
Script.scriptEnding.connect(function () {
|
||||||
if (buttonConnected) {
|
if (buttonConnected) {
|
||||||
button.clicked.disconnect(onClicked);
|
button.clicked.disconnect(onButtonClicked);
|
||||||
buttonConnected = false;
|
buttonConnected = false;
|
||||||
}
|
}
|
||||||
if (tablet) {
|
if (tablet) {
|
||||||
tablet.removeButton(button);
|
tablet.removeButton(button);
|
||||||
}
|
}
|
||||||
Window.snapshotShared.disconnect(snapshotShared);
|
Window.snapshotShared.disconnect(snapshotUploaded);
|
||||||
tablet.screenChanged.disconnect(onTabletScreenChanged);
|
tablet.screenChanged.disconnect(onTabletScreenChanged);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue