aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-08-17 07:03:28 -0700
committerAdam Soltys <[email protected]>2026-08-17 07:03:28 -0700
commit49ae68290099bc37bbbf6d7ad4dee9f906623a38 (patch)
tree01a84328f75caeaa5cd1801e4f49bb7839d1d0f9 /src
parentede4516e2255bb65d22dd1a74d0e8332b0417194 (diff)
downloadcoinosv3-49ae68290099bc37bbbf6d7ad4dee9f906623a38.tar.gz
coinosv3-49ae68290099bc37bbbf6d7ad4dee9f906623a38.zip
The profile grows a second, honest exit: Log out leaves the room, Log out & forget this device burns it down — behind the Delete-all warning, which now also sweeps the cached balances and history it always implied
Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01JtaatFfAbx91Nh3xqKVqKz
Diffstat (limited to 'src')
-rw-r--r--src/app.js12
-rw-r--r--src/features/messages.js12
-rw-r--r--src/i18n.js1
3 files changed, 23 insertions, 2 deletions
diff --git a/src/app.js b/src/app.js
index 3a9a8d2..0e36cba 100644
--- a/src/app.js
+++ b/src/app.js
@@ -2497,6 +2497,10 @@ function accountSettingsScreen() {
// Wipe every wallet from this device: session accounts, the encrypted vault,
// and saved watch-only accounts. Unbacked-up seeds are unrecoverable after this.
function clearAll() {
+ // Forget means forget: cached balances, history and feature state go with
+ // the seeds (best effort — a still-locked vault's mnemonic-keyed caches
+ // can't be found without its password; the xpub-keyed ones still match).
+ for (const a of [...accounts, ...loadWatchAccounts()]) wipeAccountCache(a);
try { localStorage.removeItem(VAULT_KEY); } catch {}
try { localStorage.removeItem(WATCH_KEY); } catch {}
ui.confirmClear = false;
@@ -4167,6 +4171,14 @@ const ctx = {
// start page (Get started / sign in). Saved wallets stay one Unlock away.
if (!ui.pw) { ui.screen = 'unlock'; ui.unlockTab = 'create'; ui.onb = { step: 'welcome' }; render(); }
},
+ // The drastic exit: leave AND remove everything saved on this device.
+ // Routes through the Delete-all warning — never a single tap.
+ logoutForget: () => {
+ ui.profilePk = null; ui.profEdit = null; ui.profEditFilled = false; ui.chatOpen = false;
+ ui.screen = 'accounts';
+ ui.confirmClear = true;
+ render();
+ },
// the identity the header avatar currently wears (login > seed key >
// remembered) — profile "mine"-ness must match what the user clicked
shownPubkey: () => (featureHook('nostrLoginIdentity') || {}).pubkey
diff --git a/src/features/messages.js b/src/features/messages.js
index db4ad93..f7fc30a 100644
--- a/src/features/messages.js
+++ b/src/features/messages.js
@@ -1487,6 +1487,13 @@ export function messagesFeature(ctx) {
},
h('span', { style: 'display:flex', html: '<svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" y1="12" x2="9" y2="12"/></svg>' }),
t('logout'));
+ // Two clearly-named exits: leave (wallets stay saved, one unlock away),
+ // or leave and take everything with you — the latter behind the
+ // Delete-all warning, never a single tap.
+ const forgetBtn = () => ctx.logoutForget ? h('button', {
+ class: 'btn-ghost btn-block small', style: 'color:var(--muted)',
+ onClick: () => ctx.logoutForget(),
+ }, t('logoutForget')) : null;
const full = fullProfiles.get(pk);
// Your own profile IS the editor — and it renders IMMEDIATELY, seeded
// from the local name/picture cache, so the page never reflows when the
@@ -1569,9 +1576,10 @@ export function messagesFeature(ctx) {
h('button', { class: 'btn-primary btn-block', disabled: ui.profSaving, onClick: saveProfile },
ui.profSaving ? h('span', { class: 'spinner sm' }) : t('save')),
hook('hatShopEntry'),
- logoutBtn())
+ logoutBtn(),
+ forgetBtn())
: mine
- ? logoutBtn() // the editor renders above once the kind 0 loads
+ ? h('div', { class: 'col', style: 'gap:8px' }, logoutBtn(), forgetBtn()) // the editor renders above once the kind 0 loads
: h('div', { class: 'row gap6 wrap' },
h('button', { class: 'btn-primary grow', onClick: () => {
const peer = pk;
diff --git a/src/i18n.js b/src/i18n.js
index e2416af..1dabde4 100644
--- a/src/i18n.js
+++ b/src/i18n.js
@@ -39,6 +39,7 @@ const STR = {
accounts: 'Wallets',
addWallet: 'Add wallet',
clearAll: 'Delete all',
+ logoutForget: 'Log out & forget this device',
clearAllWarn: '⚠ This removes every wallet from this device. Any wallet whose recovery phrase or key you have not backed up will be lost for good.',
removeWalletTitle: 'Remove wallet',
removeWalletWarn: '⚠ Remove “{name}” from this device? It will be gone from this browser — make sure you have its recovery phrase. Other wallets aren’t affected.',