aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-08-04 00:36:08 -0700
committerAdam Soltys <[email protected]>2026-08-04 00:36:08 -0700
commitdece938e6e4dc1e1ee8afc76be1c3e91282100bf (patch)
treec679d9f5ab38b40caf660d3a842834a17be32fb0
parentefad28e5bc27a40435601fd6aee9ad0a797d3c9e (diff)
downloadcoinosv3-dece938e6e4dc1e1ee8afc76be1c3e91282100bf.tar.gz
coinosv3-dece938e6e4dc1e1ee8afc76be1c3e91282100bf.zip
Keep the punks carousel where you left it, and on the page
A background repaint rebuilt the strip at scrollLeft 0 mid-swipe; render() now carries scroll positions across the swap the same way it carries focus. The onboarding column also sized itself to the strip's intrinsic width (auto margins defeat flex stretch), overflowing phones below ~450px. Co-Authored-By: Claude Fable 5 <[email protected]>
-rw-r--r--src/app.js13
-rw-r--r--src/style.css6
2 files changed, 17 insertions, 2 deletions
diff --git a/src/app.js b/src/app.js
index eef7ea6..7b7fb9a 100644
--- a/src/app.js
+++ b/src/app.js
@@ -338,6 +338,13 @@ function render() {
fpath = focusPath(a);
try { selStart = a.selectionStart; selEnd = a.selectionEnd; } catch {}
}
+ // Same idea for scrollable strips (the punks carousel): a rebuild must not
+ // yank a half-scrolled list back to its start. Anything marked with
+ // data-keep-scroll gets its position carried across the swap.
+ const scrolls = {};
+ for (const el of root.querySelectorAll('[data-keep-scroll]'))
+ if (el.scrollLeft || el.scrollTop)
+ scrolls[el.getAttribute('data-keep-scroll')] = { l: el.scrollLeft, t: el.scrollTop };
const screen =
featureHook('screenView')
|| (ui.screen === 'wallet'
@@ -364,6 +371,10 @@ function render() {
try { el.focus({ preventScroll: true }); if (selStart != null && el.setSelectionRange) el.setSelectionRange(selStart, selEnd); } catch {}
}
}
+ for (const el of root.querySelectorAll('[data-keep-scroll]')) {
+ const s = scrolls[el.getAttribute('data-keep-scroll')];
+ if (s) { el.scrollLeft = s.l; el.scrollTop = s.t; }
+ }
// Fast-poll the receive address only while the user is actually watching for a
// payment (wallet screen, Receive tab, online). Idempotent — safe each render.
wallet.setWatchReceive(ui.screen === 'wallet' && ui.tab === 'receive' && !wallet.offline);
@@ -2245,7 +2256,7 @@ function onboardScreen() {
return page([
title(t('onbAvatarTitle')),
h('p', { class: 'muted', style: 'margin:0' }, t('onbAvatarBody')),
- h('div', { class: 'onb-punks' },
+ h('div', { class: 'onb-punks', 'data-keep-scroll': 'punks' },
...PUNK_PICKS.map((n) =>
h('img', {
class: 'onb-punk' + (sel === punkImg(n) ? ' sel' : ''),
diff --git a/src/style.css b/src/style.css
index 975f490..2b9c969 100644
--- a/src/style.css
+++ b/src/style.css
@@ -513,7 +513,11 @@ body::after {
.anim-tab-right { animation: tab-in-right .26s cubic-bezier(.25, .8, .35, 1) both; }
/* ---- onboarding wizard + tour ---- */
-.onb { max-width: 420px; margin: 8vh auto 0; padding: 0 8px; }
+/* width:100%, not just max-width: with auto margins the flex item doesn't
+ stretch, and the punks strip's intrinsic width (12 avatars, ~780px — a
+ scroll container still reports its full content width) would size the
+ column to the 420px cap even on narrower phones, overflowing the page. */
+.onb { width: 100%; max-width: 420px; margin: 8vh auto 0; padding: 0 8px; }
.onb-title { margin: 0; font-size: 26px; letter-spacing: -0.02em; }
.onb-hero { margin-bottom: 8px; }
.onb-punks { display: flex; gap: 10px; overflow-x: auto; padding: 6px 2px; }