views: avoid counting directly in the view, take from the event object if it has it
This commit is contained in:
parent
3147496d78
commit
21b6a02ff3
|
@ -80,6 +80,9 @@ type EventQuery = SelectQueryBuilder<DittoDB, 'events', {
|
|||
content: string;
|
||||
created_at: number;
|
||||
sig: string;
|
||||
stats_replies_count?: number;
|
||||
stats_reposts_count?: number;
|
||||
stats_reactions_count?: number;
|
||||
author_id?: string;
|
||||
author_tags?: string;
|
||||
author_kind?: number;
|
||||
|
@ -87,6 +90,9 @@ type EventQuery = SelectQueryBuilder<DittoDB, 'events', {
|
|||
author_content?: string;
|
||||
author_created_at?: number;
|
||||
author_sig?: string;
|
||||
author_stats_followers_count?: number;
|
||||
author_stats_following_count?: number;
|
||||
author_stats_notes_count?: number;
|
||||
}>;
|
||||
|
||||
/** Build the query for a filter. */
|
||||
|
@ -184,8 +190,12 @@ function getFiltersQuery(filters: DittoFilter[]) {
|
|||
.reduce((result, query) => result.unionAll(query));
|
||||
}
|
||||
|
||||
type AuthorStats = Omit<DittoDB['pubkey_stats'], 'pubkey'>;
|
||||
type EventStats = Omit<DittoDB['event_stats'], 'event_id'>;
|
||||
|
||||
interface DittoEvent<K extends number = number> extends Event<K> {
|
||||
author?: Event<0>;
|
||||
author?: Event<0> & { stats?: AuthorStats };
|
||||
stats?: EventStats;
|
||||
}
|
||||
|
||||
/** Get events for filters from the database. */
|
||||
|
@ -221,6 +231,22 @@ async function getFilters<K extends number>(
|
|||
tags: JSON.parse(row.author_tags!),
|
||||
sig: row.author_sig!,
|
||||
};
|
||||
|
||||
if (typeof row.author_stats_followers_count === 'number') {
|
||||
event.author.stats = {
|
||||
followers_count: row.author_stats_followers_count,
|
||||
following_count: row.author_stats_following_count!,
|
||||
notes_count: row.author_stats_notes_count!,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof row.stats_replies_count === 'number') {
|
||||
event.stats = {
|
||||
replies_count: row.stats_replies_count,
|
||||
reposts_count: row.stats_reposts_count!,
|
||||
reactions_count: row.stats_reactions_count!,
|
||||
};
|
||||
}
|
||||
|
||||
return event;
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { Conf } from '@/config.ts';
|
||||
import * as eventsDB from '@/db/events.ts';
|
||||
import { type DittoEvent } from '@/db/events.ts';
|
||||
import { findUser } from '@/db/users.ts';
|
||||
import { lodash, nip19, type UnsignedEvent } from '@/deps.ts';
|
||||
import { getFollowedPubkeys } from '@/queries.ts';
|
||||
import { jsonMetaContentSchema } from '@/schemas/nostr.ts';
|
||||
import { verifyNip05Cached } from '@/utils/nip05.ts';
|
||||
import { Nip05, nostrDate, nostrNow, parseNip05 } from '@/utils.ts';
|
||||
|
@ -12,7 +11,10 @@ interface ToAccountOpts {
|
|||
withSource?: boolean;
|
||||
}
|
||||
|
||||
async function renderAccount(event: UnsignedEvent<0>, opts: ToAccountOpts = {}) {
|
||||
async function renderAccount(
|
||||
event: Omit<NonNullable<DittoEvent['author']>, 'id' | 'sig'>,
|
||||
opts: ToAccountOpts = {},
|
||||
) {
|
||||
const { withSource = false } = opts;
|
||||
const { pubkey } = event;
|
||||
|
||||
|
@ -26,12 +28,9 @@ async function renderAccount(event: UnsignedEvent<0>, opts: ToAccountOpts = {})
|
|||
|
||||
const npub = nip19.npubEncode(pubkey);
|
||||
|
||||
const [user, parsed05, followersCount, followingCount, statusesCount] = await Promise.all([
|
||||
const [user, parsed05] = await Promise.all([
|
||||
findUser({ pubkey }),
|
||||
parseAndVerifyNip05(nip05, pubkey),
|
||||
eventsDB.countFilters([{ kinds: [3], '#p': [pubkey] }]),
|
||||
getFollowedPubkeys(pubkey).then((pubkeys) => pubkeys.length),
|
||||
eventsDB.countFilters([{ kinds: [1], authors: [pubkey] }]),
|
||||
]);
|
||||
|
||||
return {
|
||||
|
@ -40,14 +39,14 @@ async function renderAccount(event: UnsignedEvent<0>, opts: ToAccountOpts = {})
|
|||
avatar: picture,
|
||||
avatar_static: picture,
|
||||
bot: false,
|
||||
created_at: event ? nostrDate(event.created_at).toISOString() : new Date().toISOString(),
|
||||
created_at: nostrDate(event.created_at).toISOString(),
|
||||
discoverable: true,
|
||||
display_name: name,
|
||||
emojis: renderEmojis(event),
|
||||
fields: [],
|
||||
follow_requests_count: 0,
|
||||
followers_count: followersCount,
|
||||
following_count: followingCount,
|
||||
followers_count: event.stats?.followers_count ?? 0,
|
||||
following_count: event.stats?.following_count ?? 0,
|
||||
fqn: parsed05?.handle || npub,
|
||||
header: banner,
|
||||
header_static: banner,
|
||||
|
@ -65,7 +64,7 @@ async function renderAccount(event: UnsignedEvent<0>, opts: ToAccountOpts = {})
|
|||
follow_requests_count: 0,
|
||||
}
|
||||
: undefined,
|
||||
statuses_count: statusesCount,
|
||||
statuses_count: event.stats?.notes_count ?? 0,
|
||||
url: Conf.local(`/users/${pubkey}`),
|
||||
username: parsed05?.nickname || npub.substring(0, 8),
|
||||
pleroma: {
|
||||
|
|
|
@ -26,13 +26,10 @@ async function renderStatus(event: eventsDB.DittoEvent<1>, viewerPubkey?: string
|
|||
|
||||
const { html, links, firstUrl } = parseNoteContent(event.content);
|
||||
|
||||
const [mentions, card, repliesCount, reblogsCount, favouritesCount, [repostEvent], [reactionEvent]] = await Promise
|
||||
const [mentions, card, [repostEvent], [reactionEvent]] = await Promise
|
||||
.all([
|
||||
Promise.all(mentionedPubkeys.map(toMention)),
|
||||
firstUrl ? unfurlCardCached(firstUrl) : null,
|
||||
eventsDB.countFilters([{ kinds: [1], '#e': [event.id] }]),
|
||||
eventsDB.countFilters([{ kinds: [6], '#e': [event.id] }]),
|
||||
eventsDB.countFilters([{ kinds: [7], '#e': [event.id] }]),
|
||||
viewerPubkey
|
||||
? eventsDB.getFilters([{ kinds: [6], '#e': [event.id], authors: [viewerPubkey] }], { limit: 1 })
|
||||
: [],
|
||||
|
@ -66,9 +63,9 @@ async function renderStatus(event: eventsDB.DittoEvent<1>, viewerPubkey?: string
|
|||
spoiler_text: (cw ? cw[1] : subject?.[1]) || '',
|
||||
visibility: 'public',
|
||||
language: event.tags.find((tag) => tag[0] === 'lang')?.[1] || null,
|
||||
replies_count: repliesCount,
|
||||
reblogs_count: reblogsCount,
|
||||
favourites_count: favouritesCount,
|
||||
replies_count: event.stats?.replies_count ?? 0,
|
||||
reblogs_count: event.stats?.reposts_count ?? 0,
|
||||
favourites_count: event.stats?.reactions_count ?? 0,
|
||||
favourited: reactionEvent?.content === '+',
|
||||
reblogged: Boolean(repostEvent),
|
||||
muted: false,
|
||||
|
|
Loading…
Reference in New Issue