Return properly formatted mentions in Status API

This commit is contained in:
Alex Gleason 2024-08-07 17:27:22 -05:00
parent a24c119c7b
commit 529e61be6d
No known key found for this signature in database
GPG key ID: 7211D1F99744FBB7
2 changed files with 48 additions and 56 deletions

View file

@ -4,12 +4,27 @@ import linkify from 'linkifyjs';
import { nip19, nip21, nip27 } from 'nostr-tools';
import { Conf } from '@/config.ts';
import { MastodonMention } from '@/entities/MastodonMention.ts';
import { getUrlMediaType, isPermittedMediaType } from '@/utils/media.ts';
linkify.registerCustomProtocol('nostr', true);
linkify.registerCustomProtocol('wss');
const linkifyOpts: linkify.Opts = {
type Link = ReturnType<typeof linkify.find>[0];
interface ParsedNoteContent {
html: string;
links: Link[];
/** First non-media URL - eligible for a preview card. */
firstUrl: string | undefined;
}
/** Convert Nostr content to Mastodon API HTML. Also return parsed data. */
function parseNoteContent(content: string, mentions: MastodonMention[]): ParsedNoteContent {
const links = linkify.find(content).filter(isLinkURL);
const firstUrl = links.find(isNonMediaLink)?.href;
const html = linkifyStr(content, {
render: {
hashtag: ({ content }) => {
const tag = content.replace(/^#/, '');
@ -21,8 +36,11 @@ const linkifyOpts: linkify.Opts = {
const { decoded } = nip21.parse(content);
const pubkey = getDecodedPubkey(decoded);
if (pubkey) {
const name = pubkey.substring(0, 8);
const href = Conf.local(`/users/${pubkey}`);
const mention = mentions.find((m) => m.id === pubkey);
const npub = nip19.npubEncode(pubkey);
const acct = mention?.acct ?? npub;
const name = mention?.acct ?? npub.substring(0, 8);
const href = mention?.url ?? Conf.local(`/@${acct}`);
return `<span class="h-card"><a class="u-url mention" href="${href}" rel="ugc">@<span>${name}</span></a></span>`;
} else {
return '';
@ -36,23 +54,7 @@ const linkifyOpts: linkify.Opts = {
}
},
},
};
type Link = ReturnType<typeof linkify.find>[0];
interface ParsedNoteContent {
html: string;
links: Link[];
/** First non-media URL - eligible for a preview card. */
firstUrl: string | undefined;
}
/** Convert Nostr content to Mastodon API HTML. Also return parsed data. */
function parseNoteContent(content: string): ParsedNoteContent {
// Parsing twice is ineffecient, but I don't know how to do only once.
const html = linkifyStr(content, linkifyOpts).replace(/\n+$/, '');
const links = linkify.find(content).filter(isLinkURL);
const firstUrl = links.find(isNonMediaLink)?.href;
}).replace(/\n+$/, '');
return {
html,

View file

@ -46,13 +46,14 @@ async function renderStatus(event: DittoEvent, opts: RenderStatusOpts): Promise<
[{ kinds: [0], authors: mentionedPubkeys, limit: mentionedPubkeys.length }],
);
const { html, links, firstUrl } = parseNoteContent(stripimeta(event.content, event.tags));
const mentions = await Promise.all(
mentionedPubkeys.map((pubkey) => renderMention(pubkey, mentionedProfiles.find((event) => event.pubkey === pubkey))),
);
const [mentions, card, relatedEvents] = await Promise
const { html, links, firstUrl } = parseNoteContent(stripimeta(event.content, event.tags), mentions);
const [card, relatedEvents] = await Promise
.all([
Promise.all(
mentionedPubkeys.map((pubkey) => toMention(pubkey, mentionedProfiles.find((event) => event.pubkey === pubkey))),
),
firstUrl ? unfurlCardCached(firstUrl) : null,
viewerPubkey
? await store.query([
@ -152,25 +153,14 @@ async function renderReblog(event: DittoEvent, opts: RenderStatusOpts): Promise<
};
}
async function toMention(pubkey: string, event?: NostrEvent): Promise<MastodonMention> {
const account = event ? await renderAccount(event) : undefined;
if (account) {
async function renderMention(pubkey: string, event?: NostrEvent): Promise<MastodonMention> {
const account = event ? await renderAccount(event) : await accountFromPubkey(pubkey);
return {
id: account.id,
acct: account.acct,
username: account.username,
url: account.url,
};
} else {
const npub = nip19.npubEncode(pubkey);
return {
id: pubkey,
acct: npub,
username: npub.substring(0, 8),
url: Conf.local(`/users/${pubkey}`),
};
}
}
function buildInlineRecipients(mentions: MastodonMention[]): string {