aboutsummaryrefslogtreecommitdiffstats
path: root/src/app.js
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-11-15 14:13:08 -0700
committerAdam Soltys <[email protected]>2026-11-15 14:13:08 -0700
commitf7fe37ef75836715580e3097c7e7bc75df819bef (patch)
treed43f38574e54da723d1224ea01a479e92abf8680 /src/app.js
parent5c94e68ba962bab6b219b71985d49247a1e0ac48 (diff)
downloadcoinosv3-f7fe37ef75836715580e3097c7e7bc75df819bef.tar.gz
coinosv3-f7fe37ef75836715580e3097c7e7bc75df819bef.zip
Ways back in: Passkey auth, Google auth, Nostr auth, Pen and paper. "Let's call recovery phrase 'Pen and paper' with a suitable icon and no need to show it twice just make it similar to the other buttons. Instead of saying Add... for everything let's try 'Passkey auth', Google auth, Nostr auth" (Adam, 2026-11-15). The card's buttons drop Add…; the recovery phrase is the fourth button (a pen over a sheet, ✓ once the words have been seen) instead of a row with Show, and the separate Recovery phrase card under it appears only when Pen and paper asks for it (scrolled to, words masked first). Accounts without the card (watch-only, imported keys) keep the phrase card as before. signup-quick-test, onboard-backup, balance-settings-row and features-smoke pass
Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01VMan6SwkivduFDDkMmnXjZ
Diffstat (limited to 'src/app.js')
-rw-r--r--src/app.js14
1 files changed, 10 insertions, 4 deletions
diff --git a/src/app.js b/src/app.js
index cead211..f3c2dcb 100644
--- a/src/app.js
+++ b/src/app.js
@@ -3247,7 +3247,10 @@ function settingsTab() {
// matters if the phone is lost tonight
case 'wallet':
if (ui.delAcct && a) return deleteAccountView(a);
- return page(a ? [featureHook('waysBackCard'), recoveryCard(a), balanceSettingsCard(a), walletNameCard(a), pubkeyCard(a), historyExportCard(), deleteAccountCard(a)] : []);
+ // the phrase is one of the ways back in: its card shows only once
+ // Pen and paper asks for it (accounts without the card keep it always)
+ { const ways = a ? featureHook('waysBackCard') : null;
+ return page(a ? [ways, ways && !ui.revealShown ? null : recoveryCard(a), balanceSettingsCard(a), walletNameCard(a), pubkeyCard(a), historyExportCard(), deleteAccountCard(a)] : []); }
case 'payments': return page(featureAll('settingsCards').reverse());
case 'pos': return page(featureAll('posSettingsCards').reverse()); // the till's own card first, then the terminal's
case 'network': return page([networkCard(), explorerCard()]); // an old bookmark of the tile; the cards live under Advanced now
@@ -3907,12 +3910,12 @@ function recoveryCard(a) {
// a warning) before anything readable is over your shoulder. The second
// actually shows them.
if (!shown)
- return h('div', { class: 'card col' },
+ return h('div', { class: 'card col recovery-card' },
h('h3', {}, t('recoveryPhrase')),
h('p', { class: 'small muted', style: 'margin:0' }, t('recoveryDesc')),
h('button', { class: 'btn-block', onClick: () => { ui.revealShown = 'masked'; render(); } }, t('revealRecovery')));
const unmasked = shown === 'words';
- return h('div', { class: 'card col' },
+ return h('div', { class: 'card col recovery-card' },
h('h3', {}, t('recoveryPhrase')),
h('div', { class: 'warn-box' }, t('recoveryWarn')),
h('div', { class: 'words', style: '--rows-3:' + Math.ceil(words.length / 3) + ';--rows-2:' + Math.ceil(words.length / 2) }, words.map((w, i) =>
@@ -7021,7 +7024,10 @@ const ctx = {
recoveryMethods: () => recoveryMethods(), addRecoveryMethod,
spendingOnlyAccount: () => { const a = activeAccount(); return !!(a && a.kind === 'spending' && a.savingsLater); },
seedSeen: () => !!(activeAccount() || {}).seedSeen,
- showRecoveryPhrase: () => { ui.tab = 'settings'; ui.settingsPage = 'wallet'; ui.revealShown = 'masked'; render(); },
+ showRecoveryPhrase: () => {
+ ui.tab = 'settings'; ui.settingsPage = 'wallet'; ui.revealShown = ui.revealShown || 'masked'; render();
+ requestAnimationFrame(() => { try { document.querySelector('.recovery-card')?.scrollIntoView({ behavior: 'smooth', block: 'start' }); } catch {} });
+ },
// Open (or create) a wallet from a mnemonic — used by nostr login.
openMnemonic: async (mnemonic, passphrase, opts) => enterWallet(mnemonic, passphrase, opts),
// Profile pictures retain the metadata-scrubbing image uploader. Public