aboutsummaryrefslogtreecommitdiffstats
path: root/src/features
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-08-13 23:22:17 -0700
committerAdam Soltys <[email protected]>2026-08-13 23:22:17 -0700
commit3104c93cece2104457d672aef59da2327659de4b (patch)
treef2687aa8366654034bcd72fd9b9ced78b2a1c401 /src/features
parentb3b820b6cbfc5a280fb795d59315480eae53b0ce (diff)
downloadcoinosv3-3104c93cece2104457d672aef59da2327659de4b.tar.gz
coinosv3-3104c93cece2104457d672aef59da2327659de4b.zip
Answering while closed becomes the default: a new connection asks once, and anywhere permission is already granted it arms itself — only an explicit Off is honored forever
Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_014tE4U5nEjGTQy8PwYqamfv
Diffstat (limited to 'src/features')
-rw-r--r--src/features/nwc.js39
1 files changed, 36 insertions, 3 deletions
diff --git a/src/features/nwc.js b/src/features/nwc.js
index 2d9d633..730299e 100644
--- a/src/features/nwc.js
+++ b/src/features/nwc.js
@@ -124,6 +124,9 @@ export function nwcFeature(ctx) {
publishInfo(c).catch(() => {});
listen();
refreshRegistration(); // the notifier must learn the new service pubkey
+ // Arm background answering off the same click — creating a connection is
+ // the one moment a permission prompt is both allowed and expected.
+ ensureBackground(true);
return c;
}
@@ -578,6 +581,27 @@ export function nwcFeature(ctx) {
return true;
}
+ // Background answering should be the norm, not a setting the user has to
+ // find: try to arm it whenever a connection exists. `interactive` marks a
+ // call made from a user gesture (creating a connection), where the browser
+ // allows the permission prompt; elsewhere we only proceed when permission
+ // was already granted, so the user is never nagged. An explicit Off on the
+ // toggle (backgroundOff) is final — auto-arming never overrides it.
+ async function ensureBackground(interactive) {
+ const st = load();
+ if (st.background || st.backgroundOff) return;
+ if (typeof navigator === 'undefined' || !('serviceWorker' in navigator)
+ || typeof window === 'undefined' || !('PushManager' in window)
+ || typeof Notification === 'undefined') return;
+ if (!conns().length) return;
+ if (!interactive && Notification.permission !== 'granted') return;
+ try {
+ await enableBackground();
+ await reconcileBg();
+ render();
+ } catch (e) { console.log('nwc: background answering not armed:', e.message); }
+ }
+
// Keep the notifier's view of our service pubkeys current. It can only
// wake this device for connections it was told about, and a registration
// made before a connection existed (or after one was revoked) watches the
@@ -730,8 +754,17 @@ export function nwcFeature(ctx) {
h('span', { class: 'small' }, t('nwcBackground')),
h('button', { class: 'btn-sm', onClick: async () => {
try {
- if (load().background) { await disableBackground(); toast(t('nwcBackgroundOff')); }
- else { await enableBackground(); await reconcileBg(); toast(t('nwcBackgroundOn')); }
+ if (load().background) {
+ await disableBackground();
+ // an explicit Off is a decision — auto-arming must not undo it
+ const s = load(); s.backgroundOff = true; save(s);
+ toast(t('nwcBackgroundOff'));
+ } else {
+ await enableBackground();
+ const s = load(); delete s.backgroundOff; save(s);
+ await reconcileBg();
+ toast(t('nwcBackgroundOn'));
+ }
} catch (e) { toast(e.message); }
render();
} }, load().background ? t('nwcOn') : t('nwcOff')))
@@ -764,7 +797,7 @@ export function nwcFeature(ctx) {
id: 'nwc',
nwcOfferPubkey() { return (hook('arkReady') && !wallet.watchOnly) ? offerKeys().pk : null; },
nwcOfferString() { return hook('arkReady') && !wallet.watchOnly ? offerString() : null; },
- init() { listen(); startWatchdog(); refreshRegistration(); reconcileBg(); },
+ init() { listen(); startWatchdog(); refreshRegistration(); reconcileBg(); ensureBackground(false); },
stop() { stop(); if (watchdog) { clearInterval(watchdog); watchdog = null; } },
nostrSettingsCards() { return [nwcCard()]; },
};