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([