mirror of
https://github.com/binwiederhier/ntfy.git
synced 2025-07-20 10:04:08 +00:00
Implement push subscription expiry
This commit is contained in:
parent
47ad024ec7
commit
0f0074cbab
16 changed files with 272 additions and 102 deletions
112
web/public/sw.js
112
web/public/sw.js
|
@ -32,35 +32,50 @@ self.addEventListener("push", (event) => {
|
|||
const data = event.data.json();
|
||||
console.log("[ServiceWorker] Received Web Push Event", { event, data });
|
||||
|
||||
const { subscription_id: subscriptionId, message } = data;
|
||||
broadcastChannel.postMessage(message);
|
||||
|
||||
event.waitUntil(
|
||||
(async () => {
|
||||
const db = await getDbAsync();
|
||||
|
||||
await Promise.all([
|
||||
(async () => {
|
||||
await db.notifications.add({
|
||||
...message,
|
||||
subscriptionId,
|
||||
// New marker (used for bubble indicator); cannot be boolean; Dexie index limitation
|
||||
new: 1,
|
||||
});
|
||||
const badgeCount = await db.notifications.where({ new: 1 }).count();
|
||||
console.log("[ServiceWorker] Setting new app badge count", { badgeCount });
|
||||
self.navigator.setAppBadge?.(badgeCount);
|
||||
})(),
|
||||
db.subscriptions.update(subscriptionId, {
|
||||
last: message.id,
|
||||
}),
|
||||
self.registration.showNotification(formatTitleWithDefault(message, message.topic), {
|
||||
tag: subscriptionId,
|
||||
body: formatMessage(message),
|
||||
if (data.event === "subscription_expiring") {
|
||||
await self.registration.showNotification("Notifications will be paused", {
|
||||
body: "Open ntfy to continue receiving notifications",
|
||||
icon: "/static/images/ntfy.png",
|
||||
data,
|
||||
}),
|
||||
]);
|
||||
});
|
||||
} else if (data.event === "message") {
|
||||
const { subscription_id: subscriptionId, message } = data;
|
||||
broadcastChannel.postMessage(message);
|
||||
|
||||
const db = await getDbAsync();
|
||||
|
||||
await Promise.all([
|
||||
(async () => {
|
||||
await db.notifications.add({
|
||||
...message,
|
||||
subscriptionId,
|
||||
// New marker (used for bubble indicator); cannot be boolean; Dexie index limitation
|
||||
new: 1,
|
||||
});
|
||||
const badgeCount = await db.notifications.where({ new: 1 }).count();
|
||||
console.log("[ServiceWorker] Setting new app badge count", { badgeCount });
|
||||
self.navigator.setAppBadge?.(badgeCount);
|
||||
})(),
|
||||
db.subscriptions.update(subscriptionId, {
|
||||
last: message.id,
|
||||
}),
|
||||
self.registration.showNotification(formatTitleWithDefault(message, message.topic), {
|
||||
tag: subscriptionId,
|
||||
body: formatMessage(message),
|
||||
icon: "/static/images/ntfy.png",
|
||||
data,
|
||||
}),
|
||||
]);
|
||||
} else {
|
||||
// We can't ignore the push, since permission can be revoked by the browser
|
||||
await self.registration.showNotification("Unknown notification received from server", {
|
||||
body: "You may need to update ntfy by opening the web app",
|
||||
icon: "/static/images/ntfy.png",
|
||||
data,
|
||||
});
|
||||
}
|
||||
})()
|
||||
);
|
||||
});
|
||||
|
@ -68,33 +83,38 @@ self.addEventListener("push", (event) => {
|
|||
self.addEventListener("notificationclick", (event) => {
|
||||
event.notification.close();
|
||||
|
||||
const { message } = event.notification.data;
|
||||
|
||||
if (message.click) {
|
||||
self.clients.openWindow(message.click);
|
||||
return;
|
||||
}
|
||||
|
||||
const rootUrl = new URL(self.location.origin);
|
||||
const topicUrl = new URL(message.topic, self.location.origin);
|
||||
|
||||
event.waitUntil(
|
||||
(async () => {
|
||||
const clients = await self.clients.matchAll({ type: "window" });
|
||||
|
||||
const topicClient = clients.find((client) => client.url === topicUrl.toString());
|
||||
if (topicClient) {
|
||||
topicClient.focus();
|
||||
return;
|
||||
}
|
||||
|
||||
const rootUrl = new URL(self.location.origin);
|
||||
const rootClient = clients.find((client) => client.url === rootUrl.toString());
|
||||
if (rootClient) {
|
||||
rootClient.focus();
|
||||
return;
|
||||
}
|
||||
|
||||
self.clients.openWindow(topicUrl);
|
||||
if (event.notification.data.event !== "message") {
|
||||
if (rootClient) {
|
||||
rootClient.focus();
|
||||
} else {
|
||||
self.clients.openWindow(rootUrl);
|
||||
}
|
||||
} else {
|
||||
const { message } = event.notification.data;
|
||||
|
||||
if (message.click) {
|
||||
self.clients.openWindow(message.click);
|
||||
return;
|
||||
}
|
||||
|
||||
const topicUrl = new URL(message.topic, self.location.origin);
|
||||
const topicClient = clients.find((client) => client.url === topicUrl.toString());
|
||||
|
||||
if (topicClient) {
|
||||
topicClient.focus();
|
||||
} else if (rootClient) {
|
||||
rootClient.focus();
|
||||
} else {
|
||||
self.clients.openWindow(topicUrl);
|
||||
}
|
||||
}
|
||||
})()
|
||||
);
|
||||
});
|
||||
|
|
|
@ -42,4 +42,5 @@ class Prefs {
|
|||
}
|
||||
}
|
||||
|
||||
export default new Prefs(getDb());
|
||||
const prefs = new Prefs(getDb());
|
||||
export default prefs;
|
||||
|
|
|
@ -57,7 +57,6 @@ import { IncorrectPasswordError, UnauthorizedError } from "../app/errors";
|
|||
import { ProChip } from "./SubscriptionPopup";
|
||||
import theme from "./theme";
|
||||
import session from "../app/Session";
|
||||
import subscriptionManager from "../app/SubscriptionManager";
|
||||
|
||||
const Account = () => {
|
||||
if (!session.exists()) {
|
||||
|
|
|
@ -58,9 +58,7 @@ const App = () => {
|
|||
const updateTitle = (newNotificationsCount) => {
|
||||
document.title = newNotificationsCount > 0 ? `(${newNotificationsCount}) ntfy` : "ntfy";
|
||||
|
||||
if ("setAppBadge" in window.navigator) {
|
||||
window.navigator.setAppBadge(newNotificationsCount);
|
||||
}
|
||||
window.navigator.setAppBadge?.(newNotificationsCount);
|
||||
};
|
||||
|
||||
const Layout = () => {
|
||||
|
|
|
@ -10,7 +10,6 @@ import session from "../app/Session";
|
|||
import accountApi from "../app/AccountApi";
|
||||
import { UnauthorizedError } from "../app/errors";
|
||||
import { webPushRefreshWorker, useWebPushUpdateWorker } from "../app/WebPushWorker";
|
||||
import notifier from "../app/Notifier";
|
||||
|
||||
/**
|
||||
* Wire connectionManager and subscriptionManager so that subscriptions are updated when the connection
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue