diff options
| author | Dawid Rycerz <dawid@rycerz.xyz> | 2026-01-12 22:27:17 +0100 |
|---|---|---|
| committer | Dawid Rycerz <dawid@rycerz.xyz> | 2026-01-12 22:27:17 +0100 |
| commit | 26ffc44ee72522891b4fdacac15134dfcf9c4859 (patch) | |
| tree | 0a4014f93f35b348f9e5062904e17d724f228a69 /src/loaders/pleroma.ts | |
| parent | 686ccbfd2ed51723f4df79ba0b976e0f5fafce2f (diff) | |
Rework how tags are working and make them native
Diffstat (limited to 'src/loaders/pleroma.ts')
| -rw-r--r-- | src/loaders/pleroma.ts | 52 |
1 files changed, 44 insertions, 8 deletions
diff --git a/src/loaders/pleroma.ts b/src/loaders/pleroma.ts index 0fd839f..975f57e 100644 --- a/src/loaders/pleroma.ts +++ b/src/loaders/pleroma.ts @@ -317,11 +317,9 @@ ${imageAttachments // Join segments with horizontal rule separator let content = segments.join("\n\n---\n\n"); - // Append consolidated tags at the end as markdown links + // Append consolidated tags at the end as plain hashtags if (allTags.size > 0) { - // Get the instance URL from the first post to construct tag URLs - const instanceUrl = chain[0]?.account.url.split("/@")[0] || "https://social.craftknight.com"; - const tagLine = [...allTags].map((t) => `[#${t}](${instanceUrl}/tag/${t})`).join(" "); + const tagLine = [...allTags].map((t) => `#${t}`).join(" "); content = `${content}\n\n${tagLine}`; } @@ -541,6 +539,36 @@ function cleanContent(htmlContent: string): string { } /** + * Replace all hashtags in content with internal tag links + * Handles both plain #hashtags and existing markdown links [#tag](url) + * Returns modified content and extracted tags array + */ +function replaceHashtagsWithLinks(content: string): { + content: string; + tags: string[]; +} { + const tags: string[] = []; + + // First, replace existing markdown hashtag links: [#tag](any-url) + let modifiedContent = content.replace(/\[#(\w+)\]\([^)]+\)/g, (_match, tag) => { + tags.push(tag.toLowerCase()); + return `[#${tag}](/micro/tags/${tag.toLowerCase()})`; + }); + + // Then, replace plain #hashtags (not already in markdown link format) + // Negative lookbehind to avoid matching hashtags already in [#tag] format + modifiedContent = modifiedContent.replace(/(?<!\[)#(\w+)(?!\])/g, (_match, tag) => { + tags.push(tag.toLowerCase()); + return `[#${tag}](/micro/tags/${tag.toLowerCase()})`; + }); + + return { + content: modifiedContent, + tags: [...new Set(tags)], // Deduplicate + }; +} + +/** * Replace Pleroma notice links with internal links when the post exists in our collection * Handles both markdown links and plain URLs */ @@ -654,6 +682,7 @@ export function pleromaLoader(config: PleromaFeedConfig): Loader { let attachments: Array<{ url: string; type: string }>; let postId: string; let sourceUrl: string; + let tags: string[]; // Check if this is a thread starter and thread merging is enabled if (config.mergeThreads !== false && isThreadStarter(content)) { @@ -667,15 +696,21 @@ export function pleromaLoader(config: PleromaFeedConfig): Loader { // Merge thread content const merged = mergeThreadContent(chain); - cleanedContent = merged.content; - cleanedContent = replacePleromaLinks(cleanedContent, instanceUrl, allPostIds); + const { content: contentWithTags, tags: extractedTags } = replaceHashtagsWithLinks( + merged.content, + ); + tags = extractedTags; + cleanedContent = replacePleromaLinks(contentWithTags, instanceUrl, allPostIds); attachments = merged.attachments; postId = status.id; sourceUrl = status.url; } else { // Process as single post - cleanedContent = cleanContent(content); - cleanedContent = replacePleromaLinks(cleanedContent, instanceUrl, allPostIds); + const rawContent = cleanContent(content); + const { content: contentWithTags, tags: extractedTags } = + replaceHashtagsWithLinks(rawContent); + tags = extractedTags; + cleanedContent = replacePleromaLinks(contentWithTags, instanceUrl, allPostIds); postId = status.id; sourceUrl = status.url; @@ -711,6 +746,7 @@ export function pleromaLoader(config: PleromaFeedConfig): Loader { author, attachments, language: status.language || undefined, + tags, }, body: cleanedContent, rendered: { |
