mirror of
https://gitlab.com/soapbox-pub/ditto.git
synced 2025-12-06 11:29:46 +00:00
Ensure relations are loaded throughout the API where needed
This commit is contained in:
parent
733b8ba9c5
commit
a5369d9826
7 changed files with 44 additions and 21 deletions
|
|
@ -59,7 +59,7 @@ const createAccountController: AppController = async (c) => {
|
||||||
const verifyCredentialsController: AppController = async (c) => {
|
const verifyCredentialsController: AppController = async (c) => {
|
||||||
const pubkey = c.get('pubkey')!;
|
const pubkey = c.get('pubkey')!;
|
||||||
|
|
||||||
const event = await getAuthor(pubkey);
|
const event = await getAuthor(pubkey, { relations: ['author_stats'] });
|
||||||
if (event) {
|
if (event) {
|
||||||
return c.json(await renderAccount(event, { withSource: true }));
|
return c.json(await renderAccount(event, { withSource: true }));
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -138,7 +138,15 @@ const accountStatusesController: AppController = async (c) => {
|
||||||
return c.json([]);
|
return c.json([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const filter: DittoFilter<1> = { authors: [pubkey], kinds: [1], relations: ['author'], since, until, limit };
|
const filter: DittoFilter<1> = {
|
||||||
|
authors: [pubkey],
|
||||||
|
kinds: [1],
|
||||||
|
relations: ['author', 'event_stats', 'author_stats'],
|
||||||
|
since,
|
||||||
|
until,
|
||||||
|
limit,
|
||||||
|
};
|
||||||
|
|
||||||
if (tagged) {
|
if (tagged) {
|
||||||
filter['#t'] = [tagged];
|
filter['#t'] = [tagged];
|
||||||
}
|
}
|
||||||
|
|
@ -257,7 +265,9 @@ const favouritesController: AppController = async (c) => {
|
||||||
.map((event) => event.tags.find((tag) => tag[0] === 'e')?.[1])
|
.map((event) => event.tags.find((tag) => tag[0] === 'e')?.[1])
|
||||||
.filter((id): id is string => !!id);
|
.filter((id): id is string => !!id);
|
||||||
|
|
||||||
const events1 = await mixer.getFilters([{ kinds: [1], ids, relations: ['author'] }], { timeout: Time.seconds(1) });
|
const events1 = await mixer.getFilters([{ kinds: [1], ids, relations: ['author', 'event_stats', 'author_stats'] }], {
|
||||||
|
timeout: Time.seconds(1),
|
||||||
|
});
|
||||||
|
|
||||||
const statuses = await Promise.all(events1.map((event) => renderStatus(event, c.get('pubkey'))));
|
const statuses = await Promise.all(events1.map((event) => renderStatus(event, c.get('pubkey'))));
|
||||||
return paginated(c, events1, statuses);
|
return paginated(c, events1, statuses);
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ function searchEvents({ q, type, limit, account_id }: SearchQuery): Promise<Even
|
||||||
const filter: DittoFilter = {
|
const filter: DittoFilter = {
|
||||||
kinds: typeToKinds(type),
|
kinds: typeToKinds(type),
|
||||||
search: q,
|
search: q,
|
||||||
relations: ['author'],
|
relations: ['author', 'event_stats', 'author_stats'],
|
||||||
limit,
|
limit,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -115,16 +115,20 @@ async function getLookupFilters({ q, type, resolve }: SearchQuery): Promise<Ditt
|
||||||
const result = nip19.decode(q);
|
const result = nip19.decode(q);
|
||||||
switch (result.type) {
|
switch (result.type) {
|
||||||
case 'npub':
|
case 'npub':
|
||||||
if (accounts) filters.push({ kinds: [0], authors: [result.data] });
|
if (accounts) filters.push({ kinds: [0], authors: [result.data], relations: ['author_stats'] });
|
||||||
break;
|
break;
|
||||||
case 'nprofile':
|
case 'nprofile':
|
||||||
if (accounts) filters.push({ kinds: [0], authors: [result.data.pubkey] });
|
if (accounts) filters.push({ kinds: [0], authors: [result.data.pubkey], relations: ['author_stats'] });
|
||||||
break;
|
break;
|
||||||
case 'note':
|
case 'note':
|
||||||
if (statuses) filters.push({ kinds: [1], ids: [result.data] });
|
if (statuses) {
|
||||||
|
filters.push({ kinds: [1], ids: [result.data], relations: ['author', 'event_stats', 'author_stats'] });
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'nevent':
|
case 'nevent':
|
||||||
if (statuses) filters.push({ kinds: [1], ids: [result.data.id] });
|
if (statuses) {
|
||||||
|
filters.push({ kinds: [1], ids: [result.data.id], relations: ['author', 'event_stats', 'author_stats'] });
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch (_e) {
|
} catch (_e) {
|
||||||
|
|
@ -136,11 +140,11 @@ async function getLookupFilters({ q, type, resolve }: SearchQuery): Promise<Ditt
|
||||||
} else if (accounts && ACCT_REGEX.test(q)) {
|
} else if (accounts && ACCT_REGEX.test(q)) {
|
||||||
const pubkey = await lookupNip05Cached(q);
|
const pubkey = await lookupNip05Cached(q);
|
||||||
if (pubkey) {
|
if (pubkey) {
|
||||||
filters.push({ kinds: [0], authors: [pubkey] });
|
filters.push({ kinds: [0], authors: [pubkey], relations: ['author_stats'] });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return filters.map((filter) => ({ ...filter, relations: ['author'] }));
|
return filters;
|
||||||
}
|
}
|
||||||
|
|
||||||
export { searchController };
|
export { searchController };
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ const createStatusSchema = z.object({
|
||||||
const statusController: AppController = async (c) => {
|
const statusController: AppController = async (c) => {
|
||||||
const id = c.req.param('id');
|
const id = c.req.param('id');
|
||||||
|
|
||||||
const event = await getEvent(id, { kind: 1, relations: ['author'] });
|
const event = await getEvent(id, { kind: 1, relations: ['author', 'event_stats', 'author_stats'] });
|
||||||
if (event) {
|
if (event) {
|
||||||
return c.json(await renderStatus(event, c.get('pubkey')));
|
return c.json(await renderStatus(event, c.get('pubkey')));
|
||||||
}
|
}
|
||||||
|
|
@ -89,7 +89,7 @@ const createStatusController: AppController = async (c) => {
|
||||||
|
|
||||||
const contextController: AppController = async (c) => {
|
const contextController: AppController = async (c) => {
|
||||||
const id = c.req.param('id');
|
const id = c.req.param('id');
|
||||||
const event = await getEvent(id, { kind: 1, relations: ['author'] });
|
const event = await getEvent(id, { kind: 1, relations: ['author', 'event_stats', 'author_stats'] });
|
||||||
|
|
||||||
async function renderStatuses(events: Event<1>[]) {
|
async function renderStatuses(events: Event<1>[]) {
|
||||||
const statuses = await Promise.all(events.map((event) => renderStatus(event, c.get('pubkey'))));
|
const statuses = await Promise.all(events.map((event) => renderStatus(event, c.get('pubkey'))));
|
||||||
|
|
@ -110,7 +110,7 @@ const contextController: AppController = async (c) => {
|
||||||
|
|
||||||
const favouriteController: AppController = async (c) => {
|
const favouriteController: AppController = async (c) => {
|
||||||
const id = c.req.param('id');
|
const id = c.req.param('id');
|
||||||
const target = await getEvent(id, { kind: 1, relations: ['author'] });
|
const target = await getEvent(id, { kind: 1, relations: ['author', 'event_stats', 'author_stats'] });
|
||||||
|
|
||||||
if (target) {
|
if (target) {
|
||||||
await createEvent({
|
await createEvent({
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ const hashtagTimelineController: AppController = (c) => {
|
||||||
/** Render statuses for timelines. */
|
/** Render statuses for timelines. */
|
||||||
async function renderStatuses(c: AppContext, filters: DittoFilter<1>[]) {
|
async function renderStatuses(c: AppContext, filters: DittoFilter<1>[]) {
|
||||||
const events = await mixer.getFilters(
|
const events = await mixer.getFilters(
|
||||||
filters.map((filter) => ({ ...filter, relations: ['author'] })),
|
filters.map((filter) => ({ ...filter, relations: ['author', 'event_stats', 'author_stats'] })),
|
||||||
{ timeout: Time.seconds(1) },
|
{ timeout: Time.seconds(1) },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,14 @@ const getEvent = async <K extends number = number>(
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Get a Nostr `set_medatadata` event for a user's pubkey. */
|
/** Get a Nostr `set_medatadata` event for a user's pubkey. */
|
||||||
const getAuthor = async (pubkey: string, timeout = 1000): Promise<Event<0> | undefined> => {
|
const getAuthor = async (pubkey: string, opts: GetEventOpts<0> = {}): Promise<Event<0> | undefined> => {
|
||||||
const [event] = await mixer.getFilters([{ authors: [pubkey], kinds: [0], limit: 1 }], { limit: 1, timeout });
|
const { relations, timeout = 1000 } = opts;
|
||||||
|
|
||||||
|
const [event] = await mixer.getFilters(
|
||||||
|
[{ authors: [pubkey], relations, kinds: [0], limit: 1 }],
|
||||||
|
{ limit: 1, timeout },
|
||||||
|
);
|
||||||
|
|
||||||
return event;
|
return event;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -60,7 +66,7 @@ async function getAncestors(event: Event<1>, result = [] as Event<1>[]): Promise
|
||||||
const inReplyTo = replyTag ? replyTag[1] : undefined;
|
const inReplyTo = replyTag ? replyTag[1] : undefined;
|
||||||
|
|
||||||
if (inReplyTo) {
|
if (inReplyTo) {
|
||||||
const parentEvent = await getEvent(inReplyTo, { kind: 1, relations: ['author'] });
|
const parentEvent = await getEvent(inReplyTo, { kind: 1, relations: ['author', 'event_stats', 'author_stats'] });
|
||||||
|
|
||||||
if (parentEvent) {
|
if (parentEvent) {
|
||||||
result.push(parentEvent);
|
result.push(parentEvent);
|
||||||
|
|
@ -73,7 +79,10 @@ async function getAncestors(event: Event<1>, result = [] as Event<1>[]): Promise
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDescendants(eventId: string): Promise<Event<1>[]> {
|
function getDescendants(eventId: string): Promise<Event<1>[]> {
|
||||||
return mixer.getFilters([{ kinds: [1], '#e': [eventId], relations: ['author'] }], { limit: 200, timeout: 2000 });
|
return mixer.getFilters(
|
||||||
|
[{ kinds: [1], '#e': [eventId], relations: ['author', 'event_stats', 'author_stats'] }],
|
||||||
|
{ limit: 200, timeout: 2000 },
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns whether the pubkey is followed by a local user. */
|
/** Returns whether the pubkey is followed by a local user. */
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ async function renderEventAccounts(c: AppContext, filters: Filter[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const accounts = await Promise.all([...pubkeys].map(async (pubkey) => {
|
const accounts = await Promise.all([...pubkeys].map(async (pubkey) => {
|
||||||
const author = await getAuthor(pubkey);
|
const author = await getAuthor(pubkey, { relations: ['author_stats'] });
|
||||||
if (author) {
|
if (author) {
|
||||||
return renderAccount(author);
|
return renderAccount(author);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -86,8 +86,8 @@ async function renderStatus(event: eventsDB.DittoEvent<1>, viewerPubkey?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
async function toMention(pubkey: string) {
|
async function toMention(pubkey: string) {
|
||||||
const profile = await getAuthor(pubkey);
|
const author = await getAuthor(pubkey);
|
||||||
const account = profile ? await renderAccount(profile) : undefined;
|
const account = author ? await renderAccount(author) : undefined;
|
||||||
|
|
||||||
if (account) {
|
if (account) {
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue