Apply same search improvements to accountSearchController

This commit is contained in:
Alex Gleason 2024-08-07 12:31:22 -05:00
parent 1efd4fad12
commit cdee2604a1
No known key found for this signature in database
GPG key ID: 7211D1F99744FBB7
3 changed files with 45 additions and 41 deletions

View file

@ -8,7 +8,7 @@ import { getAuthor, getFollowedPubkeys } from '@/queries.ts';
import { booleanParamSchema, fileSchema } from '@/schema.ts'; import { booleanParamSchema, fileSchema } from '@/schema.ts';
import { Storages } from '@/storages.ts'; import { Storages } from '@/storages.ts';
import { uploadFile } from '@/utils/upload.ts'; import { uploadFile } from '@/utils/upload.ts';
import { nostrNow } from '@/utils.ts'; import { dedupeEvents, extractBech32, nostrNow } from '@/utils.ts';
import { createEvent, paginated, parseBody, updateListEvent } from '@/utils/api.ts'; import { createEvent, paginated, parseBody, updateListEvent } from '@/utils/api.ts';
import { lookupAccount } from '@/utils/lookup.ts'; import { lookupAccount } from '@/utils/lookup.ts';
import { renderAccounts, renderEventAccounts, renderStatuses } from '@/views.ts'; import { renderAccounts, renderEventAccounts, renderStatuses } from '@/views.ts';
@ -125,30 +125,33 @@ const accountSearchController: AppController = async (c) => {
const query = decodeURIComponent(q); const query = decodeURIComponent(q);
const store = await Storages.search(); const store = await Storages.search();
const bech32 = extractBech32(query);
const [event, events] = await Promise.all([ const [event, events] = await Promise.all([
lookupAccount(query), lookupAccount(bech32 ?? query),
store.query([{ kinds: [0], search: query, limit }], { signal }), store.query([{ kinds: [0], search: query, limit }], { signal }),
]); ]);
if (event) {
events.unshift(event);
}
const results = await hydrateEvents({ const results = await hydrateEvents({
events: event ? [event, ...events] : events, events: dedupeEvents(events),
store, store,
signal, signal,
}); });
if ((results.length < 1) && query.match(/npub1\w+/)) { const accounts = await Promise.all(
const possibleNpub = query; results.map((event) => renderAccount(event)),
try { );
const npubHex = nip19.decode(possibleNpub);
return c.json([await accountFromPubkey(String(npubHex.data))]); // Render account from pubkey.
} catch (e) { const pubkey = bech32ToPubkey(result.data.q);
console.log(e); if (pubkey && !accounts.find((account) => account.id === pubkey)) {
return c.json([]); accounts.unshift(await accountFromPubkey(pubkey));
}
} }
const accounts = await Promise.all(results.map((event) => renderAccount(event)));
return c.json(accounts); return c.json(accounts);
}; };

View file

@ -5,7 +5,7 @@ import { z } from 'zod';
import { AppController } from '@/app.ts'; import { AppController } from '@/app.ts';
import { booleanParamSchema } from '@/schema.ts'; import { booleanParamSchema } from '@/schema.ts';
import { Storages } from '@/storages.ts'; import { Storages } from '@/storages.ts';
import { bech32ToPubkey, dedupeEvents } from '@/utils.ts'; import { bech32ToPubkey, dedupeEvents, extractBech32 } from '@/utils.ts';
import { nip05Cache } from '@/utils/nip05.ts'; import { nip05Cache } from '@/utils/nip05.ts';
import { accountFromPubkey, renderAccount } from '@/views/mastodon/accounts.ts'; import { accountFromPubkey, renderAccount } from '@/views/mastodon/accounts.ts';
import { renderStatus } from '@/views/mastodon/statuses.ts'; import { renderStatus } from '@/views/mastodon/statuses.ts';
@ -39,7 +39,7 @@ const searchController: AppController = async (c) => {
]); ]);
if (event) { if (event) {
events.push(event); events.unshift(event);
} }
const results = dedupeEvents(events); const results = dedupeEvents(events);
@ -169,30 +169,4 @@ async function getLookupFilters({ q, type, resolve }: SearchQuery, signal: Abort
return filters; return filters;
} }
/** Extract a bech32 ID out of a search query string. */
function extractBech32(value: string): string | undefined {
let bech32: string = value;
try {
const uri = new URL(value);
switch (uri.protocol) {
// Extract from NIP-19 URI, eg `nostr:npub1q3sle0kvfsehgsuexttt3ugjd8xdklxfwwkh559wxckmzddywnws6cd26p`.
case 'nostr:':
bech32 = uri.pathname;
break;
// Extract from URL, eg `https://njump.me/npub1q3sle0kvfsehgsuexttt3ugjd8xdklxfwwkh559wxckmzddywnws6cd26p`.
case 'http:':
case 'https:':
bech32 = uri.pathname.slice(1);
break;
}
} catch {
// do nothing
}
if (n.bech32().safeParse(bech32).success) {
return bech32;
}
}
export { searchController }; export { searchController };

View file

@ -24,6 +24,32 @@ function bech32ToPubkey(bech32: string): string | undefined {
} }
} }
/** Extract a bech32 ID out of a search query string. */
function extractBech32(value: string): string | undefined {
let bech32: string = value;
try {
const uri = new URL(value);
switch (uri.protocol) {
// Extract from NIP-19 URI, eg `nostr:npub1q3sle0kvfsehgsuexttt3ugjd8xdklxfwwkh559wxckmzddywnws6cd26p`.
case 'nostr:':
bech32 = uri.pathname;
break;
// Extract from URL, eg `https://njump.me/npub1q3sle0kvfsehgsuexttt3ugjd8xdklxfwwkh559wxckmzddywnws6cd26p`.
case 'http:':
case 'https:':
bech32 = uri.pathname.slice(1);
break;
}
} catch {
// do nothing
}
if (n.bech32().safeParse(bech32).success) {
return bech32;
}
}
interface Nip05 { interface Nip05 {
/** Localpart of the nip05, eg `alex` in `alex@alexgleason.me`. */ /** Localpart of the nip05, eg `alex` in `alex@alexgleason.me`. */
local: string | undefined; local: string | undefined;
@ -97,6 +123,7 @@ export {
bech32ToPubkey, bech32ToPubkey,
dedupeEvents, dedupeEvents,
eventAge, eventAge,
extractBech32,
findTag, findTag,
isNostrId, isNostrId,
isURL, isURL,