Merge pull request #10029 from ctrlaltdavid/21238-b

Snapshot dialog into tablet
This commit is contained in:
Seth Alves 2017-03-28 08:16:42 -07:00 committed by GitHub
commit fa0e2a69a6
4 changed files with 191 additions and 119 deletions

View file

@ -3,45 +3,43 @@
<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/edit-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="qrc:///qtwebchannel/qwebchannel.js"></script>
<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="snapshot-container"> <div class="snapsection title">
<div class="snapshot-column-left"> <label>Snap</label>
<div class="snapsection"> </div>
<label class="title">Snapshot successfully saved!</label> <hr />
</div> <div id="snapshot-pane">
<hr /> <div id="snapshot-images">
<div class="snapsection"> </div>
<div id="sharing"> </div>
<div class="prompt">Would you like to share your pics in the Snapshots feed?</div> <div id="snapshot-controls">
<div class="button"> <div class="snapsection" id="snap-buttons">
<span class="compound-button"> <div id="sharing">
<input type="button" class="blue" id="share" value="Share in Feed" onclick="shareSelected()" />
<span class="glyph"></span>
</span>
</div>
</div>
<div class="button"> <div class="button">
<input type="button" class="black" id="close" value="Don't Share" onclick="doNotShare()" /> <span class="compound-button">
<input type="button" class="blue" id="share" value="Share in Feed" onclick="shareSelected()" />
<span class="glyph"></span>
</span>
</div> </div>
</div> </div>
<hr /> <div class="button">
<div class="snapsection"> <input type="button" class="black" id="close" value="Don't Share" onclick="doNotShare()" />
<span class="setting">
<input type="button" class="glyph naked" id="snapshotSettings" value="@" onclick="snapshotSettings()" />
<label for="snapshotSettings">Snapshot settings</label>
</span>
<span class="setting checkbox">
<input id="openFeed" type="checkbox" checked />
<label for="openFeed">Open feed after</label>
</span>
</div> </div>
</div> </div>
<div id="snapshot-images" class="snapshot-column-right"> <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>
</div> </div>
</body> </body>

View file

@ -8,63 +8,81 @@
// 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 {
.snapshot-container { padding-top: 0;
width: 100%; padding-bottom: 14px;
padding-top: 3px;
}
.snapshot-column-left {
width: 320px;
position: absolute;
padding-top: 8px;
}
.snapshot-column-right {
margin-left: 342px;
}
.snapshot-column-right > div > img {
width: 100%;
}
@media (max-width: 768px) {
.snapshot-column-left {
position: initial;
width: 100%;
}
.snapshot-column-right {
margin-left: 0;
width: 100%;
}
.snapshot-column-right > div > img {
margin-top: 18px !important;
}
}
.snapshot-column-right > div {
position: relative;
padding: 2px;
}
.snapshot-column-right > div > img {
border: 2px solid #575757;
margin: -2px;
}
hr {
padding-left: 0;
padding-right: 0;
margin: 21px 0;
} }
.snapsection { .snapsection {
padding-top: 14px;
text-align: center; text-align: center;
} }
.title { .snapsection.title {
text-transform: uppercase; padding-top: 0;
font-size: 12px; text-align: left;
}
.title label {
font-size: 18px;
position: relative;
top: 12px;
}
#snapshot-pane {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
box-sizing: border-box;
padding-top: 56px;
padding-bottom: 175px;
}
#snapshot-images {
height: 100%;
width: 100%;
position: relative;
}
#snapshot-images > div {
position: relative;
text-align: center;
}
#snapshot-images img {
max-width: 100%;
max-height: 100%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
vertical-align: middle;
}
#snapshot-images div.property {
margin-top: 0;
position: absolute;
top: 50%;
left: 7px;
transform: translate(0%, -50%);
}
#snapshot-images img {
box-sizing: border-box;
padding: 0 7px 0 7px;
}
#snapshot-images img.multiple {
padding-left: 28px;
}
#snapshot-controls {
width: 100%;
position: absolute;
left: 0;
bottom: 14px;
} }
.prompt { .prompt {

View file

@ -10,7 +10,7 @@
// 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, useCheckboxes; var paths = [], idCounter = 0, imageCount;
function addImage(data) { function addImage(data) {
if (!data.localPath) { if (!data.localPath) {
return; return;
@ -19,11 +19,16 @@ function addImage(data) {
input = document.createElement("INPUT"), input = document.createElement("INPUT"),
label = document.createElement("LABEL"), label = document.createElement("LABEL"),
img = document.createElement("IMG"), img = document.createElement("IMG"),
div2 = document.createElement("DIV"),
id = "p" + idCounter++; id = "p" + idCounter++;
function toggle() { data.share = input.checked; } function toggle() { data.share = input.checked; }
div.style.height = "" + Math.floor(100 / imageCount) + "%";
if (imageCount > 1) {
img.setAttribute("class", "multiple");
}
img.src = data.localPath; img.src = data.localPath;
div.appendChild(img); div.appendChild(img);
if (useCheckboxes) { // I'd rather use css, but the included stylesheet is quite particular. if (imageCount > 1) { // I'd rather use css, but the included stylesheet is quite particular.
// Our stylesheet(?) requires input.id to match label.for. Otherwise input doesn't display the check state. // Our stylesheet(?) requires input.id to match label.for. Otherwise input doesn't display the check state.
label.setAttribute('for', id); // cannot do label.for = label.setAttribute('for', id); // cannot do label.for =
input.id = id; input.id = id;
@ -31,9 +36,10 @@ function addImage(data) {
input.checked = (id === "p0"); input.checked = (id === "p0");
data.share = input.checked; data.share = input.checked;
input.addEventListener('change', toggle); input.addEventListener('change', toggle);
div.class = "property checkbox"; div2.setAttribute("class", "property checkbox");
div.appendChild(input); div2.appendChild(input);
div.appendChild(label); div2.appendChild(label);
div.appendChild(div2);
} else { } else {
data.share = true; data.share = true;
} }
@ -43,7 +49,13 @@ function addImage(data) {
function handleShareButtons(shareMsg) { function handleShareButtons(shareMsg) {
var openFeed = document.getElementById('openFeed'); var openFeed = document.getElementById('openFeed');
openFeed.checked = shareMsg.openFeedAfterShare; openFeed.checked = shareMsg.openFeedAfterShare;
openFeed.onchange = function () { EventBridge.emitWebEvent(openFeed.checked ? 'setOpenFeedTrue' : 'setOpenFeedFalse'); }; openFeed.onchange = function () {
EventBridge.emitWebEvent(JSON.stringify({
type: "snapshot",
action: (openFeed.checked ? "setOpenFeedTrue" : "setOpenFeedFalse")
}));
};
if (!shareMsg.canShare) { if (!shareMsg.canShare) {
// this means you may or may not be logged in, but can't share // this means you may or may not be logged in, but can't share
// because you are not in a public place. // because you are not in a public place.
@ -57,25 +69,42 @@ window.onload = function () {
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);
if (message.type !== "snapshot") {
return;
}
// last element of list contains a bool for whether or not we can share stuff // last element of list contains a bool for whether or not we can share stuff
var shareMsg = message.pop(); var shareMsg = message.action.pop();
handleShareButtons(shareMsg); handleShareButtons(shareMsg);
// rest are image paths which we add // rest are image paths which we add
useCheckboxes = message.length > 1; imageCount = message.action.length;
message.forEach(addImage); message.action.forEach(addImage);
}); });
EventBridge.emitWebEvent('ready'); EventBridge.emitWebEvent(JSON.stringify({
type: "snapshot",
action: "ready"
}));
}); });
}; };
// beware of bug: Cannot send objects at top level. (Nested in arrays is fine.) // beware of bug: Cannot send objects at top level. (Nested in arrays is fine.)
function shareSelected() { function shareSelected() {
EventBridge.emitWebEvent(paths); EventBridge.emitWebEvent(JSON.stringify({
}; type: "snapshot",
action: paths
}));
}
function doNotShare() { function doNotShare() {
EventBridge.emitWebEvent([]); EventBridge.emitWebEvent(JSON.stringify({
}; type: "snapshot",
action: []
}));
}
function snapshotSettings() { function snapshotSettings() {
EventBridge.emitWebEvent("openSettings"); EventBridge.emitWebEvent(JSON.stringify({
}; type: "snapshot",
action: "openSettings"
}));
}

View file

@ -36,26 +36,36 @@ function showFeedWindow() {
DialogsManager.showFeed(); DialogsManager.showFeed();
} }
var SNAPSHOT_REVIEW_URL = Script.resolvePath("html/SnapshotReview.html");
var outstanding; var outstanding;
function confirmShare(data) { var readyData;
var dialog = new OverlayWebWindow('Snapshot Review', SNAPSHOT_REVIEW_URL, 800, 520); 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.) // 2. Although we currently use a single image, we would like to take snapshot, a selfie, a 360 etc. all at the
// 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.
// 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.
// So we'll ultimately be receiving a set of objects, perhaps with different post processing for each. message = JSON.parse(message);
var isLoggedIn; if (message.type !== "snapshot") {
var needsLogin = false; return;
switch (message) { }
case 'ready':
dialog.emitScriptEvent(data); // Send it. var isLoggedIn;
var needsLogin = false;
switch (message.action) {
case 'ready': // Send it.
tablet.emitScriptEvent(JSON.stringify({
type: "snapshot",
action: readyData
}));
outstanding = 0; outstanding = 0;
break; break;
case 'openSettings': case 'openSettings':
Desktop.show("hifi/dialogs/GeneralPreferencesDialog.qml", "GeneralPreferencesDialog"); 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; break;
case 'setOpenFeedFalse': case 'setOpenFeedFalse':
Settings.setValue('openFeedAfterShare', false); Settings.setValue('openFeedAfterShare', false);
@ -64,10 +74,11 @@ function confirmShare(data) {
Settings.setValue('openFeedAfterShare', true); Settings.setValue('openFeedAfterShare', true);
break; break;
default: default:
dialog.webEventReceived.disconnect(onMessage); //tablet.webEventReceived.disconnect(onMessage); // <<< It's probably this that's missing?!
dialog.close(); HMD.closeTablet();
tablet.gotoHomeScreen();
isLoggedIn = Account.isLoggedIn(); isLoggedIn = Account.isLoggedIn();
message.forEach(function (submessage) { message.action.forEach(function (submessage) {
if (submessage.share && !isLoggedIn) { if (submessage.share && !isLoggedIn) {
needsLogin = true; needsLogin = true;
submessage.share = false; submessage.share = false;
@ -81,15 +92,22 @@ function confirmShare(data) {
} }
}); });
if (!outstanding && shouldOpenFeedAfterShare()) { if (!outstanding && shouldOpenFeedAfterShare()) {
showFeedWindow(); //showFeedWindow();
} }
if (needsLogin) { // after the possible feed, so that the login is on top if (needsLogin) { // after the possible feed, so that the login is on top
Account.checkAndSignalForAccessToken(); Account.checkAndSignalForAccessToken();
} }
}
} }
dialog.webEventReceived.connect(onMessage); }
dialog.raise();
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) { function snapshotShared(errorMessage) {
@ -205,10 +223,18 @@ function processingGif() {
} }
} }
function onTabletScreenChanged(type, url) {
if (isInSnapshotReview) {
tablet.webEventReceived.disconnect(onMessage);
isInSnapshotReview = false;
}
}
button.clicked.connect(onClicked); button.clicked.connect(onClicked);
buttonConnected = true; buttonConnected = true;
Window.snapshotShared.connect(snapshotShared); Window.snapshotShared.connect(snapshotShared);
Window.processingGif.connect(processingGif); Window.processingGif.connect(processingGif);
tablet.screenChanged.connect(onTabletScreenChanged);
Script.scriptEnding.connect(function () { Script.scriptEnding.connect(function () {
if (buttonConnected) { if (buttonConnected) {
@ -220,6 +246,7 @@ Script.scriptEnding.connect(function () {
} }
Window.snapshotShared.disconnect(snapshotShared); Window.snapshotShared.disconnect(snapshotShared);
Window.processingGif.disconnect(processingGif); Window.processingGif.disconnect(processingGif);
tablet.screenChanged.disconnect(onTabletScreenChanged);
}); });
}()); // END LOCAL_SCOPE }()); // END LOCAL_SCOPE