2022-03-06 18:02:27 +13:00
|
|
|
import {formatMessage, formatTitleWithDefault, openUrl, playSound, topicShortUrl} from "./utils";
|
2022-03-03 10:16:30 +13:00
|
|
|
import prefs from "./Prefs";
|
2022-03-04 10:52:07 +13:00
|
|
|
import subscriptionManager from "./SubscriptionManager";
|
2022-03-10 09:58:21 +13:00
|
|
|
import logo from "../img/ntfy.png";
|
2022-02-27 04:14:43 +13:00
|
|
|
|
2022-03-12 09:17:12 +13:00
|
|
|
/**
|
|
|
|
* The notifier is responsible for displaying desktop notifications. Note that not all modern browsers
|
|
|
|
* support this; most importantly, all iOS browsers do not support window.Notification.
|
|
|
|
*/
|
2022-03-06 18:02:27 +13:00
|
|
|
class Notifier {
|
2022-03-04 10:52:07 +13:00
|
|
|
async notify(subscriptionId, notification, onClickFallback) {
|
2022-03-11 12:11:12 +13:00
|
|
|
if (!this.supported()) {
|
|
|
|
return;
|
|
|
|
}
|
2022-03-04 10:52:07 +13:00
|
|
|
const subscription = await subscriptionManager.get(subscriptionId);
|
2022-03-02 16:41:49 +13:00
|
|
|
const shouldNotify = await this.shouldNotify(subscription, notification);
|
|
|
|
if (!shouldNotify) {
|
2022-03-02 10:22:47 +13:00
|
|
|
return;
|
|
|
|
}
|
2022-03-03 10:16:30 +13:00
|
|
|
const shortUrl = topicShortUrl(subscription.baseUrl, subscription.topic);
|
2022-02-27 04:14:43 +13:00
|
|
|
const message = formatMessage(notification);
|
2022-03-05 06:10:11 +13:00
|
|
|
const title = formatTitleWithDefault(notification, shortUrl);
|
2022-03-03 10:16:30 +13:00
|
|
|
|
2022-03-06 18:02:27 +13:00
|
|
|
// Show notification
|
|
|
|
console.log(`[Notifier, ${shortUrl}] Displaying notification ${notification.id}: ${message}`);
|
2022-02-27 04:14:43 +13:00
|
|
|
const n = new Notification(title, {
|
|
|
|
body: message,
|
2022-03-10 09:58:21 +13:00
|
|
|
icon: logo
|
2022-02-27 04:14:43 +13:00
|
|
|
});
|
|
|
|
if (notification.click) {
|
2022-03-05 05:08:32 +13:00
|
|
|
n.onclick = (e) => openUrl(notification.click);
|
2022-02-27 04:14:43 +13:00
|
|
|
} else {
|
2022-03-09 10:56:41 +13:00
|
|
|
n.onclick = () => onClickFallback(subscription);
|
2022-02-27 04:14:43 +13:00
|
|
|
}
|
2022-03-06 18:02:27 +13:00
|
|
|
|
|
|
|
// Play sound
|
|
|
|
const sound = await prefs.sound();
|
|
|
|
if (sound && sound !== "none") {
|
|
|
|
try {
|
|
|
|
await playSound(sound);
|
|
|
|
} catch (e) {
|
|
|
|
console.log(`[Notifier, ${shortUrl}] Error playing audio`, e);
|
|
|
|
}
|
|
|
|
}
|
2022-02-27 04:14:43 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
granted() {
|
2022-03-11 12:11:12 +13:00
|
|
|
return this.supported() && Notification.permission === 'granted';
|
2022-02-27 04:14:43 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
maybeRequestPermission(cb) {
|
2022-03-11 12:11:12 +13:00
|
|
|
if (!this.supported()) {
|
|
|
|
cb(false);
|
|
|
|
return;
|
|
|
|
}
|
2022-02-27 04:14:43 +13:00
|
|
|
if (!this.granted()) {
|
|
|
|
Notification.requestPermission().then((permission) => {
|
|
|
|
const granted = permission === 'granted';
|
|
|
|
cb(granted);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
2022-03-02 10:22:47 +13:00
|
|
|
|
2022-03-02 16:41:49 +13:00
|
|
|
async shouldNotify(subscription, notification) {
|
2022-03-09 10:56:41 +13:00
|
|
|
if (subscription.mutedUntil === 1) {
|
|
|
|
return false;
|
|
|
|
}
|
2022-03-02 10:22:47 +13:00
|
|
|
const priority = (notification.priority) ? notification.priority : 3;
|
2022-03-03 10:16:30 +13:00
|
|
|
const minPriority = await prefs.minPriority();
|
2022-03-02 16:41:49 +13:00
|
|
|
if (priority < minPriority) {
|
2022-03-02 10:22:47 +13:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2022-03-11 12:11:12 +13:00
|
|
|
|
|
|
|
supported() {
|
2022-06-13 08:38:33 +12:00
|
|
|
return this.browserSupported() && this.contextSupported();
|
|
|
|
}
|
|
|
|
|
|
|
|
browserSupported() {
|
2022-03-11 12:11:12 +13:00
|
|
|
return 'Notification' in window;
|
|
|
|
}
|
2022-06-13 08:38:33 +12:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns true if this is a HTTPS site, or served over localhost. Otherwise the Notification API
|
|
|
|
* is not supported, see https://developer.mozilla.org/en-US/docs/Web/API/notification
|
|
|
|
*/
|
|
|
|
contextSupported() {
|
|
|
|
return location.protocol === 'https:'
|
|
|
|
|| location.hostname.match('^127.')
|
|
|
|
|| location.hostname === 'localhost';
|
|
|
|
}
|
2022-02-27 04:14:43 +13:00
|
|
|
}
|
|
|
|
|
2022-03-06 18:02:27 +13:00
|
|
|
const notifier = new Notifier();
|
|
|
|
export default notifier;
|