aboutsummaryrefslogtreecommitdiffstats
path: root/src/app.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/app.js')
-rw-r--r--src/app.js40
1 files changed, 37 insertions, 3 deletions
diff --git a/src/app.js b/src/app.js
index 8af6f75..3cdb59e 100644
--- a/src/app.js
+++ b/src/app.js
@@ -600,7 +600,7 @@ function imageViewer() {
// mounted viewer: morphing can replace handlers with a new render's ones.
document.querySelector('.lightbox')?.remove();
document.documentElement.classList.remove('no-scroll');
- goBack(() => { ui.lightbox = null; });
+ closeLayer('lightbox');
};
// A tap on the picture closes it at every zoom level; gestures are filtered
// by attachZoom before this click handler runs.
@@ -702,7 +702,7 @@ function attachZoom(box, img, { wheel = true } = {}) {
}, { passive: false });
}
if (typeof window !== 'undefined') {
- window.addEventListener('keydown', (e) => { if (e.key === 'Escape' && ui.lightbox) goBack(() => { ui.lightbox = null; }); });
+ window.addEventListener('keydown', (e) => { if (e.key === 'Escape' && ui.lightbox) closeLayer('lightbox'); });
// Enter walks the Send flow: from an amount (or any field) it presses the
// screen's main button — Review, Pay, Send — and with nothing focused it
// presses it again, so amount ⏎ reviews and ⏎ again confirms. A held key
@@ -1031,11 +1031,23 @@ window.addEventListener('popstate', (e) => {
snap.screen = 'wallet'; snap.tab = ui.tab ?? null;
try { history.replaceState({ nav: snap, i: st && typeof st.i === 'number' ? st.i : navIndex }, ''); } catch {}
}
+ let corrected = false;
+ if (layerClose) {
+ const want = layerClose.expect;
+ clearTimeout(layerClose.timer);
+ layerClose = null;
+ if (navSig(snap) !== navSig(want)) {
+ snap = want;
+ corrected = true;
+ try { history.replaceState({ nav: snap, i: st && typeof st.i === 'number' ? st.i : navIndex }, '', navUrl(snap)); } catch {}
+ }
+ }
restoringHistory = true;
try {
for (const f of NAV_FIELDS) ui[f] = (f === 'profEdit' || f === 'feedEdit') && snap[f] ? structuredClone(snap[f]) : f in snap ? snap[f] : null;
if (st && typeof st.i === 'number') navIndex = st.i;
else { const i = navStack.findIndex((s) => navSig(s) === navSig(snap)); if (i >= 0) navIndex = i; }
+ if (corrected && navIndex >= 0) navStack[navIndex] = snap;
render();
} finally {
restoringHistory = false;
@@ -1050,6 +1062,28 @@ function goBack(toParent) {
if (navIndex > 0) history.back();
else { toParent(); render(); }
}
+// Close something laid over the page (the media pager, the lightbox): Back,
+// so the browser's Back doesn't reopen it — but landing on the page that
+// was under it, whatever the entry Back reaches says. The entry under isn't
+// always that page (after the app was reloaded in the background the
+// browser's older entries are still there, or entries merged at boot), and
+// blind Back walked off to the wallet, the chat list. That entry becomes the
+// page under the layer. No Back to take (nothing of ours under it): shut in place.
+let layerClose = null; // { expect: the snapshot to land on, timer }
+function closeLayer(field) {
+ const cur = navStack[navIndex] || navSnapshot();
+ const expect = { ...navSnapshot(), [field]: null };
+ if (navIndex > 0 && cur) {
+ clearTimeout(layerClose && layerClose.timer);
+ // (the layer stays up until Back lands, as before; no popstate in time:
+ // a Back that went nowhere — shut where we are)
+ layerClose = { expect, timer: setTimeout(() => { if (layerClose && layerClose.expect === expect) { layerClose = null; ui[field] = null; render(); } }, 600) };
+ history.back();
+ return;
+ }
+ ui[field] = null;
+ render();
+}
// Whether an in-app Back has anywhere of ours to go. A page opened straight
// from a link has nothing under it; its Back would invent a parent.
const canGoBack = () => navIndex > 0;
@@ -6236,7 +6270,7 @@ async function importSnapshotFile(e) {
// sits just before boot so every helper it captures is defined; the hooks are
// only invoked at runtime (first render happens after loadLocale below).
const ctx = {
- h, ui, render, wallet, toast, copy, copyBtn, pasteBtn, blankSend, goBack, canGoBack, goHome, openExternal, showSend,
+ h, ui, render, wallet, toast, copy, copyBtn, pasteBtn, blankSend, goBack, canGoBack, closeLayer, goHome, openExternal, showSend,
openWalletSettings: (view) => openWalletSettings(view),
// one page of the Settings hub, from anywhere (Notifications' gear)
openSettingsPage: (page) => { clearFeatureNav(); ui.screen = 'wallet'; ui.tab = 'settings'; ui.settingsPage = page; render(); try { window.scrollTo(0, 0); } catch {} },