Calendar reminders as push notifications
A job every minute finds the event reminders that fell due — repeating events and moved occurrences expanded as the calendar view does — and pushes each once to every device with notifications on (sdk.push, new: plugins can notify through the new-mail push delivery). A reminder missed while the worker was down is still sent within 10 minutes; cancelled events and declined invitations stay quiet. Title, then "In 15 minutes, 14:00 · Room 2" in the user's zone and clock format; it stays until dismissed and shows even with the app open; clicking it opens that day (/p/calendar?date=…, new deep link). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+13
-6
@@ -501,11 +501,13 @@ self.addEventListener("activate", (event) => {
|
||||
);
|
||||
});
|
||||
|
||||
// ---- notifications about new mail ---------------------------------------------------
|
||||
// ---- notifications: new mail, calendar reminders ------------------------------------
|
||||
//
|
||||
// The server (app/push/service.py) sends { type: "mail", title, body, tag, url,
|
||||
// unread } encrypted to this browser. One notification per conversation (`tag`),
|
||||
// replaced when more arrives in it; the app icon's badge shows unread Inbox mail.
|
||||
// A plugin (sdk.push) sends { type: "plugin.<name>", title, body, tag, url,
|
||||
// sticky } — a calendar reminder.
|
||||
|
||||
/** A window of the app the user is looking at right now. */
|
||||
async function lookingAtApp() {
|
||||
@@ -517,16 +519,21 @@ async function showMail(data) {
|
||||
if (typeof data.unread === "number" && self.navigator.setAppBadge) {
|
||||
await (data.unread ? self.navigator.setAppBadge(data.unread) : self.navigator.clearAppBadge()).catch(() => {});
|
||||
}
|
||||
// The app is open in front of the user: the new mail is already on screen.
|
||||
// Not on Apple's push service, which withdraws permission from a site whose
|
||||
// New mail while the app is open in front of the user: it is already on
|
||||
// screen. (Other notifications — a calendar reminder — show regardless.) Not
|
||||
// on Apple's push service, which withdraws permission from a site whose
|
||||
// pushes show nothing.
|
||||
const sub = await self.registration.pushManager.getSubscription();
|
||||
const apple = Boolean(sub?.endpoint.includes(".push.apple.com"));
|
||||
if (!apple && (await lookingAtApp())) return;
|
||||
if (!data.type || data.type === "mail") {
|
||||
const sub = await self.registration.pushManager.getSubscription();
|
||||
const apple = Boolean(sub?.endpoint.includes(".push.apple.com"));
|
||||
if (!apple && (await lookingAtApp())) return;
|
||||
}
|
||||
await self.registration.showNotification(data.title || "New mail", {
|
||||
body: data.body || "",
|
||||
tag: data.tag || "new-mail",
|
||||
renotify: true,
|
||||
// A reminder stays until dismissed (where the platform allows it).
|
||||
requireInteraction: Boolean(data.sticky),
|
||||
icon: "/icon-192.png",
|
||||
badge: "/badge-96.png",
|
||||
timestamp: Date.now(),
|
||||
|
||||
Reference in New Issue
Block a user