mirror of
https://github.com/overte-org/overte.git
synced 2025-04-08 08:14:48 +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();
|
||||
}
|
||||
activeTab = "connectionsTab";
|
||||
connectionsOnlineDot.visible = false;
|
||||
pal.sendToScript({method: 'hideNotificationDot'});
|
||||
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
|
||||
RalewaySemiBold {
|
||||
id: connectionsTabSelectorText;
|
||||
|
@ -305,7 +317,11 @@ Rectangle {
|
|||
// Text size
|
||||
size: hifi.fontSizes.tabularData;
|
||||
// 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
|
||||
font.capitalization: Font.AllUppercase;
|
||||
color: activeTab === "connectionsTab" ? hifi.colors.blueAccent : hifi.colors.baseGray;
|
||||
|
@ -326,7 +342,7 @@ Rectangle {
|
|||
anchors.left: connectionsTabSelectorTextContainer.left;
|
||||
anchors.top: connectionsTabSelectorTextContainer.top;
|
||||
anchors.topMargin: 1;
|
||||
anchors.leftMargin: connectionsTabSelectorTextMetrics.width + 42;
|
||||
anchors.leftMargin: connectionsTabSelectorTextMetrics.width + 42 + connectionsOnlineDot.width + connectionsTabSelectorText.anchors.leftMargin;
|
||||
RalewayRegular {
|
||||
id: connectionsHelpText;
|
||||
text: "[?]";
|
||||
|
@ -1267,6 +1283,9 @@ Rectangle {
|
|||
case 'http.response':
|
||||
http.handleHttpResponse(message);
|
||||
break;
|
||||
case 'changeConnectionsDotStatus':
|
||||
connectionsOnlineDot.visible = message.shouldShowDot;
|
||||
break;
|
||||
default:
|
||||
console.log('Unrecognized message:', JSON.stringify(message));
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
//
|
||||
|
||||
function AppUi(properties) {
|
||||
var request = Script.require('request').request;
|
||||
/* Example development order:
|
||||
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).
|
||||
|
@ -80,13 +81,6 @@ function AppUi(properties) {
|
|||
that.buttonActive = function buttonActive(isActive) { // How to make the button active (white).
|
||||
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) {
|
||||
var type = /.qml$/.test(url) ? 'QML' : 'Web';
|
||||
return type === 'QML';
|
||||
|
@ -95,6 +89,32 @@ function AppUi(properties) {
|
|||
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
|
||||
that.onScreenChanged = function onScreenChanged(type, url) {
|
||||
// Set isOpen, wireEventBridge, set buttonActive as appropriate,
|
||||
|
@ -126,6 +146,75 @@ function AppUi(properties) {
|
|||
// Overwrite with the given properties:
|
||||
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:
|
||||
that.tablet = Tablet.getTablet(that.tabletName);
|
||||
// Must be after we gather properties.
|
||||
|
@ -147,8 +236,9 @@ function AppUi(properties) {
|
|||
}
|
||||
that.button = that.tablet.addButton(buttonOptions);
|
||||
that.ignore = function ignore() { };
|
||||
that.hasQmlEventBridge = false;
|
||||
that.hasHtmlEventBridge = false;
|
||||
that.hasOutboundEventBridge = false;
|
||||
that.hasInboundQmlEventBridge = false;
|
||||
that.hasInboundHtmlEventBridge = false;
|
||||
// HTML event bridge uses strings, not objects. Here we abstract over that.
|
||||
// (Although injected javascript still has to use JSON.stringify/JSON.parse.)
|
||||
that.sendToHtml = function (messageObject) {
|
||||
|
@ -167,8 +257,10 @@ function AppUi(properties) {
|
|||
// Outbound (always, regardless of whether there is an inbound handler).
|
||||
if (on) {
|
||||
that.sendMessage = isCurrentlyOnQMLScreen ? that.tablet.sendToQml : that.sendToHtml;
|
||||
that.hasOutboundEventBridge = true;
|
||||
} else {
|
||||
that.sendMessage = that.ignore;
|
||||
that.hasOutboundEventBridge = false;
|
||||
}
|
||||
|
||||
if (!that.onMessage) {
|
||||
|
@ -177,25 +269,25 @@ function AppUi(properties) {
|
|||
|
||||
// Inbound
|
||||
if (on) {
|
||||
if (isCurrentlyOnQMLScreen && !that.hasQmlEventBridge) {
|
||||
if (isCurrentlyOnQMLScreen && !that.hasInboundQmlEventBridge) {
|
||||
console.debug(that.buttonName, 'connecting', that.tablet.fromQml);
|
||||
that.tablet.fromQml.connect(that.onMessage);
|
||||
that.hasQmlEventBridge = true;
|
||||
} else if (!isCurrentlyOnQMLScreen && !that.hasHtmlEventBridge) {
|
||||
that.hasInboundQmlEventBridge = true;
|
||||
} else if (!isCurrentlyOnQMLScreen && !that.hasInboundHtmlEventBridge) {
|
||||
console.debug(that.buttonName, 'connecting', that.tablet.webEventReceived);
|
||||
that.tablet.webEventReceived.connect(that.fromHtml);
|
||||
that.hasHtmlEventBridge = true;
|
||||
that.hasInboundHtmlEventBridge = true;
|
||||
}
|
||||
} else {
|
||||
if (that.hasQmlEventBridge) {
|
||||
if (that.hasInboundQmlEventBridge) {
|
||||
console.debug(that.buttonName, 'disconnecting', that.tablet.fromQml);
|
||||
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);
|
||||
that.tablet.webEventReceived.disconnect(that.fromHtml);
|
||||
that.hasHtmlEventBridge = false;
|
||||
that.hasInboundHtmlEventBridge = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -212,6 +304,7 @@ function AppUi(properties) {
|
|||
} : that.ignore;
|
||||
that.onScriptEnding = function onScriptEnding() {
|
||||
// Close if necessary, clean up any remaining handlers, and remove the button.
|
||||
GlobalServices.findableByChanged.disconnect(availabilityChanged);
|
||||
if (that.isOpen) {
|
||||
that.close();
|
||||
}
|
||||
|
@ -222,10 +315,15 @@ function AppUi(properties) {
|
|||
}
|
||||
that.tablet.removeButton(that.button);
|
||||
}
|
||||
if (that.notificationPollTimeout) {
|
||||
Script.clearInterval(that.notificationPollTimeout);
|
||||
that.notificationPollTimeout = false;
|
||||
}
|
||||
};
|
||||
// Set up the handlers.
|
||||
that.tablet.screenChanged.connect(that.onScreenChanged);
|
||||
that.button.clicked.connect(that.onClicked);
|
||||
Script.scriptEnding.connect(that.onScriptEnding);
|
||||
GlobalServices.findableByChanged.connect(availabilityChanged);
|
||||
}
|
||||
module.exports = AppUi;
|
||||
|
|
|
@ -321,6 +321,10 @@ function fromQml(message) { // messages are {method, params}, like json-rpc. See
|
|||
break;
|
||||
case 'http.request':
|
||||
break; // Handled by request-service.
|
||||
case 'hideNotificationDot':
|
||||
shouldShowDot = false;
|
||||
ui.messagesWaiting(shouldShowDot);
|
||||
break;
|
||||
default:
|
||||
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;
|
||||
function getAvailableConnections(domain, callback) { // callback([{usename, location}...]) if successfull. (Logs otherwise)
|
||||
var url = METAVERSE_BASE + '/api/v1/users?per_page=' + SAFETY_LIMIT + '&';
|
||||
function getAvailableConnections(domain, callback, numResultsPerPage) { // callback([{usename, location}...]) if successfull. (Logs otherwise)
|
||||
var url = METAVERSE_BASE + '/api/v1/users?per_page=' + (numResultsPerPage || SAFETY_LIMIT) + '&';
|
||||
if (domain) {
|
||||
url += 'status=' + domain.slice(1, -1); // without curly braces
|
||||
} else {
|
||||
|
@ -728,10 +732,14 @@ function createUpdateInterval() {
|
|||
|
||||
var previousContextOverlay = ContextOverlay.enabled;
|
||||
var previousRequestsDomainListData = Users.requestsDomainListData;
|
||||
function on() {
|
||||
function palOpened() {
|
||||
ui.sendMessage({
|
||||
method: 'changeConnectionsDotStatus',
|
||||
shouldShowDot: shouldShowDot
|
||||
});
|
||||
|
||||
previousContextOverlay = ContextOverlay.enabled;
|
||||
previousRequestsDomainListData = Users.requestsDomainListData
|
||||
previousRequestsDomainListData = Users.requestsDomainListData;
|
||||
ContextOverlay.enabled = false;
|
||||
Users.requestsDomainListData = true;
|
||||
|
||||
|
@ -810,14 +818,56 @@ function avatarSessionChanged(avatarID) {
|
|||
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() {
|
||||
ui = new AppUi({
|
||||
buttonName: "PEOPLE",
|
||||
sortOrder: 7,
|
||||
home: "hifi/Pal.qml",
|
||||
onOpened: on,
|
||||
onOpened: palOpened,
|
||||
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.domainConnectionRefused.connect(clearLocalQMLDataAndClosePAL);
|
||||
|
|
Loading…
Reference in a new issue