aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/app.js1
-rw-r--r--src/features/messages.js39
-rw-r--r--src/i18n.js1
-rw-r--r--src/style.css7
4 files changed, 35 insertions, 13 deletions
diff --git a/src/app.js b/src/app.js
index 0e36cba..d4d13b8 100644
--- a/src/app.js
+++ b/src/app.js
@@ -2169,6 +2169,7 @@ function goHome() {
ui.zapSetup = null;
ui.arkExitPage = null;
ui.settingsPage = null;
+ ui.logoutConfirm = null;
ui.addrScan = false;
ui.arkMoveOpen = false;
ui.nameEditOpen = null;
diff --git a/src/features/messages.js b/src/features/messages.js
index f7fc30a..1fc2ad2 100644
--- a/src/features/messages.js
+++ b/src/features/messages.js
@@ -1131,7 +1131,7 @@ export function messagesFeature(ctx) {
function openProfile(pk) {
ui.profilePk = pk;
- ui.profEdit = null; ui.profEditFilled = false;
+ ui.profEdit = null; ui.profEditFilled = false; ui.logoutConfirm = null;
render();
fetchFullProfile(pk);
notesFor(pk);
@@ -1483,17 +1483,30 @@ export function messagesFeature(ctx) {
const mine = isMe(pk) || (ctx.shownPubkey && pk === ctx.shownPubkey());
const logoutBtn = () => h('button', {
class: 'btn-block', style: 'color:var(--red,#c0392b);display:flex;align-items:center;justify-content:center;gap:8px',
- onClick: () => { ui.profilePk = null; ui.profEdit = null; ui.profEditFilled = false; ctx.logout && ctx.logout(); },
+ onClick: () => { ui.logoutConfirm = true; render(); },
},
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;
+ // One Log out button; the popup offers the two exits — leave (wallets
+ // stay saved, one unlock away) or leave and take everything with you.
+ // The full wipe still routes through the Delete-all warning after this.
+ const logoutPop = () => !ui.logoutConfirm ? null : h('div', {
+ class: 'confirm-pop-backdrop',
+ onClick: (e) => { if (e.target === e.currentTarget) { ui.logoutConfirm = null; render(); } },
+ },
+ h('div', { class: 'card col confirm-pop', style: 'gap:10px' },
+ h('h3', { style: 'margin:0' }, t('logout') + '?'),
+ h('p', { class: 'small muted', style: 'margin:0' }, t('logoutPopBlurb')),
+ h('button', { class: 'btn-primary btn-block', onClick: () => {
+ ui.logoutConfirm = null;
+ ui.profilePk = null; ui.profEdit = null; ui.profEditFilled = false;
+ ctx.logout && ctx.logout();
+ } }, t('logout')),
+ ctx.logoutForget ? h('button', {
+ class: 'btn-block small', style: 'color:var(--red,#c0392b)',
+ onClick: () => { ui.logoutConfirm = null; ctx.logoutForget(); },
+ }, t('logoutForget')) : null,
+ h('button', { class: 'btn-ghost btn-block', onClick: () => { ui.logoutConfirm = null; render(); } }, t('back'))));
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
@@ -1576,10 +1589,9 @@ 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(),
- forgetBtn())
+ logoutBtn())
: mine
- ? h('div', { class: 'col', style: 'gap:8px' }, logoutBtn(), forgetBtn()) // the editor renders above once the kind 0 loads
+ ? logoutBtn() // 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;
@@ -1615,7 +1627,8 @@ export function messagesFeature(ctx) {
noteRow(pk, ev, name),
])));
})(),
- h('button', { class: 'btn-ghost btn-block', onClick: () => { ui.profilePk = null; ui.profEdit = null; ui.profEditFilled = false; render(); } }, t('back')));
+ h('button', { class: 'btn-ghost btn-block', onClick: () => { ui.profilePk = null; ui.profEdit = null; ui.profEditFilled = false; render(); } }, t('back')),
+ mine ? logoutPop() : null);
}
const backBtn = (onClick) => h('button', { class: 'iconbtn chat-back', onClick }, '‹');
diff --git a/src/i18n.js b/src/i18n.js
index 1dabde4..d9dcdfb 100644
--- a/src/i18n.js
+++ b/src/i18n.js
@@ -40,6 +40,7 @@ const STR = {
addWallet: 'Add wallet',
clearAll: 'Delete all',
logoutForget: 'Log out & forget this device',
+ logoutPopBlurb: 'Your wallets stay saved on this device, one unlock away.',
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.',
diff --git a/src/style.css b/src/style.css
index b5d0576..2433d82 100644
--- a/src/style.css
+++ b/src/style.css
@@ -494,6 +494,13 @@ hr.divider { margin: 16px 0; }
.hat-btn.wearing { background: var(--accent); border-color: var(--accent); color: var(--accent-fg); }
.hat-btn.confirm { border-color: var(--green); color: var(--green); }
+/* a small centered confirm popup over a dimmed page */
+.confirm-pop-backdrop {
+ position: fixed; inset: 0; z-index: 50; background: rgba(0, 0, 0, .45);
+ display: flex; align-items: center; justify-content: center; padding: 24px;
+}
+.confirm-pop { width: 100%; max-width: 340px; }
+
/* staging builds: an unmissable stamp across the header logo */
.brand.staging { position: relative; }
.staging-badge {