aboutsummaryrefslogtreecommitdiffstats
path: root/src/recipient-search.js
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-10-02 07:48:32 -0700
committerAdam Soltys <[email protected]>2026-10-02 07:48:32 -0700
commit686e2d391d3a963535d5deec7043999b9b92b19b (patch)
treef44167f4affaf38e63ed1bd637c7509f74a72679 /src/recipient-search.js
parent53160e57a1bf65812ddade7e4e71d0c3a75e812c (diff)
downloadcoinosv3-686e2d391d3a963535d5deec7043999b9b92b19b.tar.gz
coinosv3-686e2d391d3a963535d5deec7043999b9b92b19b.zip
Profiles show Following and Followers, each a list you can open
Under the bio: "116 Following · 572 Followers". Tapping either opens the people below it (50 at a time); tapping a person opens their profile. Follows are the person's kind 3, now read from Primal's cache alongside the relays (a list kept only on their outbox relays used to read as nobody). Followers, which no relay counts, come from Primal: the count from user_profile, the list from user_followers, a first screenful fast and the rest after, without reordering what is on screen. Every event taken from Primal is signature-checked in the verify worker first, and the profiles among them fill names and faces the relays lacked. Also translates the post-zap "no address" message. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Dmcrt9KyNDKVWFKnb8BREo
Diffstat (limited to 'src/recipient-search.js')
-rw-r--r--src/recipient-search.js12
1 files changed, 8 insertions, 4 deletions
diff --git a/src/recipient-search.js b/src/recipient-search.js
index b0a0edc..fdeaeaf 100644
--- a/src/recipient-search.js
+++ b/src/recipient-search.js
@@ -51,21 +51,25 @@ const MAX_RESULTS = 8;
// to cost more than the query itself. Idle for a minute, it closes itself.
let pws = null, pwsN = 0, pwsIdle = null;
const pwsSubs = new Map(); // sub id -> { rows, finish }
-function primalSearch(q, limit = MAX_RESULTS) {
+// Any of Primal's cache calls over the shared socket; resolves with every
+// event it answered (its own stats kinds included) at EOSE or the timeout.
+export function primalCache(cmd, args, timeoutMs = 3500) {
return new Promise((resolve) => {
const sid = 'rs' + ++pwsN;
const rows = [];
const finish = () => { clearTimeout(to); pwsSubs.delete(sid); resolve(rows); };
- const to = setTimeout(finish, 3500);
+ const to = setTimeout(finish, timeoutMs);
pwsSubs.set(sid, { rows, finish });
clearTimeout(pwsIdle);
pwsIdle = setTimeout(() => { try { pws?.close(); } catch {} pws = null; }, 60_000);
- const send = () => { try { pws.send(JSON.stringify(['REQ', sid, { cache: ['user_search', { query: q, limit }] }])); } catch { finish(); } };
+ const send = () => { try { pws.send(JSON.stringify(['REQ', sid, { cache: [cmd, args] }])); } catch { finish(); } };
if (pws && pws.readyState === 1) return send();
if (!ensurePws()) return finish();
pws.addEventListener('open', send, { once: true });
});
}
+const primalSearch = (q, limit = MAX_RESULTS) =>
+ primalCache('user_search', { query: q, limit }).then((evs) => evs.filter((e) => e.kind === 0));
function ensurePws() {
if (pws && pws.readyState <= 1) return true;
@@ -75,7 +79,7 @@ function ensurePws() {
const m = JSON.parse(ev.data);
const sub = pwsSubs.get(m[1]);
if (!sub) return;
- if (m[0] === 'EVENT' && m[2] && m[2].kind === 0) sub.rows.push(m[2]);
+ if (m[0] === 'EVENT' && m[2]) sub.rows.push(m[2]);
if (m[0] === 'EOSE') sub.finish();
} catch {}
};