mirror of
https://github.com/element-hq/element-web
synced 2024-11-27 03:36:07 +03:00
Merge pull request #534 from matrix-org/dbkr/platform_notification
Move Notifications into Platform
This commit is contained in:
commit
0944408946
2 changed files with 70 additions and 28 deletions
|
@ -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) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue