mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-09-01 21:49:21 +03:00
Testing van be done at https://snappymail.eu/demo/
This commit is contained in:
parent
0ec37b7e90
commit
542d9c91e9
10 changed files with 215 additions and 270 deletions
|
|
@ -1,154 +1,96 @@
|
|||
import ko from 'ko';
|
||||
|
||||
import { DesktopNotification } from 'Common/Enums';
|
||||
import Audio from 'Common/Audio';
|
||||
import * as Links from 'Common/Links';
|
||||
|
||||
/**
|
||||
* Might not work due to the new ServiceWorkerRegistration.showNotification
|
||||
*/
|
||||
const HTML5Notification = window.Notification ? Notification : null,
|
||||
HTML5NotificationStatus = () => (HTML5Notification && HTML5Notification.permission) || 'denied',
|
||||
dispatchMessage = data => {
|
||||
focus();
|
||||
if (data.Folder && data.Uid) {
|
||||
dispatchEvent(new CustomEvent('mailbox.message.show', {detail:data}));
|
||||
}
|
||||
};
|
||||
|
||||
let DesktopNotifications = false,
|
||||
WorkerNotifications = navigator.serviceWorker;
|
||||
|
||||
// Are Notifications supported in the service worker?
|
||||
if (WorkerNotifications && ServiceWorkerRegistration && ServiceWorkerRegistration.prototype.showNotification) {
|
||||
console.log('ServiceWorker supported');
|
||||
/* Listen for close requests from the ServiceWorker */
|
||||
WorkerNotifications.addEventListener('message', event => {
|
||||
const obj = JSON.parse(event.data);
|
||||
obj && 'notificationclick' === obj.action && dispatchMessage(obj.data);
|
||||
});
|
||||
} else {
|
||||
WorkerNotifications = null;
|
||||
console.log('WorkerNotifications not supported');
|
||||
}
|
||||
|
||||
class NotificationUserStore {
|
||||
constructor() {
|
||||
this.enableSoundNotification = ko.observable(false);
|
||||
this.soundNotificationIsSupported = ko.observable(false);
|
||||
|
||||
this.allowDesktopNotification = ko.observable(false);
|
||||
this.enableDesktopNotification = ko.observable(false)/*.extend({ notify: 'always' })*/;
|
||||
|
||||
this.desktopNotificationPermissions = ko
|
||||
.computed(() => {
|
||||
this.allowDesktopNotification();
|
||||
this.isDesktopNotificationDenied = ko.observable('denied' === HTML5NotificationStatus());
|
||||
|
||||
let result = DesktopNotification.NotSupported;
|
||||
|
||||
const NotificationClass = this.notificationClass();
|
||||
if (NotificationClass && NotificationClass.permission) {
|
||||
switch (NotificationClass.permission.toLowerCase()) {
|
||||
case 'granted':
|
||||
result = DesktopNotification.Allowed;
|
||||
break;
|
||||
case 'denied':
|
||||
result = DesktopNotification.Denied;
|
||||
break;
|
||||
case 'default':
|
||||
result = DesktopNotification.NotAllowed;
|
||||
break;
|
||||
// no default
|
||||
}
|
||||
} else if (window.webkitNotifications && window.webkitNotifications.checkPermission) {
|
||||
result = window.webkitNotifications.checkPermission();
|
||||
}
|
||||
|
||||
return result;
|
||||
})
|
||||
.extend({ notify: 'always' });
|
||||
|
||||
this.enableDesktopNotification = ko
|
||||
.computed({
|
||||
read: () =>
|
||||
this.allowDesktopNotification() && DesktopNotification.Allowed === this.desktopNotificationPermissions(),
|
||||
write: (value) => {
|
||||
if (value) {
|
||||
const NotificationClass = this.notificationClass(),
|
||||
permission = this.desktopNotificationPermissions();
|
||||
|
||||
if (NotificationClass && DesktopNotification.Allowed === permission) {
|
||||
this.allowDesktopNotification(true);
|
||||
} else if (NotificationClass && DesktopNotification.NotAllowed === permission) {
|
||||
NotificationClass.requestPermission(() => {
|
||||
this.allowDesktopNotification.valueHasMutated();
|
||||
|
||||
if (DesktopNotification.Allowed === this.desktopNotificationPermissions()) {
|
||||
if (this.allowDesktopNotification()) {
|
||||
this.allowDesktopNotification.valueHasMutated();
|
||||
} else {
|
||||
this.allowDesktopNotification(true);
|
||||
}
|
||||
} else {
|
||||
if (this.allowDesktopNotification()) {
|
||||
this.allowDesktopNotification(false);
|
||||
} else {
|
||||
this.allowDesktopNotification.valueHasMutated();
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.allowDesktopNotification(false);
|
||||
}
|
||||
} else {
|
||||
this.allowDesktopNotification(false);
|
||||
}
|
||||
}
|
||||
})
|
||||
.extend({ notify: 'always' });
|
||||
|
||||
if (!this.enableDesktopNotification.valueHasMutated) {
|
||||
this.enableDesktopNotification.valueHasMutated = () => {
|
||||
this.allowDesktopNotification.valueHasMutated();
|
||||
};
|
||||
}
|
||||
|
||||
this.isDesktopNotificationSupported = ko.computed(
|
||||
() => DesktopNotification.NotSupported !== this.desktopNotificationPermissions()
|
||||
);
|
||||
|
||||
this.isDesktopNotificationDenied = ko.computed(
|
||||
() =>
|
||||
DesktopNotification.NotSupported === this.desktopNotificationPermissions() ||
|
||||
DesktopNotification.Denied === this.desktopNotificationPermissions()
|
||||
);
|
||||
|
||||
this.initNotificationPlayer();
|
||||
}
|
||||
|
||||
initNotificationPlayer() {
|
||||
if (Audio && Audio.supportedNotification) {
|
||||
this.soundNotificationIsSupported(true);
|
||||
} else {
|
||||
this.enableSoundNotification(false);
|
||||
this.soundNotificationIsSupported(false);
|
||||
}
|
||||
this.enableDesktopNotification.subscribe(value => {
|
||||
DesktopNotifications = !!value;
|
||||
if (value && HTML5Notification && 'granted' !== HTML5Notification.permission) {
|
||||
HTML5Notification.requestPermission(() =>
|
||||
this.isDesktopNotificationDenied('denied' === HTML5Notification.permission)
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Used with SoundNotification setting
|
||||
*/
|
||||
playSoundNotification(skipSetting) {
|
||||
if (Audio && Audio.supportedNotification && (skipSetting ? true : this.enableSoundNotification())) {
|
||||
if (skipSetting ? true : this.enableSoundNotification()) {
|
||||
Audio.playNotification();
|
||||
}
|
||||
}
|
||||
|
||||
displayDesktopNotification(imageSrc, title, text, messageData) {
|
||||
if (this.enableDesktopNotification()) {
|
||||
const NotificationClass = this.notificationClass(),
|
||||
notification = NotificationClass
|
||||
? new NotificationClass(title, {
|
||||
body: text,
|
||||
icon: imageSrc
|
||||
})
|
||||
: null;
|
||||
|
||||
if (notification) {
|
||||
if (notification.show) {
|
||||
notification.show();
|
||||
}
|
||||
|
||||
if (messageData) {
|
||||
notification.onclick = () => {
|
||||
focus();
|
||||
|
||||
if (messageData.Folder && messageData.Uid) {
|
||||
dispatchEvent(new CustomEvent('mailbox.message.show', {detail:messageData}));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
setTimeout(
|
||||
(function(localNotifications) {
|
||||
return () => {
|
||||
if (localNotifications.cancel) {
|
||||
localNotifications.cancel();
|
||||
} else if (localNotifications.close) {
|
||||
localNotifications.close();
|
||||
}
|
||||
};
|
||||
})(notification),
|
||||
7000
|
||||
);
|
||||
/**
|
||||
* Used with DesktopNotifications setting
|
||||
*/
|
||||
displayDesktopNotification(title, text, messageData, imageSrc) {
|
||||
if (DesktopNotifications && 'granted' === HTML5NotificationStatus()) {
|
||||
const options = {
|
||||
body: text,
|
||||
icon: imageSrc || Links.notificationMailIcon(),
|
||||
data: messageData
|
||||
};
|
||||
if (WorkerNotifications) {
|
||||
// Service-Worker-Allowed HTTP header to allow the scope.
|
||||
WorkerNotifications.register('/serviceworker.js')
|
||||
// WorkerNotifications.register(Links.staticPrefix('js/serviceworker.js'), {scope:'/'})
|
||||
.then(() =>
|
||||
WorkerNotifications.ready.then(registration =>
|
||||
/* Show the notification */
|
||||
registration
|
||||
.showNotification(title, options)
|
||||
.then(() =>
|
||||
registration.getNotifications().then((/*notifications*/) => {
|
||||
/* Send an empty message so the Worker knows who the client is */
|
||||
registration.active.postMessage('');
|
||||
})
|
||||
)
|
||||
)
|
||||
)
|
||||
.catch(e => console.error(e));
|
||||
} else {
|
||||
const notification = new HTML5Notification(title, options);
|
||||
notification.show && notification.show();
|
||||
notification.onclick = messageData ? () => dispatchMessage(messageData) : null;
|
||||
setTimeout(() => notification.close(), 7000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -157,13 +99,6 @@ class NotificationUserStore {
|
|||
this.enableSoundNotification(!!rl.settings.get('SoundNotification'));
|
||||
this.enableDesktopNotification(!!rl.settings.get('DesktopNotifications'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {*|null}
|
||||
*/
|
||||
notificationClass() {
|
||||
return window.Notification && Notification.requestPermission ? Notification : null;
|
||||
}
|
||||
}
|
||||
|
||||
export default new NotificationUserStore();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue