From c8158d13fcd0278a7525e762fccea2a1329f7768 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Thu, 8 Oct 2026 22:47:06 -0700 Subject: Desktop layout: from 900px the bottom nav is a left rail (your profile first with a bigger face and name, Settings last) beside a 600px page column, and from 1220px the wallet (balance, Receive/Send, latest payments) rides in a right column; search is a full field in the header there. Floaters re-centred on the page column, open chats still fill the window, phones unchanged Co-Authored-By: Claude Opus 5.5 --- src/features/messages.js | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) (limited to 'src/features') diff --git a/src/features/messages.js b/src/features/messages.js index 759b155..b80c87b 100644 --- a/src/features/messages.js +++ b/src/features/messages.js @@ -10130,8 +10130,9 @@ export function messagesFeature(ctx) { } function appBottomNav() { const visitor = isVisitor(); - const active = ui.noteThread || ui.profilePk ? 'feed' : ui.chatOpen - ? ui.msgView === 'feed' ? 'feed' : ui.msgView === 'notifs' ? 'notifs' : 'messages' : 'wallet'; + const me = !visitor && ctx.shownPubkey ? ctx.shownPubkey() : null; + const active = ui.userSearch ? 'search' : me && ui.profilePk === me && !ui.noteThread ? 'profile' : ui.noteThread || ui.profilePk ? 'feed' : ui.chatOpen + ? ui.msgView === 'feed' ? 'feed' : ui.msgView === 'notifs' ? 'notifs' : 'messages' : ui.tab === 'settings' ? 'settings' : 'wallet'; const leavePage = () => { stopFeedWatch(); stopNotifWatch(); // Top-level destinations must leave any feature page covering the shell. @@ -10149,8 +10150,8 @@ export function messagesFeature(ctx) { return notifUnread(); }; const icon = (paths) => ''; - const button = (id, label, paths, onClick) => h('button', { - type: 'button', class: 'app-nav-button' + (!visitor && (id === 'messages' ? hook('unreadMessages') : id === 'notifs' && notifsWaiting()) ? ' unread' : ''), + const button = (id, label, paths, onClick, cls = '') => h('button', { + type: 'button', class: 'app-nav-button' + cls + (!visitor && (id === 'messages' ? hook('unreadMessages') : id === 'notifs' && notifsWaiting()) ? ' unread' : ''), 'aria-label': label, 'aria-current': active === id ? 'page' : undefined, onClick: (e) => { // An open composer doesn't follow you around: back on the feed it sat @@ -10160,9 +10161,17 @@ export function messagesFeature(ctx) { onClick(e); }, }, h('span', { html: icon(paths) }), h('span', {}, label)); + // Your profile heads the desktop rail: a bigger face and your name, where + // the header's avatar sits on a phone. + const profileItem = me ? h('button', { + type: 'button', class: 'app-nav-button app-nav-wide app-nav-profile', + 'aria-label': t('profYourProfile'), 'aria-current': active === 'profile' ? 'page' : undefined, + onClick: () => { ui.profCompose = null; leavePage(); openProfile(me); render(); window.scrollTo({ top: 0 }); }, + }, avatar(me, 'chat-avatar app-nav-ava', false), h('span', { class: 'app-nav-name' }, displayName(me))) : null; return h('nav', { class: 'app-bottom-nav', 'data-key': 'app-bottom-nav', }, + profileItem, button('feed', t('feedTitle'), '', () => { // A destination tab is a destination: tapping Feed while already // there always returns to its top. Only the explicit "x new posts" @@ -10191,7 +10200,13 @@ export function messagesFeature(ctx) { ui.txDetail = null; ui.arkMoveDetail = null; ui.arkReconDetail = null; ui.arkExitDetail = null; ui.giftDetail = null; ui.chatOpen = false; ui.msgView = null; ui.tab = 'receive'; render(); window.scrollTo({ top: 0 }); - })); + }), + // Settings joins the nav where it's the desktop rail (the header's own + // gear steps aside there); a phone's bar keeps four. + ctx.openSettingsPage ? button('settings', t('tabSettings'), '', () => { + if (visitor) { toFrontDoor(); return; } + leavePage(); ctx.openSettingsPage(null); + }, ' app-nav-wide') : null); } // ---- media views: a feed's pictures as a grid, its videos to flip through -- // All / Images / Videos sits under the feed chips. Images lays the feed's @@ -11322,9 +11337,9 @@ export function messagesFeature(ctx) { return h('div', { class: 'col', style: 'gap:16px' }, ctx.brandHeader(!ui.pubProf && wallet.loaded), h('div', { class: 'card col', style: 'gap:10px' }, - h('h3', { style: 'margin:0' }, t('searchUsers')), + h('h3', { class: 'user-search-main', style: 'margin:0' }, t('searchUsers')), h('input', { - type: 'text', class: 'user-search-input', placeholder: t('searchUsersHint'), value: s.q, + type: 'text', class: 'user-search-input user-search-main', placeholder: t('searchUsersHint'), value: s.q, autocapitalize: 'none', autocomplete: 'off', spellcheck: 'false', onInput: (e) => { s.q = e.target.value; userSearcher.update(s.q); }, }), @@ -13049,6 +13064,12 @@ export function messagesFeature(ctx) { }, // The header magnifier: search anyone on nostr, results open profiles. userSearchAvailable() { return true; }, + // the desktop header's search field: typing there IS the search page's query + userSearchQuery(q) { + if (!ui.userSearch) { if (!isVisitor()) ui.chatOpen = false; ui.profilePk = null; ui.noteThread = null; ui.userSearch = { q: '', rows: null }; warmSearch(); } + ui.userSearch.q = q; userSearcher.update(q); render(); + return true; + }, openUserSearch() { if (!isVisitor()) ui.chatOpen = false; // a visitor's feed stays underneath, for Back ui.profilePk = null; -- cgit v1.2.3