Merge pull request #534 from matrix-org/dbkr/platform_notification

Move Notifications into Platform
This commit is contained in:
David Baker 2016-11-02 19:44:12 +00:00 committed by GitHub
commit 0944408946
2 changed files with 70 additions and 28 deletions

View file

@ -36,6 +36,32 @@ export default class BasePlatform {
this.errorDidOccur = errorDidOccur;
}
/**
* Returns true if the platform supports displaying
* notifications, otherwise false.
*/
supportsNotifications() : boolean {
return false;
}
/**
* Returns true if the application currently has permission
* to display notifications. Otherwise false.
*/
maySendNotifications() : boolean {
return false;
}
/**
* Requests permission to send notifications. Returns
* a promise that is resolved when the user has responded
* to the request. The promise has a single string argument
* that is 'granted' if the user allowed the request or
* 'denied' otherwise.
*/
requestNotificationPermission() : Promise<string> {
}
displayNotification(title: string, msg: string, avatarUrl: string) {
}
}

View file

@ -17,6 +17,7 @@ limitations under the License.
'use strict';
var MatrixClientPeg = require("./MatrixClientPeg");
var PlatformPeg = require("./PlatformPeg");
var TextForEvent = require('./TextForEvent');
var Avatar = require('./Avatar');
var dis = require("./dispatcher");
@ -30,13 +31,18 @@ var dis = require("./dispatcher");
*/
var Notifier = {
notifsByRoom: {},
notificationMessageForEvent: function(ev) {
return TextForEvent.textForEvent(ev);
},
_displayPopupNotification: function(ev, room) {
if (!global.Notification || global.Notification.permission != 'granted') {
const plaf = PlatformPeg.get();
if (!plaf) {
return;
}
if (!plaf.supportsNotifications() || !plaf.maySendNotifications()) {
return;
}
if (global.document.hasFocus()) {
@ -67,26 +73,14 @@ var Notifier = {
ev.sender, 40, 40, 'crop'
) : null;
var notification = new global.Notification(
title,
{
"body": msg,
"icon": avatarUrl,
"tag": "matrixreactsdk"
}
);
const notif = plaf.displayNotification(title, msg, avatarUrl);
notification.onclick = function() {
dis.dispatch({
action: 'view_room',
room_id: room.roomId
});
global.focus();
};
global.setTimeout(function() {
notification.close();
}, 5 * 1000);
// if displayNotification returns non-null, the platform supports
// clearing notifications later, so keep track of this.
if (notif) {
if (this.notifsByRoom[ev.getRoomId()] === undefined) this.notifsByRoom[ev.getRoomId()] = [];
this.notifsByRoom[ev.getRoomId()].push(notif);
}
},
_playAudioNotification: function(ev, room) {
@ -100,7 +94,9 @@ var Notifier = {
start: function() {
this.boundOnRoomTimeline = this.onRoomTimeline.bind(this);
this.boundOnSyncStateChange = this.onSyncStateChange.bind(this);
this.boundOnRoomReceipt = this.onRoomReceipt.bind(this);
MatrixClientPeg.get().on('Room.timeline', this.boundOnRoomTimeline);
MatrixClientPeg.get().on("Room.receipt", this.boundOnRoomReceipt);
MatrixClientPeg.get().on("sync", this.boundOnSyncStateChange);
this.toolbarHidden = false;
this.isPrepared = false;
@ -109,21 +105,20 @@ var Notifier = {
stop: function() {
if (MatrixClientPeg.get()) {
MatrixClientPeg.get().removeListener('Room.timeline', this.boundOnRoomTimeline);
MatrixClientPeg.get().removeListener("Room.receipt", this.boundOnRoomReceipt);
MatrixClientPeg.get().removeListener('sync', this.boundOnSyncStateChange);
}
this.isPrepared = false;
},
supportsDesktopNotifications: function() {
return !!global.Notification;
},
havePermission: function() {
if (!this.supportsDesktopNotifications()) return false;
return global.Notification.permission == 'granted';
const plaf = PlatformPeg.get();
return plaf && plaf.supportsNotifications();
},
setEnabled: function(enable, callback) {
const plaf = PlatformPeg.get();
if (!plaf) return;
// make sure that we persist the current setting audio_enabled setting
// before changing anything
if (global.localStorage) {
@ -134,7 +129,7 @@ var Notifier = {
if (enable) {
// Attempt to get permission from user
global.Notification.requestPermission(function(result) {
plaf.requestNotificationPermission().done((result) => {
if (result !== 'granted') {
// The permission request was dismissed or denied
return;
@ -164,7 +159,10 @@ var Notifier = {
},
isEnabled: function() {
if (!this.havePermission()) return false;
const plaf = PlatformPeg.get();
if (!plaf) return false;
if (!plaf.supportsNotifications()) return false;
if (!plaf.maySendNotifications()) return false;
if (!global.localStorage) return true;
@ -240,6 +238,24 @@ var Notifier = {
this._playAudioNotification(ev, room);
}
}
},
onRoomReceipt: function(ev, room) {
if (room.getUnreadNotificationCount() == 0) {
// ideally we would clear each notification when it was read,
// but we have no way, given a read receipt, to know whether
// the receipt comes before or after an event, so we can't
// do this. Instead, clear all notifications for a room once
// there are no notifs left in that room., which is not quite
// as good but it's something.
const plaf = PlatformPeg.get();
if (!plaf) return;
if (this.notifsByRoom[room.roomId] === undefined) return;
for (const notif of this.notifsByRoom[room.roomId]) {
plaf.clearNotification(notif);
}
delete this.notifsByRoom[room.roomId];
}
}
};