diff --git a/src/utils/note.ts b/src/utils/note.ts index 20cb83a..03da2de 100644 --- a/src/utils/note.ts +++ b/src/utils/note.ts @@ -57,6 +57,32 @@ function parseNoteContent(content: string): ParsedNoteContent { }; } +/** Remove imeta links. */ +function stripimeta(content: string, tags: string[][]): string { + const imeta = tags.filter(([name]) => name === 'imeta'); + + if (!imeta.length) { + return content; + } + + const urls = new Set( + imeta.map(([, ...values]) => values.map((v) => v.split(' ')).find(([name]) => name === 'url')?.[1]), + ); + + const lines = content.split('\n').reverse(); + + for (let i = 0; i < lines.length; i++) { + const line = lines[i]; + if (line === '' || urls.has(line)) { + lines.splice(i, 1); + } else { + break; + } + } + + return lines.reverse().join('\n'); +} + /** Returns a matrix of tags. Each item is a list of NIP-94 tags representing a file. */ function getMediaLinks(links: Pick[]): string[][][] { return links.reduce((acc, link) => { @@ -93,4 +119,4 @@ function getDecodedPubkey(decoded: nip19.DecodeResult): string | undefined { } } -export { getMediaLinks, parseNoteContent }; +export { getMediaLinks, parseNoteContent, stripimeta }; diff --git a/src/views/mastodon/statuses.ts b/src/views/mastodon/statuses.ts index c707ebb..a06aac2 100644 --- a/src/views/mastodon/statuses.ts +++ b/src/views/mastodon/statuses.ts @@ -7,7 +7,7 @@ import { type DittoEvent } from '@/interfaces/DittoEvent.ts'; import { Storages } from '@/storages.ts'; import { findReplyTag } from '@/tags.ts'; import { nostrDate } from '@/utils.ts'; -import { getMediaLinks, parseNoteContent } from '@/utils/note.ts'; +import { getMediaLinks, parseNoteContent, stripimeta } from '@/utils/note.ts'; import { unfurlCardCached } from '@/utils/unfurl.ts'; import { accountFromPubkey, renderAccount } from '@/views/mastodon/accounts.ts'; import { renderAttachment } from '@/views/mastodon/attachments.ts'; @@ -46,7 +46,7 @@ async function renderStatus(event: DittoEvent, opts: RenderStatusOpts): Promise< [{ kinds: [0], authors: mentionedPubkeys, limit: mentionedPubkeys.length }], ); - const { html, links, firstUrl } = parseNoteContent(event.content); + const { html, links, firstUrl } = parseNoteContent(stripimeta(event.content, event.tags)); const [mentions, card, relatedEvents] = await Promise .all([