mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-09 21:26:25 +02:00
Merge in big work from appui_notifications branch
This commit is contained in:
parent
9e50904376
commit
9c5544af39
5 changed files with 299 additions and 25 deletions
83
interface/resources/icons/tablet-icons/people-a-msg.svg
Normal file
83
interface/resources/icons/tablet-icons/people-a-msg.svg
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 19.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
version="1.1"
|
||||||
|
x="0px"
|
||||||
|
y="0px"
|
||||||
|
viewBox="0 0 50 50"
|
||||||
|
style="enable-background:new 0 0 50 50;"
|
||||||
|
xml:space="preserve"
|
||||||
|
id="svg2"
|
||||||
|
inkscape:version="0.91 r13725"
|
||||||
|
sodipodi:docname="people-a.svg"><metadata
|
||||||
|
id="metadata24"><rdf:RDF><cc:Work
|
||||||
|
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||||
|
id="defs22" /><sodipodi:namedview
|
||||||
|
pagecolor="#ff0000"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="852"
|
||||||
|
inkscape:window-height="480"
|
||||||
|
id="namedview20"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="4.72"
|
||||||
|
inkscape:cx="25"
|
||||||
|
inkscape:cy="25"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="svg2" /><style
|
||||||
|
type="text/css"
|
||||||
|
id="style4">
|
||||||
|
.st0{fill:#FFFFFF;}
|
||||||
|
.st1{fill:#EF3B4E;}
|
||||||
|
</style>
|
||||||
|
<circle class="st1" cx="44.1" cy="6" r="5.6"/>
|
||||||
|
<g
|
||||||
|
id="Layer_2" /><g
|
||||||
|
id="Layer_1"
|
||||||
|
style="fill:#000000;fill-opacity:1"><circle
|
||||||
|
class="st0"
|
||||||
|
cx="25.6"
|
||||||
|
cy="14.8"
|
||||||
|
r="8.1"
|
||||||
|
id="circle8"
|
||||||
|
style="fill:#000000;fill-opacity:1" /><path
|
||||||
|
class="st0"
|
||||||
|
d="M31.4,27h-11c-4.6,0-8.2,3.9-8.2,8.5v4.3c3.8,2.8,8.1,4.5,13.1,4.5c5.6,0,10.6-2.1,14.4-5.6v-3.2 C39.6,30.9,35.9,27,31.4,27z"
|
||||||
|
id="path10"
|
||||||
|
style="fill:#000000;fill-opacity:1" /><circle
|
||||||
|
class="st0"
|
||||||
|
cx="41.6"
|
||||||
|
cy="17.1"
|
||||||
|
r="3.5"
|
||||||
|
id="circle12"
|
||||||
|
style="fill:#000000;fill-opacity:1" /><path
|
||||||
|
class="st0"
|
||||||
|
d="M43.9,23.9h-4.1c-0.9,0-1.7,0.4-2.3,1c1.2,0.6,2.3,1.6,3.1,2.5c1,1.2,1.5,2.7,1.7,4.3c0.3,0.9,0.4,1.8,0.2,2.8 v0.6c1.6-2.2,3.3-6,4-8.1v-0.3C46.5,25.7,45.3,23.9,43.9,23.9z"
|
||||||
|
id="path14"
|
||||||
|
style="fill:#000000;fill-opacity:1" /><circle
|
||||||
|
class="st0"
|
||||||
|
cx="9.4"
|
||||||
|
cy="18"
|
||||||
|
r="3.5"
|
||||||
|
id="circle16"
|
||||||
|
style="fill:#000000;fill-opacity:1" /><path
|
||||||
|
class="st0"
|
||||||
|
d="M8.5,35.7c-0.1-0.7-0.1-1.4,0-2.1l0.1-0.2c0-0.2,0-0.4,0-0.6c0-0.2,0-0.3,0.1-0.5c0-0.2,0-0.3,0-0.5 c0.2-2.1,1.6-4.4,3.2-5.7c0.4-0.4,0.9-0.6,1.4-0.9c-0.5-0.5-1.3-0.7-2-0.7H7c-1.4,0-2.6,1.8-2.4,2.7v0.3 C5.1,29.8,6.8,33.5,8.5,35.7z"
|
||||||
|
id="path18"
|
||||||
|
style="fill:#000000;fill-opacity:1" /></g></svg>
|
After Width: | Height: | Size: 2.9 KiB |
24
interface/resources/icons/tablet-icons/people-i-msg.svg
Normal file
24
interface/resources/icons/tablet-icons/people-i-msg.svg
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<?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" 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>
|
||||||
|
<circle class="st1" cx="44.1" cy="6" r="5.6"/>
|
||||||
|
<g id="Layer_2">
|
||||||
|
</g>
|
||||||
|
<g id="Layer_1">
|
||||||
|
<circle class="st0" cx="25.6" cy="14.8" r="8.1"/>
|
||||||
|
<path class="st0" d="M31.4,27h-11c-4.6,0-8.2,3.9-8.2,8.5v4.3c3.8,2.8,8.1,4.5,13.1,4.5c5.6,0,10.6-2.1,14.4-5.6v-3.2
|
||||||
|
C39.6,30.9,35.9,27,31.4,27z"/>
|
||||||
|
<circle class="st0" cx="41.6" cy="17.1" r="3.5"/>
|
||||||
|
<path class="st0" d="M43.9,23.9h-4.1c-0.9,0-1.7,0.4-2.3,1c1.2,0.6,2.3,1.6,3.1,2.5c1,1.2,1.5,2.7,1.7,4.3c0.3,0.9,0.4,1.8,0.2,2.8
|
||||||
|
v0.6c1.6-2.2,3.3-6,4-8.1v-0.3C46.5,25.7,45.3,23.9,43.9,23.9z"/>
|
||||||
|
<circle class="st0" cx="9.4" cy="18" r="3.5"/>
|
||||||
|
<path class="st0" d="M8.5,35.7c-0.1-0.7-0.1-1.4,0-2.1l0.1-0.2c0-0.2,0-0.4,0-0.6c0-0.2,0-0.3,0.1-0.5c0-0.2,0-0.3,0-0.5
|
||||||
|
c0.2-2.1,1.6-4.4,3.2-5.7c0.4-0.4,0.9-0.6,1.4-0.9c-0.5-0.5-1.3-0.7-2-0.7H7c-1.4,0-2.6,1.8-2.4,2.7v0.3
|
||||||
|
C5.1,29.8,6.8,33.5,8.5,35.7z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
|
@ -271,6 +271,8 @@ Rectangle {
|
||||||
connectionsUserModel.getFirstPage();
|
connectionsUserModel.getFirstPage();
|
||||||
}
|
}
|
||||||
activeTab = "connectionsTab";
|
activeTab = "connectionsTab";
|
||||||
|
connectionsOnlineDot.visible = false;
|
||||||
|
pal.sendToScript({method: 'hideNotificationDot'});
|
||||||
connectionsHelpText.color = hifi.colors.blueAccent;
|
connectionsHelpText.color = hifi.colors.blueAccent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -298,6 +300,16 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Rectangle {
|
||||||
|
id: connectionsOnlineDot;
|
||||||
|
visible: false;
|
||||||
|
width: 10;
|
||||||
|
height: width;
|
||||||
|
radius: width;
|
||||||
|
color: "#EF3B4E"
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.verticalCenter: parent.verticalCenter;
|
||||||
|
}
|
||||||
// "CONNECTIONS" text
|
// "CONNECTIONS" text
|
||||||
RalewaySemiBold {
|
RalewaySemiBold {
|
||||||
id: connectionsTabSelectorText;
|
id: connectionsTabSelectorText;
|
||||||
|
@ -305,7 +317,11 @@ Rectangle {
|
||||||
// Text size
|
// Text size
|
||||||
size: hifi.fontSizes.tabularData;
|
size: hifi.fontSizes.tabularData;
|
||||||
// Anchors
|
// Anchors
|
||||||
anchors.fill: parent;
|
anchors.left: connectionsOnlineDot.visible ? connectionsOnlineDot.right : parent.left;
|
||||||
|
anchors.leftMargin: connectionsOnlineDot.visible ? 4 : 0;
|
||||||
|
anchors.top: parent.top;
|
||||||
|
anchors.bottom: parent.bottom;
|
||||||
|
anchors.right: parent.right;
|
||||||
// Style
|
// Style
|
||||||
font.capitalization: Font.AllUppercase;
|
font.capitalization: Font.AllUppercase;
|
||||||
color: activeTab === "connectionsTab" ? hifi.colors.blueAccent : hifi.colors.baseGray;
|
color: activeTab === "connectionsTab" ? hifi.colors.blueAccent : hifi.colors.baseGray;
|
||||||
|
@ -326,7 +342,7 @@ Rectangle {
|
||||||
anchors.left: connectionsTabSelectorTextContainer.left;
|
anchors.left: connectionsTabSelectorTextContainer.left;
|
||||||
anchors.top: connectionsTabSelectorTextContainer.top;
|
anchors.top: connectionsTabSelectorTextContainer.top;
|
||||||
anchors.topMargin: 1;
|
anchors.topMargin: 1;
|
||||||
anchors.leftMargin: connectionsTabSelectorTextMetrics.width + 42;
|
anchors.leftMargin: connectionsTabSelectorTextMetrics.width + 42 + connectionsOnlineDot.width + connectionsTabSelectorText.anchors.leftMargin;
|
||||||
RalewayRegular {
|
RalewayRegular {
|
||||||
id: connectionsHelpText;
|
id: connectionsHelpText;
|
||||||
text: "[?]";
|
text: "[?]";
|
||||||
|
@ -1267,6 +1283,9 @@ Rectangle {
|
||||||
case 'http.response':
|
case 'http.response':
|
||||||
http.handleHttpResponse(message);
|
http.handleHttpResponse(message);
|
||||||
break;
|
break;
|
||||||
|
case 'changeConnectionsDotStatus':
|
||||||
|
connectionsOnlineDot.visible = message.shouldShowDot;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
console.log('Unrecognized message:', JSON.stringify(message));
|
console.log('Unrecognized message:', JSON.stringify(message));
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
function AppUi(properties) {
|
function AppUi(properties) {
|
||||||
|
var request = Script.require('request').request;
|
||||||
/* Example development order:
|
/* Example development order:
|
||||||
1. var AppUi = Script.require('appUi');
|
1. var AppUi = Script.require('appUi');
|
||||||
2. Put appname-i.svg, appname-a.svg in graphicsDirectory (where non-default graphicsDirectory can be added in #3).
|
2. Put appname-i.svg, appname-a.svg in graphicsDirectory (where non-default graphicsDirectory can be added in #3).
|
||||||
|
@ -80,13 +81,6 @@ function AppUi(properties) {
|
||||||
that.buttonActive = function buttonActive(isActive) { // How to make the button active (white).
|
that.buttonActive = function buttonActive(isActive) { // How to make the button active (white).
|
||||||
that.button.editProperties({isActive: isActive});
|
that.button.editProperties({isActive: isActive});
|
||||||
};
|
};
|
||||||
that.messagesWaiting = function messagesWaiting(isWaiting) { // How to indicate a message light on button.
|
|
||||||
// Note that waitingButton doesn't have to exist unless someone explicitly calls this with isWaiting true.
|
|
||||||
that.button.editProperties({
|
|
||||||
icon: isWaiting ? that.normalMessagesButton : that.normalButton,
|
|
||||||
activeIcon: isWaiting ? that.activeMessagesButton : that.activeButton
|
|
||||||
});
|
|
||||||
};
|
|
||||||
that.isQMLUrl = function isQMLUrl(url) {
|
that.isQMLUrl = function isQMLUrl(url) {
|
||||||
var type = /.qml$/.test(url) ? 'QML' : 'Web';
|
var type = /.qml$/.test(url) ? 'QML' : 'Web';
|
||||||
return type === 'QML';
|
return type === 'QML';
|
||||||
|
@ -95,6 +89,32 @@ function AppUi(properties) {
|
||||||
return that.currentVisibleScreenType === 'QML';
|
return that.currentVisibleScreenType === 'QML';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// START Notification Handling Defaults
|
||||||
|
//
|
||||||
|
that.messagesWaiting = function messagesWaiting(isWaiting) { // How to indicate a message light on button.
|
||||||
|
// Note that waitingButton doesn't have to exist unless someone explicitly calls this with isWaiting true.
|
||||||
|
that.button.editProperties({
|
||||||
|
icon: isWaiting ? that.normalMessagesButton : that.normalButton,
|
||||||
|
activeIcon: isWaiting ? that.activeMessagesButton : that.activeButton
|
||||||
|
});
|
||||||
|
};
|
||||||
|
that.notificationPollTimeout = false;
|
||||||
|
that.notificationPollTimeoutMs = 60000;
|
||||||
|
that.notificationPollEndpoint = false;
|
||||||
|
that.notificationPollStopPaginatingConditionMet = false;
|
||||||
|
that.notificationDataProcessPage = function (data) {
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
that.notificationPollCallback = that.ignore;
|
||||||
|
that.notificationPollCaresAboutSince = false;
|
||||||
|
that.notificationDisplayBanner = function (message) {
|
||||||
|
Window.displayAnnouncement(message);
|
||||||
|
};
|
||||||
|
//
|
||||||
|
// END Notification Handling Defaults
|
||||||
|
//
|
||||||
|
|
||||||
// Handlers
|
// Handlers
|
||||||
that.onScreenChanged = function onScreenChanged(type, url) {
|
that.onScreenChanged = function onScreenChanged(type, url) {
|
||||||
// Set isOpen, wireEventBridge, set buttonActive as appropriate,
|
// Set isOpen, wireEventBridge, set buttonActive as appropriate,
|
||||||
|
@ -126,6 +146,75 @@ function AppUi(properties) {
|
||||||
// Overwrite with the given properties:
|
// Overwrite with the given properties:
|
||||||
Object.keys(properties).forEach(function (key) { that[key] = properties[key]; });
|
Object.keys(properties).forEach(function (key) { that[key] = properties[key]; });
|
||||||
|
|
||||||
|
//
|
||||||
|
// START Notification Handling
|
||||||
|
//
|
||||||
|
var METAVERSE_BASE = Account.metaverseServerURL;
|
||||||
|
var currentDataPageToRetrieve = 1;
|
||||||
|
var concatenatedServerResponse = new Array();
|
||||||
|
that.notificationPoll = function () {
|
||||||
|
if (!that.notificationPollEndpoint) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// User is "appearing offline"
|
||||||
|
if (GlobalServices.findableBy === "none") {
|
||||||
|
that.notificationPollTimeout = Script.setTimeout(that.notificationPoll, that.notificationPollTimeoutMs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var url = METAVERSE_BASE + that.notificationPollEndpoint;
|
||||||
|
|
||||||
|
if (that.notificationPollCaresAboutSince) {
|
||||||
|
url = url + "&since=" + (new Date().getTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
console.debug(that.buttonName, 'polling for notifications at endpoint', url);
|
||||||
|
|
||||||
|
function requestCallback(error, response) {
|
||||||
|
if (error || (response.status !== 'success')) {
|
||||||
|
print("Error: unable to get", url, error || response.status);
|
||||||
|
that.notificationPollTimeout = Script.setTimeout(that.notificationPoll, that.notificationPollTimeoutMs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!that.notificationPollStopPaginatingConditionMet || that.notificationPollStopPaginatingConditionMet(response)) {
|
||||||
|
that.notificationPollTimeout = Script.setTimeout(that.notificationPoll, that.notificationPollTimeoutMs);
|
||||||
|
|
||||||
|
var notificationData;
|
||||||
|
if (concatenatedServerResponse.length) {
|
||||||
|
notificationData = concatenatedServerResponse;
|
||||||
|
} else {
|
||||||
|
notificationData = that.notificationDataProcessPage(response);
|
||||||
|
}
|
||||||
|
console.debug(that.buttonName, 'notification data for processing:', JSON.stringify(notificationData));
|
||||||
|
that.notificationPollCallback(notificationData);
|
||||||
|
currentDataPageToRetrieve = 1;
|
||||||
|
concatenatedServerResponse = new Array();
|
||||||
|
} else {
|
||||||
|
concatenatedServerResponse = concatenatedServerResponse.concat(that.notificationDataProcessPage(response));
|
||||||
|
currentDataPageToRetrieve++;
|
||||||
|
request({ uri: (url + "&page=" + currentDataPageToRetrieve) }, requestCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
request({ uri: url }, requestCallback);
|
||||||
|
};
|
||||||
|
|
||||||
|
// This won't do anything if there isn't a notification endpoint set
|
||||||
|
that.notificationPoll();
|
||||||
|
|
||||||
|
function availabilityChanged() {
|
||||||
|
if (that.notificationPollTimeout) {
|
||||||
|
Script.clearTimeout(that.notificationPollTimeout);
|
||||||
|
that.notificationPollTimeout = false;
|
||||||
|
}
|
||||||
|
that.notificationPoll();
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// END Notification Handling
|
||||||
|
//
|
||||||
|
|
||||||
// Properties:
|
// Properties:
|
||||||
that.tablet = Tablet.getTablet(that.tabletName);
|
that.tablet = Tablet.getTablet(that.tabletName);
|
||||||
// Must be after we gather properties.
|
// Must be after we gather properties.
|
||||||
|
@ -147,8 +236,9 @@ function AppUi(properties) {
|
||||||
}
|
}
|
||||||
that.button = that.tablet.addButton(buttonOptions);
|
that.button = that.tablet.addButton(buttonOptions);
|
||||||
that.ignore = function ignore() { };
|
that.ignore = function ignore() { };
|
||||||
that.hasQmlEventBridge = false;
|
that.hasOutboundEventBridge = false;
|
||||||
that.hasHtmlEventBridge = false;
|
that.hasInboundQmlEventBridge = false;
|
||||||
|
that.hasInboundHtmlEventBridge = false;
|
||||||
// HTML event bridge uses strings, not objects. Here we abstract over that.
|
// HTML event bridge uses strings, not objects. Here we abstract over that.
|
||||||
// (Although injected javascript still has to use JSON.stringify/JSON.parse.)
|
// (Although injected javascript still has to use JSON.stringify/JSON.parse.)
|
||||||
that.sendToHtml = function (messageObject) {
|
that.sendToHtml = function (messageObject) {
|
||||||
|
@ -167,8 +257,10 @@ function AppUi(properties) {
|
||||||
// Outbound (always, regardless of whether there is an inbound handler).
|
// Outbound (always, regardless of whether there is an inbound handler).
|
||||||
if (on) {
|
if (on) {
|
||||||
that.sendMessage = isCurrentlyOnQMLScreen ? that.tablet.sendToQml : that.sendToHtml;
|
that.sendMessage = isCurrentlyOnQMLScreen ? that.tablet.sendToQml : that.sendToHtml;
|
||||||
|
that.hasOutboundEventBridge = true;
|
||||||
} else {
|
} else {
|
||||||
that.sendMessage = that.ignore;
|
that.sendMessage = that.ignore;
|
||||||
|
that.hasOutboundEventBridge = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!that.onMessage) {
|
if (!that.onMessage) {
|
||||||
|
@ -177,25 +269,25 @@ function AppUi(properties) {
|
||||||
|
|
||||||
// Inbound
|
// Inbound
|
||||||
if (on) {
|
if (on) {
|
||||||
if (isCurrentlyOnQMLScreen && !that.hasQmlEventBridge) {
|
if (isCurrentlyOnQMLScreen && !that.hasInboundQmlEventBridge) {
|
||||||
console.debug(that.buttonName, 'connecting', that.tablet.fromQml);
|
console.debug(that.buttonName, 'connecting', that.tablet.fromQml);
|
||||||
that.tablet.fromQml.connect(that.onMessage);
|
that.tablet.fromQml.connect(that.onMessage);
|
||||||
that.hasQmlEventBridge = true;
|
that.hasInboundQmlEventBridge = true;
|
||||||
} else if (!isCurrentlyOnQMLScreen && !that.hasHtmlEventBridge) {
|
} else if (!isCurrentlyOnQMLScreen && !that.hasInboundHtmlEventBridge) {
|
||||||
console.debug(that.buttonName, 'connecting', that.tablet.webEventReceived);
|
console.debug(that.buttonName, 'connecting', that.tablet.webEventReceived);
|
||||||
that.tablet.webEventReceived.connect(that.fromHtml);
|
that.tablet.webEventReceived.connect(that.fromHtml);
|
||||||
that.hasHtmlEventBridge = true;
|
that.hasInboundHtmlEventBridge = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (that.hasQmlEventBridge) {
|
if (that.hasInboundQmlEventBridge) {
|
||||||
console.debug(that.buttonName, 'disconnecting', that.tablet.fromQml);
|
console.debug(that.buttonName, 'disconnecting', that.tablet.fromQml);
|
||||||
that.tablet.fromQml.disconnect(that.onMessage);
|
that.tablet.fromQml.disconnect(that.onMessage);
|
||||||
that.hasQmlEventBridge = false;
|
that.hasInboundQmlEventBridge = false;
|
||||||
}
|
}
|
||||||
if (that.hasHtmlEventBridge) {
|
if (that.hasInboundHtmlEventBridge) {
|
||||||
console.debug(that.buttonName, 'disconnecting', that.tablet.webEventReceived);
|
console.debug(that.buttonName, 'disconnecting', that.tablet.webEventReceived);
|
||||||
that.tablet.webEventReceived.disconnect(that.fromHtml);
|
that.tablet.webEventReceived.disconnect(that.fromHtml);
|
||||||
that.hasHtmlEventBridge = false;
|
that.hasInboundHtmlEventBridge = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -212,6 +304,7 @@ function AppUi(properties) {
|
||||||
} : that.ignore;
|
} : that.ignore;
|
||||||
that.onScriptEnding = function onScriptEnding() {
|
that.onScriptEnding = function onScriptEnding() {
|
||||||
// Close if necessary, clean up any remaining handlers, and remove the button.
|
// Close if necessary, clean up any remaining handlers, and remove the button.
|
||||||
|
GlobalServices.findableByChanged.disconnect(availabilityChanged);
|
||||||
if (that.isOpen) {
|
if (that.isOpen) {
|
||||||
that.close();
|
that.close();
|
||||||
}
|
}
|
||||||
|
@ -222,10 +315,15 @@ function AppUi(properties) {
|
||||||
}
|
}
|
||||||
that.tablet.removeButton(that.button);
|
that.tablet.removeButton(that.button);
|
||||||
}
|
}
|
||||||
|
if (that.notificationPollTimeout) {
|
||||||
|
Script.clearInterval(that.notificationPollTimeout);
|
||||||
|
that.notificationPollTimeout = false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
// Set up the handlers.
|
// Set up the handlers.
|
||||||
that.tablet.screenChanged.connect(that.onScreenChanged);
|
that.tablet.screenChanged.connect(that.onScreenChanged);
|
||||||
that.button.clicked.connect(that.onClicked);
|
that.button.clicked.connect(that.onClicked);
|
||||||
Script.scriptEnding.connect(that.onScriptEnding);
|
Script.scriptEnding.connect(that.onScriptEnding);
|
||||||
|
GlobalServices.findableByChanged.connect(availabilityChanged);
|
||||||
}
|
}
|
||||||
module.exports = AppUi;
|
module.exports = AppUi;
|
||||||
|
|
|
@ -321,6 +321,10 @@ function fromQml(message) { // messages are {method, params}, like json-rpc. See
|
||||||
break;
|
break;
|
||||||
case 'http.request':
|
case 'http.request':
|
||||||
break; // Handled by request-service.
|
break; // Handled by request-service.
|
||||||
|
case 'hideNotificationDot':
|
||||||
|
shouldShowDot = false;
|
||||||
|
ui.messagesWaiting(shouldShowDot);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
print('Unrecognized message from Pal.qml:', JSON.stringify(message));
|
print('Unrecognized message from Pal.qml:', JSON.stringify(message));
|
||||||
}
|
}
|
||||||
|
@ -364,8 +368,8 @@ function getProfilePicture(username, callback) { // callback(url) if successfull
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
var SAFETY_LIMIT = 400;
|
var SAFETY_LIMIT = 400;
|
||||||
function getAvailableConnections(domain, callback) { // callback([{usename, location}...]) if successfull. (Logs otherwise)
|
function getAvailableConnections(domain, callback, numResultsPerPage) { // callback([{usename, location}...]) if successfull. (Logs otherwise)
|
||||||
var url = METAVERSE_BASE + '/api/v1/users?per_page=' + SAFETY_LIMIT + '&';
|
var url = METAVERSE_BASE + '/api/v1/users?per_page=' + (numResultsPerPage || SAFETY_LIMIT) + '&';
|
||||||
if (domain) {
|
if (domain) {
|
||||||
url += 'status=' + domain.slice(1, -1); // without curly braces
|
url += 'status=' + domain.slice(1, -1); // without curly braces
|
||||||
} else {
|
} else {
|
||||||
|
@ -728,10 +732,14 @@ function createUpdateInterval() {
|
||||||
|
|
||||||
var previousContextOverlay = ContextOverlay.enabled;
|
var previousContextOverlay = ContextOverlay.enabled;
|
||||||
var previousRequestsDomainListData = Users.requestsDomainListData;
|
var previousRequestsDomainListData = Users.requestsDomainListData;
|
||||||
function on() {
|
function palOpened() {
|
||||||
|
ui.sendMessage({
|
||||||
|
method: 'changeConnectionsDotStatus',
|
||||||
|
shouldShowDot: shouldShowDot
|
||||||
|
});
|
||||||
|
|
||||||
previousContextOverlay = ContextOverlay.enabled;
|
previousContextOverlay = ContextOverlay.enabled;
|
||||||
previousRequestsDomainListData = Users.requestsDomainListData
|
previousRequestsDomainListData = Users.requestsDomainListData;
|
||||||
ContextOverlay.enabled = false;
|
ContextOverlay.enabled = false;
|
||||||
Users.requestsDomainListData = true;
|
Users.requestsDomainListData = true;
|
||||||
|
|
||||||
|
@ -810,14 +818,56 @@ function avatarSessionChanged(avatarID) {
|
||||||
sendToQml({ method: 'palIsStale', params: [avatarID, 'avatarSessionChanged'] });
|
sendToQml({ method: 'palIsStale', params: [avatarID, 'avatarSessionChanged'] });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function notificationDataProcessPage(data) {
|
||||||
|
return data.data.users;
|
||||||
|
}
|
||||||
|
|
||||||
|
var shouldShowDot = false;
|
||||||
|
var firstBannerNotificationShown = false;
|
||||||
|
function notificationPollCallback(onlineUsersArray) {
|
||||||
|
shouldShowDot = onlineUsersArray.length > 0;
|
||||||
|
|
||||||
|
if (!ui.isOpen) {
|
||||||
|
ui.messagesWaiting(shouldShowDot);
|
||||||
|
ui.sendMessage({
|
||||||
|
method: 'changeConnectionsDotStatus',
|
||||||
|
shouldShowDot: shouldShowDot
|
||||||
|
});
|
||||||
|
|
||||||
|
var message;
|
||||||
|
if (!firstBannerNotificationShown) {
|
||||||
|
message = onlineUsersArray.length + " of your connections are online. Open PEOPLE to join them!";
|
||||||
|
ui.notificationDisplayBanner(message);
|
||||||
|
firstBannerNotificationShown = true;
|
||||||
|
} else {
|
||||||
|
for (var i = 0; i < onlineUsersArray.length; i++) {
|
||||||
|
message = onlineUsersArray[i].username + " is available in " +
|
||||||
|
onlineUsersArray[i].location.root.name + ". Open PEOPLE to join them!";
|
||||||
|
ui.notificationDisplayBanner(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function isReturnedDataEmpty(data) {
|
||||||
|
var usersArray = data.data.users;
|
||||||
|
return usersArray.length === 0;
|
||||||
|
}
|
||||||
|
|
||||||
function startup() {
|
function startup() {
|
||||||
ui = new AppUi({
|
ui = new AppUi({
|
||||||
buttonName: "PEOPLE",
|
buttonName: "PEOPLE",
|
||||||
sortOrder: 7,
|
sortOrder: 7,
|
||||||
home: "hifi/Pal.qml",
|
home: "hifi/Pal.qml",
|
||||||
onOpened: on,
|
onOpened: palOpened,
|
||||||
onClosed: off,
|
onClosed: off,
|
||||||
onMessage: fromQml
|
onMessage: fromQml,
|
||||||
|
notificationPollEndpoint: "/api/v1/users?filter=connections&status=online&per_page=10",
|
||||||
|
notificationPollTimeoutMs: 60000,
|
||||||
|
notificationDataProcessPage: notificationDataProcessPage,
|
||||||
|
notificationPollCallback: notificationPollCallback,
|
||||||
|
notificationPollStopPaginatingConditionMet: isReturnedDataEmpty,
|
||||||
|
notificationPollCaresAboutSince: true
|
||||||
});
|
});
|
||||||
Window.domainChanged.connect(clearLocalQMLDataAndClosePAL);
|
Window.domainChanged.connect(clearLocalQMLDataAndClosePAL);
|
||||||
Window.domainConnectionRefused.connect(clearLocalQMLDataAndClosePAL);
|
Window.domainConnectionRefused.connect(clearLocalQMLDataAndClosePAL);
|
||||||
|
|
Loading…
Reference in a new issue