mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-09 14:29:13 +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() {
|
||||
return qApp->isPhysicsEnabled();
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@ public slots:
|
|||
void copyToClipboard(const QString& text);
|
||||
void takeSnapshot(bool notify = true, bool includeAnimated = false, float aspectRatio = 0.0f);
|
||||
void makeConnection(bool success, const QString& userNameOrError);
|
||||
void displayAnnouncement(const QString& message);
|
||||
void shareSnapshot(const QString& path, const QUrl& href = QUrl(""));
|
||||
bool isPhysicsEnabled();
|
||||
|
||||
|
@ -79,6 +80,7 @@ signals:
|
|||
|
||||
void connectionAdded(const QString& connectionName);
|
||||
void connectionError(const QString& errorString);
|
||||
void announcement(const QString& message);
|
||||
|
||||
void messageBoxClosed(int id, int button);
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
"use strict";
|
||||
|
||||
/*jslint vars:true, plusplus:true, forin:true*/
|
||||
/*global Script, Settings, Window, Controller, Overlays, SoundArray, LODManager, MyAvatar, Tablet, Camera, HMD, Menu, Quat, Vec3*/
|
||||
//
|
||||
// notifications.js
|
||||
// Version 0.801
|
||||
|
@ -56,39 +57,36 @@
|
|||
// }
|
||||
// }
|
||||
|
||||
/* global Script, Controller, Overlays, SoundArray, Quat, Vec3, MyAvatar, Menu, HMD, AudioDevice, LODManager, Settings, Camera */
|
||||
|
||||
(function() { // BEGIN LOCAL_SCOPE
|
||||
(function () { // BEGIN LOCAL_SCOPE
|
||||
|
||||
Script.include("./libraries/soundArray.js");
|
||||
Script.include("./libraries/soundArray.js");
|
||||
|
||||
var width = 340.0; //width of notification overlay
|
||||
var windowDimensions = Controller.getViewportDimensions(); // get the size of the interface window
|
||||
var overlayLocationX = (windowDimensions.x - (width + 20.0)); // positions window 20px from the right of the interface window
|
||||
var buttonLocationX = overlayLocationX + (width - 28.0);
|
||||
var locationY = 20.0; // position down from top of interface window
|
||||
var topMargin = 13.0;
|
||||
var leftMargin = 10.0;
|
||||
var textColor = { red: 228, green: 228, blue: 228}; // text color
|
||||
var backColor = { red: 2, green: 2, blue: 2}; // background color was 38,38,38
|
||||
var backgroundAlpha = 0;
|
||||
var fontSize = 12.0;
|
||||
var PERSIST_TIME_2D = 10.0; // Time in seconds before notification fades
|
||||
var PERSIST_TIME_3D = 15.0;
|
||||
var persistTime = PERSIST_TIME_2D;
|
||||
var frame = 0;
|
||||
var ourWidth = Window.innerWidth;
|
||||
var ourHeight = Window.innerHeight;
|
||||
var ctrlIsPressed = false;
|
||||
var ready = true;
|
||||
var MENU_NAME = 'Tools > Notifications';
|
||||
var PLAY_NOTIFICATION_SOUNDS_MENU_ITEM = "Play Notification Sounds";
|
||||
var NOTIFICATION_MENU_ITEM_POST = " Notifications";
|
||||
var PLAY_NOTIFICATION_SOUNDS_SETTING = "play_notification_sounds";
|
||||
var PLAY_NOTIFICATION_SOUNDS_TYPE_SETTING_PRE = "play_notification_sounds_type_";
|
||||
var lodTextID = false;
|
||||
var width = 340.0; //width of notification overlay
|
||||
var windowDimensions = Controller.getViewportDimensions(); // get the size of the interface window
|
||||
var overlayLocationX = (windowDimensions.x - (width + 20.0)); // positions window 20px from the right of the interface window
|
||||
var buttonLocationX = overlayLocationX + (width - 28.0);
|
||||
var locationY = 20.0; // position down from top of interface window
|
||||
var topMargin = 13.0;
|
||||
var leftMargin = 10.0;
|
||||
var textColor = { red: 228, green: 228, blue: 228}; // text color
|
||||
var backColor = { red: 2, green: 2, blue: 2}; // background color was 38,38,38
|
||||
var backgroundAlpha = 0;
|
||||
var fontSize = 12.0;
|
||||
var PERSIST_TIME_2D = 10.0; // Time in seconds before notification fades
|
||||
var PERSIST_TIME_3D = 15.0;
|
||||
var persistTime = PERSIST_TIME_2D;
|
||||
var frame = 0;
|
||||
var ctrlIsPressed = false;
|
||||
var ready = true;
|
||||
var MENU_NAME = 'Tools > Notifications';
|
||||
var PLAY_NOTIFICATION_SOUNDS_MENU_ITEM = "Play Notification Sounds";
|
||||
var NOTIFICATION_MENU_ITEM_POST = " Notifications";
|
||||
var PLAY_NOTIFICATION_SOUNDS_SETTING = "play_notification_sounds";
|
||||
var PLAY_NOTIFICATION_SOUNDS_TYPE_SETTING_PRE = "play_notification_sounds_type_";
|
||||
var lodTextID = false;
|
||||
|
||||
var NotificationType = {
|
||||
var NotificationType = {
|
||||
UNKNOWN: 0,
|
||||
SNAPSHOT: 1,
|
||||
LOD_WARNING: 2,
|
||||
|
@ -104,36 +102,38 @@ var NotificationType = {
|
|||
{ text: "Tablet" },
|
||||
{ text: "Connection" }
|
||||
],
|
||||
getTypeFromMenuItem: function(menuItemName) {
|
||||
getTypeFromMenuItem: function (menuItemName) {
|
||||
var type;
|
||||
if (menuItemName.substr(menuItemName.length - NOTIFICATION_MENU_ITEM_POST.length) !== NOTIFICATION_MENU_ITEM_POST) {
|
||||
return NotificationType.UNKNOWN;
|
||||
}
|
||||
var preMenuItemName = menuItemName.substr(0, menuItemName.length - NOTIFICATION_MENU_ITEM_POST.length);
|
||||
for (var type in this.properties) {
|
||||
for (type in this.properties) {
|
||||
if (this.properties[type].text === preMenuItemName) {
|
||||
return parseInt(type) + 1;
|
||||
return parseInt(type, 10) + 1;
|
||||
}
|
||||
}
|
||||
return NotificationType.UNKNOWN;
|
||||
},
|
||||
getMenuString: function(type) {
|
||||
getMenuString: function (type) {
|
||||
return this.properties[type - 1].text + NOTIFICATION_MENU_ITEM_POST;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
var randomSounds = new SoundArray({ localOnly: true }, true);
|
||||
var numberOfSounds = 2;
|
||||
for (var i = 1; i <= numberOfSounds; i++) {
|
||||
randomSounds.addSound(Script.resolvePath("assets/sounds/notification-general"+ i + ".raw"));
|
||||
}
|
||||
var randomSounds = new SoundArray({ localOnly: true }, true);
|
||||
var numberOfSounds = 2;
|
||||
var soundIndex;
|
||||
for (soundIndex = 1; soundIndex <= numberOfSounds; soundIndex++) {
|
||||
randomSounds.addSound(Script.resolvePath("assets/sounds/notification-general" + soundIndex + ".raw"));
|
||||
}
|
||||
|
||||
var notifications = [];
|
||||
var buttons = [];
|
||||
var times = [];
|
||||
var heights = [];
|
||||
var myAlpha = [];
|
||||
var arrays = [];
|
||||
var isOnHMD = false,
|
||||
var notifications = [];
|
||||
var buttons = [];
|
||||
var times = [];
|
||||
var heights = [];
|
||||
var myAlpha = [];
|
||||
var arrays = [];
|
||||
var isOnHMD = false,
|
||||
NOTIFICATIONS_3D_DIRECTION = 0.0, // Degrees from avatar orientation.
|
||||
NOTIFICATIONS_3D_DISTANCE = 0.6, // Horizontal distance from avatar position.
|
||||
NOTIFICATIONS_3D_ELEVATION = -0.8, // Height of top middle of top notification relative to avatar eyes.
|
||||
|
@ -143,14 +143,14 @@ var isOnHMD = false,
|
|||
NOTIFICATION_3D_BUTTON_WIDTH = 40 * NOTIFICATION_3D_SCALE, // Need a little more room for button in 3D.
|
||||
overlay3DDetails = [];
|
||||
|
||||
// push data from above to the 2 dimensional array
|
||||
function createArrays(notice, button, createTime, height, myAlpha) {
|
||||
// push data from above to the 2 dimensional array
|
||||
function createArrays(notice, button, createTime, height, myAlpha) {
|
||||
arrays.push([notice, button, createTime, height, myAlpha]);
|
||||
}
|
||||
}
|
||||
|
||||
// This handles the final dismissal of a notification after fading
|
||||
function dismiss(firstNoteOut, firstButOut, firstOut) {
|
||||
if (firstNoteOut == lodTextID) {
|
||||
// This handles the final dismissal of a notification after fading
|
||||
function dismiss(firstNoteOut, firstButOut, firstOut) {
|
||||
if (firstNoteOut === lodTextID) {
|
||||
lodTextID = false;
|
||||
}
|
||||
|
||||
|
@ -162,9 +162,9 @@ function dismiss(firstNoteOut, firstButOut, firstOut) {
|
|||
heights.splice(firstOut, 1);
|
||||
myAlpha.splice(firstOut, 1);
|
||||
overlay3DDetails.splice(firstOut, 1);
|
||||
}
|
||||
}
|
||||
|
||||
function fadeIn(noticeIn, buttonIn) {
|
||||
function fadeIn(noticeIn, buttonIn) {
|
||||
var q = 0,
|
||||
qFade,
|
||||
pauseTimer = null;
|
||||
|
@ -178,29 +178,29 @@ function fadeIn(noticeIn, buttonIn) {
|
|||
Script.clearInterval(pauseTimer);
|
||||
}
|
||||
}, 10);
|
||||
}
|
||||
}
|
||||
|
||||
// this fades the notification ready for dismissal, and removes it from the arrays
|
||||
function fadeOut(noticeOut, buttonOut, arraysOut) {
|
||||
// this fades the notification ready for dismissal, and removes it from the arrays
|
||||
function fadeOut(noticeOut, buttonOut, arraysOut) {
|
||||
var r = 9.0,
|
||||
rFade,
|
||||
pauseTimer = null;
|
||||
|
||||
pauseTimer = Script.setInterval(function () {
|
||||
r -= 1;
|
||||
rFade = r / 10.0;
|
||||
rFade = Math.max(0.0, r / 10.0);
|
||||
Overlays.editOverlay(noticeOut, { alpha: rFade });
|
||||
Overlays.editOverlay(buttonOut, { alpha: rFade });
|
||||
if (r < 0) {
|
||||
if (r <= 0) {
|
||||
dismiss(noticeOut, buttonOut, arraysOut);
|
||||
arrays.splice(arraysOut, 1);
|
||||
ready = true;
|
||||
Script.clearInterval(pauseTimer);
|
||||
}
|
||||
}, 20);
|
||||
}
|
||||
}
|
||||
|
||||
function calculate3DOverlayPositions(noticeWidth, noticeHeight, y) {
|
||||
function calculate3DOverlayPositions(noticeWidth, noticeHeight, y) {
|
||||
// Calculates overlay positions and orientations in avatar coordinates.
|
||||
var noticeY,
|
||||
originOffset,
|
||||
|
@ -231,12 +231,12 @@ function calculate3DOverlayPositions(noticeWidth, noticeHeight, y) {
|
|||
notificationPosition: notificationPosition,
|
||||
buttonPosition: buttonPosition
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Pushes data to each array and sets up data for 2nd dimension array
|
||||
// to handle auxiliary data not carried by the overlay class
|
||||
// specifically notification "heights", "times" of creation, and .
|
||||
function notify(notice, button, height, imageProperties, image) {
|
||||
// Pushes data to each array and sets up data for 2nd dimension array
|
||||
// to handle auxiliary data not carried by the overlay class
|
||||
// specifically notification "heights", "times" of creation, and .
|
||||
function notify(notice, button, height, imageProperties, image) {
|
||||
var notificationText,
|
||||
noticeWidth,
|
||||
noticeHeight,
|
||||
|
@ -290,32 +290,33 @@ function notify(notice, button, height, imageProperties, image) {
|
|||
avatarOrientation,
|
||||
notificationPosition,
|
||||
notificationOrientation,
|
||||
buttonPosition;
|
||||
buttonPosition,
|
||||
notificationIndex;
|
||||
|
||||
if (isOnHMD && notifications.length > 0) {
|
||||
// Update 3D overlays to maintain positions relative to avatar
|
||||
defaultEyePosition = MyAvatar.getDefaultEyePosition();
|
||||
avatarOrientation = MyAvatar.orientation;
|
||||
|
||||
for (i = 0; i < notifications.length; i += 1) {
|
||||
for (notificationIndex = 0; notificationIndex < notifications.length; notificationIndex += 1) {
|
||||
notificationPosition = Vec3.sum(defaultEyePosition,
|
||||
Vec3.multiplyQbyV(avatarOrientation,
|
||||
overlay3DDetails[i].notificationPosition));
|
||||
overlay3DDetails[notificationIndex].notificationPosition));
|
||||
notificationOrientation = Quat.multiply(avatarOrientation,
|
||||
overlay3DDetails[i].notificationOrientation);
|
||||
overlay3DDetails[notificationIndex].notificationOrientation);
|
||||
buttonPosition = Vec3.sum(defaultEyePosition,
|
||||
Vec3.multiplyQbyV(avatarOrientation,
|
||||
overlay3DDetails[i].buttonPosition));
|
||||
Overlays.editOverlay(notifications[i], { position: notificationPosition,
|
||||
overlay3DDetails[notificationIndex].buttonPosition));
|
||||
Overlays.editOverlay(notifications[notificationIndex], { position: notificationPosition,
|
||||
rotation: notificationOrientation });
|
||||
Overlays.editOverlay(buttons[i], { position: buttonPosition, rotation: notificationOrientation });
|
||||
Overlays.editOverlay(buttons[notificationIndex], { position: buttonPosition, rotation: notificationOrientation });
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (!image) {
|
||||
notificationText = Overlays.addOverlay("text", notice);
|
||||
notifications.push((notificationText));
|
||||
notifications.push(notificationText);
|
||||
} else {
|
||||
notifications.push(Overlays.addOverlay("image", notice));
|
||||
}
|
||||
|
@ -347,12 +348,12 @@ function notify(notice, button, height, imageProperties, image) {
|
|||
}
|
||||
|
||||
return notificationText;
|
||||
}
|
||||
}
|
||||
|
||||
var CLOSE_NOTIFICATION_ICON = Script.resolvePath("assets/images/close-small-light.svg");
|
||||
var CLOSE_NOTIFICATION_ICON = Script.resolvePath("assets/images/close-small-light.svg");
|
||||
|
||||
// This function creates and sizes the overlays
|
||||
function createNotification(text, notificationType, imageProperties) {
|
||||
// This function creates and sizes the overlays
|
||||
function createNotification(text, notificationType, imageProperties) {
|
||||
var count = (text.match(/\n/g) || []).length,
|
||||
breakPoint = 43.0, // length when new line is added
|
||||
extraLine = 0,
|
||||
|
@ -409,11 +410,11 @@ function createNotification(text, notificationType, imageProperties) {
|
|||
}
|
||||
|
||||
return notify(noticeProperties, buttonProperties, height, imageProperties);
|
||||
}
|
||||
}
|
||||
|
||||
function deleteNotification(index) {
|
||||
function deleteNotification(index) {
|
||||
var notificationTextID = notifications[index];
|
||||
if (notificationTextID == lodTextID) {
|
||||
if (notificationTextID === lodTextID) {
|
||||
lodTextID = false;
|
||||
}
|
||||
Overlays.deleteOverlay(notificationTextID);
|
||||
|
@ -425,12 +426,12 @@ function deleteNotification(index) {
|
|||
myAlpha.splice(index, 1);
|
||||
overlay3DDetails.splice(index, 1);
|
||||
arrays.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Trims extra whitespace and breaks into lines of length no more than MAX_LENGTH, breaking at spaces. Trims extra whitespace.
|
||||
var MAX_LENGTH = 42;
|
||||
function wordWrap(string) {
|
||||
// Trims extra whitespace and breaks into lines of length no more than MAX_LENGTH, breaking at spaces. Trims extra whitespace.
|
||||
var MAX_LENGTH = 42;
|
||||
function wordWrap(string) {
|
||||
var finishedLines = [], currentLine = '';
|
||||
string.split(/\s/).forEach(function (word) {
|
||||
var tail = currentLine ? ' ' + word : word;
|
||||
|
@ -445,11 +446,10 @@ function wordWrap(string) {
|
|||
finishedLines.push(currentLine);
|
||||
}
|
||||
return finishedLines.join('\n');
|
||||
}
|
||||
}
|
||||
|
||||
function update() {
|
||||
var nextOverlay,
|
||||
noticeOut,
|
||||
function update() {
|
||||
var noticeOut,
|
||||
buttonOut,
|
||||
arraysOut,
|
||||
positions,
|
||||
|
@ -470,7 +470,6 @@ function update() {
|
|||
if ((frame % 60.0) === 0) { // only update once a second
|
||||
locationY = 20.0;
|
||||
for (i = 0; i < arrays.length; i += 1) { //repositions overlays as others fade
|
||||
nextOverlay = Overlays.getOverlayAtPoint({ x: overlayLocationX, y: locationY });
|
||||
Overlays.editOverlay(notifications[i], { x: overlayLocationX, y: locationY });
|
||||
Overlays.editOverlay(buttons[i], { x: buttonLocationX, y: locationY + 12.0 });
|
||||
if (isOnHMD) {
|
||||
|
@ -498,18 +497,18 @@ function update() {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var STARTUP_TIMEOUT = 500, // ms
|
||||
var STARTUP_TIMEOUT = 500, // ms
|
||||
startingUp = true,
|
||||
startupTimer = null;
|
||||
|
||||
function finishStartup() {
|
||||
function finishStartup() {
|
||||
startingUp = false;
|
||||
Script.clearTimeout(startupTimer);
|
||||
}
|
||||
}
|
||||
|
||||
function isStartingUp() {
|
||||
function isStartingUp() {
|
||||
// Is starting up until get no checks that it is starting up for STARTUP_TIMEOUT
|
||||
if (startingUp) {
|
||||
if (startupTimer) {
|
||||
|
@ -518,21 +517,21 @@ function isStartingUp() {
|
|||
startupTimer = Script.setTimeout(finishStartup, STARTUP_TIMEOUT);
|
||||
}
|
||||
return startingUp;
|
||||
}
|
||||
}
|
||||
|
||||
function onDomainConnectionRefused(reason) {
|
||||
function onDomainConnectionRefused(reason) {
|
||||
createNotification("Connection refused: " + reason, NotificationType.CONNECTION_REFUSED);
|
||||
}
|
||||
}
|
||||
|
||||
function onEditError(msg) {
|
||||
function onEditError(msg) {
|
||||
createNotification(wordWrap(msg), NotificationType.EDIT_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
function onNotify(msg) {
|
||||
function onNotify(msg) {
|
||||
createNotification(wordWrap(msg), NotificationType.UNKNOWN); // Needs a generic notification system for user feedback, thus using this
|
||||
}
|
||||
}
|
||||
|
||||
function onSnapshotTaken(pathStillSnapshot, notify) {
|
||||
function onSnapshotTaken(pathStillSnapshot, notify) {
|
||||
if (notify) {
|
||||
var imageProperties = {
|
||||
path: "file:///" + pathStillSnapshot,
|
||||
|
@ -540,26 +539,26 @@ function onSnapshotTaken(pathStillSnapshot, notify) {
|
|||
};
|
||||
createNotification(wordWrap("Snapshot saved to " + pathStillSnapshot), NotificationType.SNAPSHOT, imageProperties);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function tabletNotification() {
|
||||
function tabletNotification() {
|
||||
createNotification("Tablet needs your attention", NotificationType.TABLET);
|
||||
}
|
||||
}
|
||||
|
||||
function processingGif() {
|
||||
function processingGif() {
|
||||
createNotification("Processing GIF snapshot...", NotificationType.SNAPSHOT);
|
||||
}
|
||||
}
|
||||
|
||||
function connectionAdded(connectionName) {
|
||||
function connectionAdded(connectionName) {
|
||||
createNotification(connectionName, NotificationType.CONNECTION);
|
||||
}
|
||||
}
|
||||
|
||||
function connectionError(error) {
|
||||
function connectionError(error) {
|
||||
createNotification(wordWrap("Error trying to make connection: " + error), NotificationType.CONNECTION);
|
||||
}
|
||||
}
|
||||
|
||||
// handles mouse clicks on buttons
|
||||
function mousePressEvent(event) {
|
||||
// handles mouse clicks on buttons
|
||||
function mousePressEvent(event) {
|
||||
var pickRay,
|
||||
clickedOverlay,
|
||||
i;
|
||||
|
@ -576,23 +575,24 @@ function mousePressEvent(event) {
|
|||
deleteNotification(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Control key remains active only while key is held down
|
||||
function keyReleaseEvent(key) {
|
||||
// Control key remains active only while key is held down
|
||||
function keyReleaseEvent(key) {
|
||||
if (key.key === 16777249) {
|
||||
ctrlIsPressed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Triggers notification on specific key driven events
|
||||
function keyPressEvent(key) {
|
||||
// Triggers notification on specific key driven events
|
||||
function keyPressEvent(key) {
|
||||
if (key.key === 16777249) {
|
||||
ctrlIsPressed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setup() {
|
||||
function setup() {
|
||||
var type;
|
||||
Menu.addMenu(MENU_NAME);
|
||||
var checked = Settings.getValue(PLAY_NOTIFICATION_SOUNDS_SETTING);
|
||||
checked = checked === '' ? true : checked;
|
||||
|
@ -603,8 +603,8 @@ function setup() {
|
|||
isChecked: Settings.getValue(PLAY_NOTIFICATION_SOUNDS_SETTING)
|
||||
});
|
||||
Menu.addSeparator(MENU_NAME, "Play sounds for:");
|
||||
for (var type in NotificationType.properties) {
|
||||
checked = Settings.getValue(PLAY_NOTIFICATION_SOUNDS_TYPE_SETTING_PRE + (parseInt(type) + 1));
|
||||
for (type in NotificationType.properties) {
|
||||
checked = Settings.getValue(PLAY_NOTIFICATION_SOUNDS_TYPE_SETTING_PRE + (parseInt(type, 10) + 1));
|
||||
checked = checked === '' ? true : checked;
|
||||
Menu.addMenuItem({
|
||||
menuName: MENU_NAME,
|
||||
|
@ -613,18 +613,19 @@ function setup() {
|
|||
isChecked: checked
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// When our script shuts down, we should clean up all of our overlays
|
||||
function scriptEnding() {
|
||||
for (var i = 0; i < notifications.length; i++) {
|
||||
Overlays.deleteOverlay(notifications[i]);
|
||||
Overlays.deleteOverlay(buttons[i]);
|
||||
// When our script shuts down, we should clean up all of our overlays
|
||||
function scriptEnding() {
|
||||
var notificationIndex;
|
||||
for (notificationIndex = 0; notificationIndex < notifications.length; notificationIndex++) {
|
||||
Overlays.deleteOverlay(notifications[notificationIndex]);
|
||||
Overlays.deleteOverlay(buttons[notificationIndex]);
|
||||
}
|
||||
Menu.removeMenu(MENU_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
function menuItemEvent(menuItem) {
|
||||
function menuItemEvent(menuItem) {
|
||||
if (menuItem === PLAY_NOTIFICATION_SOUNDS_MENU_ITEM) {
|
||||
Settings.setValue(PLAY_NOTIFICATION_SOUNDS_SETTING, Menu.isOptionChecked(PLAY_NOTIFICATION_SOUNDS_MENU_ITEM));
|
||||
return;
|
||||
|
@ -633,9 +634,9 @@ function menuItemEvent(menuItem) {
|
|||
if (notificationType !== notificationType.UNKNOWN) {
|
||||
Settings.setValue(PLAY_NOTIFICATION_SOUNDS_TYPE_SETTING_PRE + notificationType, Menu.isOptionChecked(menuItem));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LODManager.LODDecreased.connect(function() {
|
||||
LODManager.LODDecreased.connect(function () {
|
||||
var warningText = "\n" +
|
||||
"Due to the complexity of the content, the \n" +
|
||||
"level of detail has been decreased. " +
|
||||
|
@ -647,22 +648,23 @@ LODManager.LODDecreased.connect(function() {
|
|||
} else {
|
||||
Overlays.editOverlay(lodTextID, { text: warningText });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Controller.keyPressEvent.connect(keyPressEvent);
|
||||
Controller.mousePressEvent.connect(mousePressEvent);
|
||||
Controller.keyReleaseEvent.connect(keyReleaseEvent);
|
||||
Script.update.connect(update);
|
||||
Script.scriptEnding.connect(scriptEnding);
|
||||
Menu.menuItemEvent.connect(menuItemEvent);
|
||||
Window.domainConnectionRefused.connect(onDomainConnectionRefused);
|
||||
Window.stillSnapshotTaken.connect(onSnapshotTaken);
|
||||
Window.processingGifStarted.connect(processingGif);
|
||||
Window.connectionAdded.connect(connectionAdded);
|
||||
Window.connectionError.connect(connectionError);
|
||||
Window.notifyEditError = onEditError;
|
||||
Window.notify = onNotify;
|
||||
Tablet.tabletNotification.connect(tabletNotification);
|
||||
setup();
|
||||
Controller.keyPressEvent.connect(keyPressEvent);
|
||||
Controller.mousePressEvent.connect(mousePressEvent);
|
||||
Controller.keyReleaseEvent.connect(keyReleaseEvent);
|
||||
Script.update.connect(update);
|
||||
Script.scriptEnding.connect(scriptEnding);
|
||||
Menu.menuItemEvent.connect(menuItemEvent);
|
||||
Window.domainConnectionRefused.connect(onDomainConnectionRefused);
|
||||
Window.stillSnapshotTaken.connect(onSnapshotTaken);
|
||||
Window.processingGifStarted.connect(processingGif);
|
||||
Window.connectionAdded.connect(connectionAdded);
|
||||
Window.connectionError.connect(connectionError);
|
||||
Window.announcement.connect(onNotify);
|
||||
Window.notifyEditError = onEditError;
|
||||
Window.notify = onNotify;
|
||||
Tablet.tabletNotification.connect(tabletNotification);
|
||||
setup();
|
||||
|
||||
}()); // END LOCAL_SCOPE
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
"use strict";
|
||||
/*jslint vars:true, plusplus:true, forin:true*/
|
||||
/*global Window, Script, Tablet, HMD, Controller, Account, XMLHttpRequest, location, print*/
|
||||
|
||||
//
|
||||
// goto.js
|
||||
|
@ -11,11 +13,29 @@
|
|||
// 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 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) {
|
||||
|
@ -29,29 +49,115 @@
|
|||
}
|
||||
|
||||
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});
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
|
|
Loading…
Reference in a new issue