mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 08:21:24 +02:00
Merge pull request #10258 from howard-stearns/watch-for-announcements
watch for announcements
This commit is contained in:
commit
88c3b4d9d3
5 changed files with 683 additions and 551 deletions
18
interface/resources/icons/tablet-icons/goto-msg.svg
Normal file
18
interface/resources/icons/tablet-icons/goto-msg.svg
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 19.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0{fill:#FFFFFF;}
|
||||||
|
.st1{fill:#EF3B4E;}
|
||||||
|
</style>
|
||||||
|
<g id="Layer_2">
|
||||||
|
</g>
|
||||||
|
<g id="Layer_1_1_">
|
||||||
|
<path class="st0" d="M47.2,41.3l-9.1-9.1c-0.8-0.8-1.9-1.1-3-1l-2.4-2.4c1.8-2.6,2.8-5.7,2.8-9c0-8.9-7.2-16.1-16.1-16.1
|
||||||
|
S3.3,11,3.3,19.8c0,8.9,7.2,16.1,16.1,16.1c4.1,0,7.8-1.5,10.6-4l2.2,2.2c-0.2,1.1,0.1,2.2,1,3l9.1,9.1c1.4,1.4,3.6,1.4,4.9,0
|
||||||
|
C48.5,44.9,48.5,42.7,47.2,41.3z M19.4,32.2c-6.8,0-12.3-5.5-12.3-12.3S12.6,7.6,19.4,7.6s12.3,5.5,12.3,12.3
|
||||||
|
C31.8,26.6,26.2,32.2,19.4,32.2z"/>
|
||||||
|
</g>
|
||||||
|
<circle class="st1" cx="43.5" cy="6.5" r="5.9"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 911 B |
|
@ -278,6 +278,10 @@ void WindowScriptingInterface::makeConnection(bool success, const QString& userN
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WindowScriptingInterface::displayAnnouncement(const QString& message) {
|
||||||
|
emit announcement(message);
|
||||||
|
}
|
||||||
|
|
||||||
bool WindowScriptingInterface::isPhysicsEnabled() {
|
bool WindowScriptingInterface::isPhysicsEnabled() {
|
||||||
return qApp->isPhysicsEnabled();
|
return qApp->isPhysicsEnabled();
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,7 @@ public slots:
|
||||||
void copyToClipboard(const QString& text);
|
void copyToClipboard(const QString& text);
|
||||||
void takeSnapshot(bool notify = true, bool includeAnimated = false, float aspectRatio = 0.0f);
|
void takeSnapshot(bool notify = true, bool includeAnimated = false, float aspectRatio = 0.0f);
|
||||||
void makeConnection(bool success, const QString& userNameOrError);
|
void makeConnection(bool success, const QString& userNameOrError);
|
||||||
|
void displayAnnouncement(const QString& message);
|
||||||
void shareSnapshot(const QString& path, const QUrl& href = QUrl(""));
|
void shareSnapshot(const QString& path, const QUrl& href = QUrl(""));
|
||||||
bool isPhysicsEnabled();
|
bool isPhysicsEnabled();
|
||||||
|
|
||||||
|
@ -79,6 +80,7 @@ signals:
|
||||||
|
|
||||||
void connectionAdded(const QString& connectionName);
|
void connectionAdded(const QString& connectionName);
|
||||||
void connectionError(const QString& errorString);
|
void connectionError(const QString& errorString);
|
||||||
|
void announcement(const QString& message);
|
||||||
|
|
||||||
void messageBoxClosed(int id, int button);
|
void messageBoxClosed(int id, int button);
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,6 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
/*jslint vars:true, plusplus:true, forin:true*/
|
||||||
|
/*global Window, Script, Tablet, HMD, Controller, Account, XMLHttpRequest, location, print*/
|
||||||
|
|
||||||
//
|
//
|
||||||
// goto.js
|
// goto.js
|
||||||
|
@ -11,11 +13,29 @@
|
||||||
// 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
|
||||||
//
|
//
|
||||||
|
|
||||||
(function() { // BEGIN LOCAL_SCOPE
|
(function () { // BEGIN LOCAL_SCOPE
|
||||||
var gotoQmlSource = "TabletAddressDialog.qml";
|
var gotoQmlSource = "TabletAddressDialog.qml";
|
||||||
var buttonName = "GOTO";
|
var buttonName = "GOTO";
|
||||||
var onGotoScreen = false;
|
var onGotoScreen = false;
|
||||||
var shouldActivateButton = 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() {
|
function onClicked() {
|
||||||
if (onGotoScreen) {
|
if (onGotoScreen) {
|
||||||
|
@ -29,29 +49,115 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function onScreenChanged(type, url) {
|
function onScreenChanged(type, url) {
|
||||||
|
ignore(type);
|
||||||
if (url === gotoQmlSource) {
|
if (url === gotoQmlSource) {
|
||||||
onGotoScreen = true;
|
onGotoScreen = true;
|
||||||
shouldActivateButton = true;
|
shouldActivateButton = true;
|
||||||
button.editProperties({isActive: shouldActivateButton});
|
button.editProperties({isActive: shouldActivateButton});
|
||||||
} else {
|
messagesWaiting(false);
|
||||||
|
} else {
|
||||||
shouldActivateButton = false;
|
shouldActivateButton = false;
|
||||||
onGotoScreen = false;
|
onGotoScreen = false;
|
||||||
button.editProperties({isActive: shouldActivateButton});
|
button.editProperties({isActive: shouldActivateButton});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
|
||||||
var button = tablet.addButton({
|
|
||||||
icon: "icons/tablet-icons/goto-i.svg",
|
|
||||||
activeIcon: "icons/tablet-icons/goto-a.svg",
|
|
||||||
text: buttonName,
|
|
||||||
sortOrder: 8
|
|
||||||
});
|
|
||||||
|
|
||||||
button.clicked.connect(onClicked);
|
button.clicked.connect(onClicked);
|
||||||
tablet.screenChanged.connect(onScreenChanged);
|
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.scriptEnding.connect(function () {
|
||||||
|
Script.clearInterval(pollTimer);
|
||||||
button.clicked.disconnect(onClicked);
|
button.clicked.disconnect(onClicked);
|
||||||
tablet.removeButton(button);
|
tablet.removeButton(button);
|
||||||
tablet.screenChanged.disconnect(onScreenChanged);
|
tablet.screenChanged.disconnect(onScreenChanged);
|
||||||
|
|
Loading…
Reference in a new issue