diff options
| -rw-r--r-- | src/app.js | 12 | ||||
| -rw-r--r-- | src/features/messages.js | 9 | ||||
| -rw-r--r-- | tools/profile-stream-test.js | 19 |
3 files changed, 36 insertions, 4 deletions
@@ -3082,9 +3082,17 @@ function headerSearch() { onKeydown: (e) => { if (e.key === 'Enter' && !e.isComposing && e.target.value.trim()) { e.preventDefault(); featureHook('userSearchSubmit', e.target.value); e.target.blur(); } }, }); } +// Typing in the header field: whatever page is open steps aside for the +// results, but the search itself (its query and rows) stays. It used to do +// nothing once a search existed, so a profile opened from the results kept +// covering them while a new query was typed (Adam, 2026-11-14). function clearFeatureNavKeepSearch() { - if (ui.userSearch) return; // already on the search page: just the query moves - clearFeatureNav(); ui.screen = 'wallet'; + const s = ui.userSearch; + clearFeatureNav(); + // a visitor has no wallet screen to land on (it derived addresses from no + // seed: "Invalid mnemonic"); their search page draws over the front door + if (wallet.loaded) ui.screen = 'wallet'; + ui.userSearch = s; } function searchBtn() { diff --git a/src/features/messages.js b/src/features/messages.js index 2892153..b65b689 100644 --- a/src/features/messages.js +++ b/src/features/messages.js @@ -19218,7 +19218,14 @@ export function messagesFeature(ctx) { // the desktop header's search field: typing there IS the search page's query userSearchSubmit(q) { if (String(q || '').trim()) { openTextSearch(q); render(); } }, userSearchQuery(q) { - if (!ui.userSearch) { if (!isVisitor()) ui.chatOpen = false; ui.profilePk = null; ui.noteThread = null; ui.liveStream = null; ui.goLive = null; ui.userSearch = { q: '', rows: null }; warmSearch(); } + if (!ui.userSearch) { ui.userSearch = { q: '', rows: null }; warmSearch(); } + // Typing brings the results forward every time, not only the first: + // the search is kept (Back from a profile lands on it), so a second + // search typed from a profile opened from the first one updated a + // page hidden under that profile ("the search box stops working", + // Adam 2026-11-14). Back still returns to the profile. + if (!isVisitor()) ui.chatOpen = false; + ui.profilePk = null; ui.noteThread = null; ui.liveStream = null; ui.goLive = null; ui.userSearch.q = q; userSearcher.update(q); render(); return true; }, diff --git a/tools/profile-stream-test.js b/tools/profile-stream-test.js index 8d15775..b7dfb9b 100644 --- a/tools/profile-stream-test.js +++ b/tools/profile-stream-test.js @@ -17,7 +17,7 @@ const server = Bun.serve({ port: 0, fetch: () => new Response(html, { headers: { const browser = await puppeteer.launch({ relays: 'read', executablePath: '/usr/bin/google-chrome', headless: 'new', args: ['--no-sandbox'] }); const page = await browser.newPage(); const errs = []; -page.on('pageerror', (e) => errs.push(String(e))); +page.on('pageerror', (e) => errs.push(String(e.stack || e).slice(0, 600))); try { await page.setViewport({ width: 390, height: 844 }); if (process.env.DARK) await page.emulateMediaFeatures([{ name: 'prefers-color-scheme', value: 'dark' }]); @@ -52,6 +52,23 @@ try { console.log(` placeholder ${ghostAt ? ghostAt + ' ms' : 'not seen'}, first post ${firstAt || '—'} ms, rows at 3 s ${rowsAt3}`); check('posts arrive', firstAt > 0); check('...while waiting, the page says posts are loading', !!ghostAt || firstAt < 300, ghostAt ? 'placeholder shown' : 'posts were already in hand'); + // a second search typed into the desktop header field while that profile + // is open: the results come forward ("the search box stops working", + // Adam 2026-11-14 — they updated a page hidden under the profile) + await page.setViewport({ width: 1300, height: 900 }); + await sleep(500); + const field = await page.$('.header-search'); + check('the desktop header has a search field', !!field); + if (field) { + await page.evaluate(() => { const f = document.querySelector('.header-search'); f.focus(); f.value = ''; }); + await field.type('jack', { delay: 60 }); + let again = []; + for (let i = 0; i < 80 && !(again.length && again[0] !== found[0]); i++) { again = await rows(); if (!(again.length && again[0] !== found[0])) await sleep(250); } + const onProfile = await page.evaluate(() => !!document.querySelector('.prof-tabs')); + check('typing a new search from a profile shows its results', again.length > 0 && !onProfile, again.slice(0, 2).join(' | ')); + await page.goBack(); await sleep(800); + check('...and Back returns to the profile', await page.evaluate(() => !!document.querySelector('.prof-tabs'))); + } check('no page errors', !errs.length, errs.join(' | ')); } catch (e) { console.error(e); ok = false; } finally { await browser.close(); server.stop(); } console.log(ok ? '\nPASS' : '\nFAIL'); |
