overte/scripts/system/tablet-goto.js
Howard Stearns 0f8ee7051c lint
2017-04-26 08:20:12 -07:00

166 lines
6.3 KiB
JavaScript

"use strict";
/*jslint vars:true, plusplus:true, forin:true*/
/*global Window, Script, Tablet, HMD, Controller, Account, XMLHttpRequest, location, print*/
//
// goto.js
// scripts/system/
//
// Created by Dante Ruiz on 8 February 2017
// Copyright 2016 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
(function () { // BEGIN LOCAL_SCOPE
var gotoQmlSource = "TabletAddressDialog.qml";
var buttonName = "GOTO";
var onGotoScreen = false;
var shouldActivateButton = false;
function ignore() { }
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
var NORMAL_ICON = "icons/tablet-icons/goto-i.svg";
var NORMAL_ACTIVE = "icons/tablet-icons/goto-a.svg";
var WAITING_ICON = "icons/tablet-icons/goto-msg.svg";
var button = tablet.addButton({
icon: NORMAL_ICON,
activeIcon: NORMAL_ACTIVE,
text: buttonName,
sortOrder: 8
});
function messagesWaiting(isWaiting) {
button.editProperties({
icon: isWaiting ? WAITING_ICON : NORMAL_ICON
// No need for a different activeIcon, because we issue messagesWaiting(false) when the button goes active anyway.
});
}
function onClicked() {
if (onGotoScreen) {
// for toolbar-mode: go back to home screen, this will close the window.
tablet.gotoHomeScreen();
} else {
shouldActivateButton = true;
tablet.loadQMLSource(gotoQmlSource);
onGotoScreen = true;
}
}
function onScreenChanged(type, url) {
ignore(type);
if (url === gotoQmlSource) {
onGotoScreen = true;
shouldActivateButton = true;
button.editProperties({isActive: shouldActivateButton});
messagesWaiting(false);
} else {
shouldActivateButton = false;
onGotoScreen = false;
button.editProperties({isActive: shouldActivateButton});
}
}
button.clicked.connect(onClicked);
tablet.screenChanged.connect(onScreenChanged);
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);
}
var stories = {};
var DEBUG = false;
function pollForAnnouncements() {
var actions = DEBUG ? 'snapshot' : 'announcement';
var count = DEBUG ? 10 : 100;
var options = [
'now=' + new Date().toISOString(),
'include_actions=' + actions,
'restriction=' + (Account.isLoggedIn() ? 'open,hifi' : 'open'),
'require_online=true',
'protocol=' + encodeURIComponent(location.protocolVersion()),
'per_page=' + count
];
var url = location.metaverseServerUrl + '/api/v1/user_stories?' + options.join('&');
request({
uri: url
}, function (error, data) {
if (error || (data.status !== 'success')) {
print("Error: unable to get", url, error || data.status);
return;
}
var didNotify = false;
data.user_stories.forEach(function (story) {
if (stories[story.id]) { // already seen
return;
}
stories[story.id] = story;
var message = story.username + " says something is happening in " + story.place_name + ". Open GOTO to join them.";
Window.displayAnnouncement(message);
didNotify = true;
});
if (didNotify) {
messagesWaiting(true);
if (HMD.isHandControllerAvailable()) {
var STRENGTH = 1.0, DURATION_MS = 60, HAND = 2; // both hands
Controller.triggerHapticPulse(STRENGTH, DURATION_MS, HAND);
}
}
});
}
var ANNOUNCEMENTS_POLL_TIME_MS = (DEBUG ? 10 : 60) * 1000;
var pollTimer = Script.setInterval(pollForAnnouncements, ANNOUNCEMENTS_POLL_TIME_MS);
Script.scriptEnding.connect(function () {
Script.clearInterval(pollTimer);
button.clicked.disconnect(onClicked);
tablet.removeButton(button);
tablet.screenChanged.disconnect(onScreenChanged);
});
}()); // END LOCAL_SCOPE