aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/app.js12
-rw-r--r--src/features/messages.js9
-rw-r--r--tools/profile-stream-test.js19
3 files changed, 36 insertions, 4 deletions
diff --git a/src/app.js b/src/app.js
index e6e6843..b7580e5 100644
--- a/src/app.js
+++ b/src/app.js
@@ -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');