aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-10-23 08:12:40 -0700
committerAdam Soltys <[email protected]>2026-10-23 08:12:40 -0700
commit91dbee408ad59ef4eb85dbec3eff4d512c9b4792 (patch)
treec5337468eff5661658787032db57e89d95f6ac4f /src
parent6c3b49a559c90954bf5ae6dbfada73ec5b3409cc (diff)
downloadcoinosv3-91dbee408ad59ef4eb85dbec3eff4d512c9b4792.tar.gz
coinosv3-91dbee408ad59ef4eb85dbec3eff4d512c9b4792.zip
Push handler: a notification the platform refuses is retried plain and never counts as shown
PullCap's iPhone paid four times overnight with the "payments sent" notifications on and never showed a "Payment sent" line. The worker hands the handler the heads-up (covered by a test now); the handler flagged the push as answered BEFORE calling showNotification, so a refusal left the push with no line at all — on iOS a silent push, a strike towards losing the subscription. Now the flag follows success, a refused notification is retried with the plainest options, and the stand-in covers the rest. iOS never replaces by tag, so renotify is left out there. Co-Authored-By: Claude Fable 5.1 <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/sw-nwc.js19
1 files changed, 15 insertions, 4 deletions
diff --git a/src/sw-nwc.js b/src/sw-nwc.js
index dbd2d98..211c4f9 100644
--- a/src/sw-nwc.js
+++ b/src/sw-nwc.js
@@ -29,7 +29,7 @@ async function applePush() {
} catch (_) { return false; }
}
async function standIn(visible) {
- if (!(await applePush())) return;
+ if (!(await applePush())) return false;
await self.registration.showNotification('Coinos', {
body: 'Your wallet checked in.', icon: 'icon-192.png', badge: 'badge-96.png',
tag: 'coinos-bg', renotify: false, silent: true, data: { url: './' },
@@ -38,6 +38,7 @@ async function standIn(visible) {
const open = await self.registration.getNotifications({ tag: 'coinos-bg' }).catch(() => []);
for (const n of open) n.close();
}
+ return true;
}
self.addEventListener('push', (e) => {
@@ -45,7 +46,17 @@ self.addEventListener('push', (e) => {
try { data = e.data ? e.data.json() : {}; } catch (_) {}
// every path below ends in a notification or, failing that, the stand-in
let showed = false;
- const show = (title, opts) => { showed = true; return self.registration.showNotification(title, opts); };
+ // A notification the platform refuses must not count as shown: the old
+ // code flagged it before the call, so a refusal left the push with no line
+ // at all — a silent push, on iOS a strike towards losing the subscription.
+ // (PullCap's night of 2026-10-22: paid four times, no "Payment sent" seen.)
+ // Try the full options; refused, try again with the plainest ones.
+ const show = async (title, opts) => {
+ try { await self.registration.showNotification(title, opts); showed = true; return; }
+ catch (e) { console.warn('[sw] notification refused:', e && e.message); }
+ try { await self.registration.showNotification(title, { body: opts && opts.body, tag: opts && opts.tag, data: opts && opts.data }); showed = true; }
+ catch (e) { console.warn('[sw] plain notification refused too:', e && e.message); }
+ };
// the stand-in, as soon as a path knows it has nothing to say (a long tail
// of work after it mustn't keep the push waiting for its notification)
const quiet = async () => {
@@ -165,7 +176,7 @@ self.addEventListener('push', (e) => {
const open = await self.registration.getNotifications({ tag: 'coinos-bg' }).catch(() => []);
for (const n of open) n.close();
};
- if (apple) { showed = true; await standIn(false).catch(() => {}); }
+ if (apple && await standIn(false).catch(() => false)) showed = true;
// An open window handles requests itself with full wallet state — nudge
// it and stay out of the way. On iOS only one on screen counts: a
// backgrounded app is suspended, so a nudge to it went unanswered.
@@ -197,7 +208,7 @@ self.addEventListener('push', (e) => {
await show(handled.notify.title, {
body: handled.notify.body,
icon: 'icon-192.png', badge: 'badge-96.png',
- tag: handled.notify.tag || 'nwc-incoming', renotify: true,
+ tag: handled.notify.tag || 'nwc-incoming', renotify: !apple,
data: { url: './' },
});
if (apple) await dropStandIn();