mirror of
https://gitlab.com/soapbox-pub/ditto.git
synced 2025-12-06 11:29:46 +00:00
Fix mentions in statuses?
This commit is contained in:
parent
7780507a15
commit
5811a19151
3 changed files with 44 additions and 21 deletions
|
|
@ -30,6 +30,7 @@ export interface DittoEvent extends NostrEvent {
|
||||||
author_domain?: string;
|
author_domain?: string;
|
||||||
author_stats?: AuthorStats;
|
author_stats?: AuthorStats;
|
||||||
event_stats?: EventStats;
|
event_stats?: EventStats;
|
||||||
|
mentions?: DittoEvent[];
|
||||||
user?: DittoEvent;
|
user?: DittoEvent;
|
||||||
repost?: DittoEvent;
|
repost?: DittoEvent;
|
||||||
quote?: DittoEvent;
|
quote?: DittoEvent;
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,10 @@ async function hydrateEvents(opts: HydrateOpts): Promise<DittoEvent[]> {
|
||||||
|
|
||||||
const cache = [...events];
|
const cache = [...events];
|
||||||
|
|
||||||
|
for (const event of await gatherMentions({ events: cache, store, signal })) {
|
||||||
|
cache.push(event);
|
||||||
|
}
|
||||||
|
|
||||||
for (const event of await gatherReposts({ events: cache, store, signal })) {
|
for (const event of await gatherReposts({ events: cache, store, signal })) {
|
||||||
cache.push(event);
|
cache.push(event);
|
||||||
}
|
}
|
||||||
|
|
@ -146,6 +150,9 @@ export function assembleEvents(
|
||||||
if (id) {
|
if (id) {
|
||||||
event.quote = b.find((e) => matchFilter({ kinds: [1, 20], ids: [id] }, e));
|
event.quote = b.find((e) => matchFilter({ kinds: [1, 20], ids: [id] }, e));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const pubkeys = event.tags.filter(([name]) => name === 'p').map(([_name, value]) => value);
|
||||||
|
event.mentions = b.filter((e) => matchFilter({ kinds: [0], authors: pubkeys }, e));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.kind === 6) {
|
if (event.kind === 6) {
|
||||||
|
|
@ -267,6 +274,35 @@ function gatherQuotes({ events, store, signal }: HydrateOpts): Promise<DittoEven
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Collect mentioned profiles from notes. */
|
||||||
|
async function gatherMentions({ events, store, signal }: HydrateOpts): Promise<DittoEvent[]> {
|
||||||
|
const pubkeys = new Set<string>();
|
||||||
|
|
||||||
|
for (const event of events) {
|
||||||
|
if (event.kind === 1) {
|
||||||
|
const pubkey = event.tags.find(([name]) => name === 'p')?.[1];
|
||||||
|
if (pubkey) {
|
||||||
|
pubkeys.add(pubkey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const authors = await store.query(
|
||||||
|
[{ kinds: [0], authors: [...pubkeys], limit: pubkeys.size }],
|
||||||
|
{ signal },
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const pubkey of pubkeys) {
|
||||||
|
const author = authors.find((e) => matchFilter({ kinds: [0], authors: [pubkey] }, e));
|
||||||
|
if (!author) {
|
||||||
|
const fallback = fallbackAuthor(pubkey);
|
||||||
|
authors.push(fallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return authors;
|
||||||
|
}
|
||||||
|
|
||||||
/** Collect authors from the events. */
|
/** Collect authors from the events. */
|
||||||
async function gatherAuthors({ events, store, signal }: HydrateOpts): Promise<DittoEvent[]> {
|
async function gatherAuthors({ events, store, signal }: HydrateOpts): Promise<DittoEvent[]> {
|
||||||
const pubkeys = new Set<string>();
|
const pubkeys = new Set<string>();
|
||||||
|
|
@ -297,7 +333,7 @@ async function gatherAuthors({ events, store, signal }: HydrateOpts): Promise<Di
|
||||||
|
|
||||||
for (const pubkey of pubkeys) {
|
for (const pubkey of pubkeys) {
|
||||||
const author = authors.find((e) => matchFilter({ kinds: [0], authors: [pubkey] }, e));
|
const author = authors.find((e) => matchFilter({ kinds: [0], authors: [pubkey] }, e));
|
||||||
if (author) {
|
if (!author) {
|
||||||
const fallback = fallbackAuthor(pubkey);
|
const fallback = fallbackAuthor(pubkey);
|
||||||
authors.push(fallback);
|
authors.push(fallback);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import { MastodonMention } from '@/entities/MastodonMention.ts';
|
||||||
import { MastodonStatus } from '@/entities/MastodonStatus.ts';
|
import { MastodonStatus } from '@/entities/MastodonStatus.ts';
|
||||||
import { type DittoEvent } from '@/interfaces/DittoEvent.ts';
|
import { type DittoEvent } from '@/interfaces/DittoEvent.ts';
|
||||||
import { Storages } from '@/storages.ts';
|
import { Storages } from '@/storages.ts';
|
||||||
import { isNostrId, nostrDate } from '@/utils.ts';
|
import { nostrDate } from '@/utils.ts';
|
||||||
import { getMediaLinks, parseNoteContent, stripimeta } from '@/utils/note.ts';
|
import { getMediaLinks, parseNoteContent, stripimeta } from '@/utils/note.ts';
|
||||||
import { findReplyTag } from '@/utils/tags.ts';
|
import { findReplyTag } from '@/utils/tags.ts';
|
||||||
import { unfurlCardCached } from '@/utils/unfurl.ts';
|
import { unfurlCardCached } from '@/utils/unfurl.ts';
|
||||||
|
|
@ -33,28 +33,14 @@ async function renderStatus(event: DittoEvent, opts: RenderStatusOpts): Promise<
|
||||||
});
|
});
|
||||||
|
|
||||||
const account = event.author
|
const account = event.author
|
||||||
? await renderAccount({ ...event.author, author_stats: event.author_stats })
|
? renderAccount({ ...event.author, author_stats: event.author_stats })
|
||||||
: await accountFromPubkey(event.pubkey);
|
: accountFromPubkey(event.pubkey);
|
||||||
|
|
||||||
const replyId = findReplyTag(event.tags)?.[1];
|
const replyId = findReplyTag(event.tags)?.[1];
|
||||||
|
|
||||||
const mentionedPubkeys = [
|
|
||||||
...new Set(
|
|
||||||
event.tags
|
|
||||||
.filter(([name, value]) => name === 'p' && isNostrId(value))
|
|
||||||
.map(([, value]) => value),
|
|
||||||
),
|
|
||||||
];
|
|
||||||
|
|
||||||
const store = await Storages.db();
|
const store = await Storages.db();
|
||||||
|
|
||||||
const mentionedProfiles = await store.query(
|
const mentions = event.mentions?.map((event) => renderMention(event)) ?? [];
|
||||||
[{ kinds: [0], authors: mentionedPubkeys, limit: mentionedPubkeys.length }],
|
|
||||||
);
|
|
||||||
|
|
||||||
const mentions = await Promise.all(
|
|
||||||
mentionedPubkeys.map((pubkey) => renderMention(pubkey, mentionedProfiles.find((event) => event.pubkey === pubkey))),
|
|
||||||
);
|
|
||||||
|
|
||||||
const { html, links, firstUrl } = parseNoteContent(stripimeta(event.content, event.tags), mentions);
|
const { html, links, firstUrl } = parseNoteContent(stripimeta(event.content, event.tags), mentions);
|
||||||
|
|
||||||
|
|
@ -170,8 +156,8 @@ async function renderReblog(event: DittoEvent, opts: RenderStatusOpts): Promise<
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function renderMention(pubkey: string, event?: NostrEvent): Promise<MastodonMention> {
|
function renderMention(event: NostrEvent): MastodonMention {
|
||||||
const account = event ? await renderAccount(event) : await accountFromPubkey(pubkey);
|
const account = renderAccount(event);
|
||||||
return {
|
return {
|
||||||
id: account.id,
|
id: account.id,
|
||||||
acct: account.acct,
|
acct: account.acct,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue