diff options
| author | Adam Soltys <[email protected]> | 2026-08-26 11:13:03 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-08-26 11:13:03 -0700 |
| commit | 6be9a45c4d085988c8bfaf210df762dbc83c8ab1 (patch) | |
| tree | 6d3a48e3b69b0851d127b1ad10ade3d31969c9fe /src | |
| parent | 7a108d1e1ae46bcbaded1d73fe22c551c40a2232 (diff) | |
| download | coinosv3-6be9a45c4d085988c8bfaf210df762dbc83c8ab1.tar.gz coinosv3-6be9a45c4d085988c8bfaf210df762dbc83c8ab1.zip | |
The landing settles as one motion: the resolving shell now holds the frame over every screen — an auto-restored wallet no longer flashes its home page — and the animation clock stands still until the profile has replaced the shell in place, so nothing slides twice
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_019eA8JRq9Wr7z2fRQk99HLi
Diffstat (limited to 'src')
| -rw-r--r-- | src/app.js | 6 | ||||
| -rw-r--r-- | src/features/messages.js | 25 |
2 files changed, 21 insertions, 10 deletions
@@ -474,7 +474,11 @@ function renderInner() { const navKey = [ui.screen, ui.tab === 'settings', ui.chatOpen, ui.msgView, ui.msgPeer, ui.msgCommunity, ui.profilePk, ui.settingsPage, ui.addrScan, ui.arkExitPage, ui.txDetail, ui.giftMode, ui.claimStep, ui.nameEditOpen, ui.noteThread && ui.noteThread.focusId, !!ui.userSearch, !!ui.zapSetup, !!ui.hatShop].join('|'); - if (uiChanged('nav', navKey)) _navAt = performance.now(); + // A deep-linked profile landing is ONE page settling, not a chain of + // navigations: boot screens shuffle beneath the shell (unlock → restored + // wallet), then the resolved profile replaces the shell in place. The key + // still updates, but nothing slides or re-animates until the landing ends. + if (uiChanged('nav', navKey) && !(ui.pubProfPending || ui.pubProfHold)) _navAt = performance.now(); applyAnim(screen, 'anim-page', (performance.now() - _navAt) < 340 ? performance.now() - _navAt : -1); morphChildren(root, [screen, footer()]); if (fpath) { diff --git a/src/features/messages.js b/src/features/messages.js index 94e8909..c4ed990 100644 --- a/src/features/messages.js +++ b/src/features/messages.js @@ -652,11 +652,16 @@ export function messagesFeature(ctx) { if (!profiles.has(pk)) profiles.set(pk, { name, t: 0 }); } } - ui.pubProfPending = null; if (pk && /^[0-9a-f]{64}$/.test(pk)) { + // hold the pinned nav key across this render: the profile replaces + // the shell in place, with no page-slide re-animation + ui.pubProfHold = true; + ui.pubProfPending = null; if (ui.screen === 'wallet') ui.pubProf = null; // wallet chrome owns it openProfile(pk); + ui.pubProfHold = null; } else { + ui.pubProfPending = null; ui.pubProf = null; // unknown name: fall through to the front door render(); } @@ -2384,6 +2389,16 @@ export function messagesFeature(ctx) { unreadMessages() { return unreadCount(); }, notifySettingsCards() { return [notifyCard()]; }, screenView() { + // A profile deep link mid-resolution holds the frame over EVERY screen + // — an auto-restored wallet would otherwise flash its home page for the + // beat the registrar lookup takes. The shell shows the name straight + // off the URL; no spinner, the empty beat reads calmer. + if (ui.pubProfPending) return h('div', { class: 'col', style: 'gap:16px' }, + ctx.brandHeader(false), + h('div', { class: 'card col', style: 'gap:12px' }, + h('div', { class: 'row gap6', style: 'align-items:center' }, + h('div', { class: 'chat-avatar profile-avatar fallback loading' }), + h('div', { class: 'chat-title' }, ui.pubProfPending)))); if (ui.screen !== 'wallet') { // The public (no-wallet) surface: a deep-linked profile, and the // threads reachable from it, are public nostr content — shown @@ -2391,14 +2406,6 @@ export function messagesFeature(ctx) { if (ui.pubProf) { if (ui.noteThread) return threadScreen(); if (ui.profilePk) return profileScreen(); - // resolution in flight: the shell holds the layout with the name - // straight off the URL — no spinner, the empty beat reads calmer - if (ui.pubProfPending) return h('div', { class: 'col', style: 'gap:16px' }, - ctx.brandHeader(false), - h('div', { class: 'card col', style: 'gap:12px' }, - h('div', { class: 'row gap6', style: 'align-items:center' }, - h('div', { class: 'chat-avatar profile-avatar fallback loading' }), - h('div', { class: 'chat-title' }, ui.pubProfPending)))); } return null; } |
