aboutsummaryrefslogtreecommitdiffstats
path: root/src/app.js
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-08-02 23:26:38 -0700
committerAdam Soltys <[email protected]>2026-08-02 23:26:38 -0700
commit02d60eb824cad0b8c09cb5685a6c2dbe02e16c4f (patch)
tree9c3637c21783bf55ce8d3d3aa6de4cd47c6abb59 /src/app.js
parent70b02f00c63ba6f6cae939a5ebdedac6e3552eb6 (diff)
downloadcoinosv3-02d60eb824cad0b8c09cb5685a6c2dbe02e16c4f.tar.gz
coinosv3-02d60eb824cad0b8c09cb5685a6c2dbe02e16c4f.zip
Tab carousel, login avatar fix, signer callback hint
Tab changes no longer flash the whole page: only the content pane below the tab strip slides sideways with a soft cross-fade — swipe direction when a gesture caused it, index order for taps — while the balance card and strip stay planted. Full-page entrances remain for real page changes (settings, chat, profile, takeovers). After a nostr sign-in the header briefly wore the wallet key's face: nostrLoginIdentity now reports a just-connected live signer immediately instead of waiting for the persisted link that only lands after the wallet opens. The nostrconnect URI carries a callbackUrl hint (NIP-55 style) so signer apps that honor it can bounce back to the PWA after approval — apps that don't will still find the session signed in when the user returns, since the handshake completes over the relay in the background. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
Diffstat (limited to 'src/app.js')
-rw-r--r--src/app.js32
1 files changed, 23 insertions, 9 deletions
diff --git a/src/app.js b/src/app.js
index 073b4c4..89b0dc3 100644
--- a/src/app.js
+++ b/src/app.js
@@ -285,8 +285,11 @@ function uiChanged(key, val) {
// the animation started by this change are we?" — callers re-apply the class
// with a negative animation-delay so a rebuild RESUMES the animation.
let _navAt = -1e9;
-let _navCls = 'anim-page';
let _swipeDir = null; // set by the swipe handler just before render
+// tab switches carousel just the content pane, not the whole page
+let _tabAt = -1e9;
+let _tabCls = 'anim-tab-left';
+let _prevTabIdx = 0;
const _animAt = new Map();
function animWindow(key, val, durMs) {
if (uiChanged(key, val)) _animAt.set(key, performance.now());
@@ -348,14 +351,10 @@ function render() {
: unlockScreen());
// Navigation animates; background repaints must not. The key is every
// ui field that decides which page is on screen.
- const navKey = [ui.screen, ui.tab, ui.chatOpen, ui.msgView, ui.msgPeer, ui.msgCommunity,
+ 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].join('|');
- if (uiChanged('nav', navKey)) {
- _navAt = performance.now();
- _navCls = _swipeDir ? 'anim-slide-' + _swipeDir : 'anim-page';
- }
- _swipeDir = null;
- applyAnim(screen, _navCls, (performance.now() - _navAt) < 340 ? performance.now() - _navAt : -1);
+ if (uiChanged('nav', navKey)) _navAt = performance.now();
+ applyAnim(screen, 'anim-page', (performance.now() - _navAt) < 340 ? performance.now() - _navAt : -1);
root.replaceChildren(screen, footer());
if (fpath) {
const el = nodeAtPath(fpath);
@@ -2017,6 +2016,21 @@ function walletScreen() {
h('div', { class: 'mt16' }, tabContent())
);
}
+ // Tab changes slide the content pane sideways like a carousel — swipe
+ // direction when a gesture caused it, index order for taps. The balance
+ // card and tab strip stay planted.
+ const TAB_ORDER = ['receive', 'send', 'history'];
+ if (uiChanged('tabnav', ui.tab)) {
+ const idx = TAB_ORDER.indexOf(ui.tab);
+ _tabCls = 'anim-tab-' + (_swipeDir || (idx >= 0 && idx < _prevTabIdx ? 'right' : 'left'));
+ _tabAt = performance.now();
+ if (idx >= 0) _prevTabIdx = idx;
+ }
+ _swipeDir = null;
+ const pane = h('div', { class: 'tab-pane' }, tabContent());
+ const tabDt = performance.now() - _tabAt;
+ // skip the pane slide while a full-page entrance is already running
+ if (performance.now() - _navAt > 400) applyAnim(pane, _tabCls, tabDt < 300 ? tabDt : -1);
return h(
'div',
{ class: 'col', style: 'gap:0' },
@@ -2024,7 +2038,7 @@ function walletScreen() {
h('div', { class: 'mt16' }, balanceCard()),
ui.offlineFallback && wallet.offline ? offlineBanner() : null,
tabsBar(),
- tabContent()
+ pane
);
}