diff options
| author | Adam Soltys <[email protected]> | 2026-09-20 23:33:07 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-09-20 23:33:07 -0700 |
| commit | ff411c6e1eb708e434899f66d66bf242fb576336 (patch) | |
| tree | 29984463950cf628c3c3cee0ce5f5d5158eb9fed /src/app.js | |
| parent | d80d7a5284eea39a80a738302b8202861a4f172d (diff) | |
| download | coinosv3-ff411c6e1eb708e434899f66d66bf242fb576336.tar.gz coinosv3-ff411c6e1eb708e434899f66d66bf242fb576336.zip | |
Settings → Nostr: make coinos the browser's handler for web+nostr: and bitcoin: links.
njump's "Your default web app" is a web+nostr: link: it opens whichever
site registered that scheme. A card offers to register this app (the
browser asks), and ?u= now accepts the web+nostr: form.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Diffstat (limited to 'src/app.js')
| -rw-r--r-- | src/app.js | 26 |
1 files changed, 24 insertions, 2 deletions
@@ -2548,11 +2548,31 @@ function settingsTab() { } // Everything nostr — identity, sync, wallet connect — on its own page. +// Ask the browser to send a URL scheme's links to this app (the ?u= path +// the Android intents already use). Chrome shows its own permission bar; +// a scheme it won't register throws and we say so. +function registerLinkHandler(scheme) { + try { + navigator.registerProtocolHandler(scheme, location.origin + '/?u=%s'); + toast(t('linkHandlerAsked')); + } catch (e) { toast(t('linkHandlerRefused')); } +} function nostrSettingsView() { return h( 'div', { class: 'col', style: 'gap:16px' }, ...featureAll('nostrSettingsCards'), + // The browser's own "open these links here" registry: njump's "Your + // default web app" is a web+nostr: link, and it opens whichever site + // asked for that scheme last. Needs a tap (the browser asks). + typeof navigator !== 'undefined' && navigator.registerProtocolHandler + ? h('div', { class: 'card col', style: 'gap:8px' }, + h('h3', {}, t('linkHandlerTitle')), + h('p', { class: 'small muted', style: 'margin:0' }, t('linkHandlerDesc')), + h('div', { class: 'row gap6', style: 'flex-wrap:wrap' }, + h('button', { class: 'btn-sm', onClick: () => registerLinkHandler('web+nostr') }, t('linkHandlerNostr')), + h('button', { class: 'btn-sm', onClick: () => registerLinkHandler('bitcoin') }, t('linkHandlerBitcoin')))) + : null, h('button', { class: 'btn-ghost btn-block', onClick: () => { ui.settingsPage = null; render(); } }, t('back')) ); } @@ -5472,9 +5492,11 @@ const INTENT_URI = (() => { const u = new URLSearchParams(location.search).get('u'); if (!u) return null; history.replaceState(null, '', location.pathname || '/'); - const m = u.match(/^nostr:((npub|nprofile|note|nevent)1[a-z0-9]+)\/?$/i); + // web+nostr: is what a browser hands a registered protocol handler + // (njump's "Your default web app"); nostr: is the Android intent + const m = u.match(/^(?:web\+)?nostr:((npub|nprofile|note|nevent)1[a-z0-9]+)\/?$/i); if (m) { history.replaceState(null, '', '/' + m[1]); return null; } - return u; + return u.replace(/^web\+/i, ''); } catch { return null; } })(); const FEATURES = buildFeatures(ctx); |
