diff options
| author | Dawid Rycerz <dawid@rycerz.xyz> | 2026-01-13 17:13:43 +0100 |
|---|---|---|
| committer | Dawid Rycerz <dawid@rycerz.xyz> | 2026-01-13 17:20:15 +0100 |
| commit | 9fe4480c3981c38ae8e24d0495df957039864a5d (patch) | |
| tree | a5f3e4f8c0732c8cd934c28596c6a4d0ab38a4b4 /src | |
| parent | c0dcecc43e36eeb6b10f662c1be760736cd0dbac (diff) | |
Remove micro and migrate to use only posts
Diffstat (limited to 'src')
29 files changed, 158 insertions, 352 deletions
diff --git a/src/components/BaseHead.astro b/src/components/BaseHead.astro index 40f1d20..14286c3 100644 --- a/src/components/BaseHead.astro +++ b/src/components/BaseHead.astro @@ -95,7 +95,6 @@ const ogLocale = getOgLocale(lang); {/* RSS auto-discovery */} <link href="/rss.xml" title="Blog" rel="alternate" type="application/rss+xml" /> -<link href="/micro/rss.xml" title="Micro" rel="alternate" type="application/rss+xml" /> {/* Webmentions */} { diff --git a/src/components/note/Note.astro b/src/components/note/Note.astro deleted file mode 100644 index 920cbc1..0000000 --- a/src/components/note/Note.astro +++ /dev/null @@ -1,86 +0,0 @@ ---- -import { type CollectionEntry, render } from "astro:content"; -import type { HTMLTag, Polymorphic } from "astro/types"; -import FormattedDate from "@/components/FormattedDate.astro"; - -type Props<Tag extends HTMLTag> = Polymorphic<{ as: Tag }> & { - note: CollectionEntry<"micro">; - isPreview?: boolean | undefined; -}; - -const { as: Tag = "div", note, isPreview = false } = Astro.props; -const { Content } = await render(note); ---- - -<article - class:list={[ - isPreview && "inline-grid rounded-md bg-[rgb(240,240,240)] px-4 py-3 dark:bg-[rgb(33,35,38)]", - ]} - data-pagefind-body={isPreview ? false : true} -> - <Tag class="title" class:list={{ "text-base": isPreview }}> - { - isPreview ? ( - <a class="cactus-link" href={`/micro/${note.id}/`}> - {note.data.title} - </a> - ) : ( - <>{note.data.title}</> - ) - } - </Tag> - <FormattedDate - dateTimeOptions={{ - hour: "2-digit", - minute: "2-digit", - year: "2-digit", - month: "2-digit", - day: "2-digit", - }} - date={note.data.publishDate} - /> - <div - class="prose prose-sm prose-cactus mt-4 max-w-none [&>p:last-of-type]:mb-0" - class:list={{ "line-clamp-6": isPreview }} - > - <Content /> - { - !isPreview && note.data.attachments && note.data.attachments.length > 0 && ( - <div class="mt-6 grid grid-cols-1 gap-4 sm:grid-cols-2"> - {note.data.attachments.map((attachment: { type: string; url: string; alt?: string }) => ( - <a - href={attachment.url} - target="_blank" - rel="noopener noreferrer" - class="block overflow-hidden rounded-lg border border-gray-200 transition-colors hover:border-gray-300 dark:border-gray-700 dark:hover:border-gray-600" - > - <img - src={attachment.url} - alt={attachment.alt || "Image"} - class="h-48 w-full object-cover" - loading="lazy" - /> - </a> - ))} - </div> - ) - } - { - !isPreview && note.data.sourceUrl && ( - <> - <hr class="mt-6 mb-4 border-t border-gray-300 dark:border-gray-600" /> - <p class="text-sm text-gray-600 dark:text-gray-400"> - <a - href={note.data.sourceUrl} - class="cactus-link" - target="_blank" - rel="noopener noreferrer" - > - View original post → - </a> - </p> - </> - ) - } - </div> -</article> diff --git a/src/content.config.ts b/src/content.config.ts index a9fa0e2..5b5836b 100644 --- a/src/content.config.ts +++ b/src/content.config.ts @@ -35,10 +35,12 @@ const post = defineCollection({ .optional() .transform((str) => (str ? new Date(str) : undefined)), language: z.string().optional(), + sourceUrl: z.string().optional(), + author: z.string().optional(), }), }); -const micro = defineCollection({ +const pleroma = defineCollection({ loader: pleromaLoader({ instanceUrl: "https://social.craftknight.com", username: "dawid", @@ -51,23 +53,8 @@ const micro = defineCollection({ sourceUrl: z.string().optional(), language: z.string().optional(), tags: z.array(z.string()).default([]).transform(removeDupsAndLowerCase), - author: z - .object({ - username: z.string(), - displayName: z.string().optional(), - acct: z.string(), - url: z.string().optional(), - }) - .optional(), - attachments: z - .array( - z.object({ - url: z.string(), - type: z.string(), - alt: z.string().optional(), - }), - ) - .optional(), + draft: z.boolean().default(false), + author: z.string().optional(), }), }); @@ -79,4 +66,4 @@ const tag = defineCollection({ }), }); -export const collections = { post, tag, micro }; +export const collections = { post, tag, pleroma }; diff --git a/src/content/post/devops-mindset.md b/src/content/post/devops-mindset.md index 166d282..7761cc3 100644 --- a/src/content/post/devops-mindset.md +++ b/src/content/post/devops-mindset.md @@ -4,6 +4,7 @@ description: "DevOps - culture, mindset and processes" publishDate: "3 July 2025" tags: ["devops101", devops] draft: false +author: "Dawid" --- ## DevOps Mindset diff --git a/src/content/post/fediverse-101.md b/src/content/post/fediverse-101.md index 6c248b9..595606b 100644 --- a/src/content/post/fediverse-101.md +++ b/src/content/post/fediverse-101.md @@ -4,6 +4,7 @@ description: "A short collection of resources and links for getting started with publishDate: 19 Dec 2025 tags: [fediverse, social] draft: false +author: "Dawid" --- ## Fediverse 101 diff --git a/src/content/post/niedziela-11-wrzesnia-2022.md b/src/content/post/niedziela-11-wrzesnia-2022.md index 6f5a31a..3f47dec 100644 --- a/src/content/post/niedziela-11-wrzesnia-2022.md +++ b/src/content/post/niedziela-11-wrzesnia-2022.md @@ -3,6 +3,7 @@ title: "Niedziela 11 września 2022" description: "Weekend minął jak z bicza strzelił. Zdecydowanie nie był to jeden z tych leniwych weekendów. W sobotę rano poznaliśmy przemiłą starszą parę z Polski." publishDate: "2022-09-11" tags: ["archived"] +author: "Dawid" --- Weekend minął „jak z bicza strzelił". Zdecydowanie nie był to jeden z tych leniwych weekendów. diff --git a/src/content/post/piatek-16-wrzesnia-2022.md b/src/content/post/piatek-16-wrzesnia-2022.md index b6a46a2..104f737 100644 --- a/src/content/post/piatek-16-wrzesnia-2022.md +++ b/src/content/post/piatek-16-wrzesnia-2022.md @@ -3,6 +3,7 @@ title: "Piątek 16 września 2022" description: "Ostatnie dni były wyjątkowo ciepłe. Pogoda sprzyjała plażowaniu, więc po pracy dołączałem do Aleksandry. Mieliśmy swoją miejscówkę koło nadmorskiego baru, który był niestety zamknięty po sezonie." publishDate: "2022-09-16" tags: ["archived"] +author: "Dawid" --- Ostatnie dni były wyjątkowo ciepłe. Pogoda sprzyjała plażowaniu, więc po pracy dołączałem do Aleksandry. Mieliśmy swoją miejscówkę koło nadmorskiego baru, który był niestety zamknięty po sezonie. Rumuńskie plaże całe są w muszelkach. Większe i jeszcze ostre muszle są bliżej wody, natomiast mniejsze kawałki – już pokruszone – tworzą specyficzny "piasek". diff --git a/src/content/post/piatek-7-pazdziernika-2022.md b/src/content/post/piatek-7-pazdziernika-2022.md index 72819db..d278fd3 100644 --- a/src/content/post/piatek-7-pazdziernika-2022.md +++ b/src/content/post/piatek-7-pazdziernika-2022.md @@ -3,6 +3,7 @@ title: "Piątek 7 października 2022" description: "Dotarłem na jedno z najbardziej epickich miejsc, w których zdarzyło nam się spać. Wysokie klify, rozległa polana, ogromne przestrzenie i tylko wypasające się konie, owce i kozy." publishDate: "2022-10-07" tags: ["archived"] +author: "Dawid" --- Dotarłem na jedno z najbardziej epickich miejsc, w których zdarzyło nam się spać. Wysokie klify, rozległa polana, ogromne przestrzenie i tylko wypasające się konie, owce i kozy. Nocą na horyzoncie widać światła Ahtopola, ale poza nimi tylko Księżyc i Jowisz rozświetla okolicę. Nad samą przepaścią ktoś wystawił stolik, krzesło i dalej ławkę, na których co kilka godzin ktoś przyjeżdża zrobić sobie zdjęcia. diff --git a/src/content/post/piatek-9-wrzesnia-2022.md b/src/content/post/piatek-9-wrzesnia-2022.md index 005a673..2ccd517 100644 --- a/src/content/post/piatek-9-wrzesnia-2022.md +++ b/src/content/post/piatek-9-wrzesnia-2022.md @@ -3,6 +3,7 @@ title: "Piątek 9 września 2022" description: "Ostatnie dni miałem bardzo zawalone w pracy. Dużo spotkań, przygotowywania prezentacji, prowadzenie treningów – w sumie poza siedzeniem w laptopie niewiele się wydarzyło." publishDate: "2022-09-09" tags: ["archived"] +author: "Dawid" --- Ostatnie dni miałem bardzo zawalone w pracy. Dużo spotkań, przygotowywania prezentacji, prowadzenie treningów – w sumie poza siedzeniem w laptopie niewiele się wydarzyło. Wiatr za to tak zaczął doskwierać, że musieliśmy zwinąć markizę i prawie całe dwa dni spędziłem w kamperze. Przynajmniej Freja przestała nam plątać się we wsporniki i linki 🙂 diff --git a/src/content/post/poniedzialek-3-pazdziernika-2022.md b/src/content/post/poniedzialek-3-pazdziernika-2022.md index 9ac4688..f4088ed 100644 --- a/src/content/post/poniedzialek-3-pazdziernika-2022.md +++ b/src/content/post/poniedzialek-3-pazdziernika-2022.md @@ -3,6 +3,7 @@ title: "Poniedziałek 3 października 2022" description: "W czwartek rano już się upewniłem, że na skarpie zaparkował Groszek – zielony VW T4 który należy do kampermaniaków. Skończyło mi się wolne, więc szybko tylko poszedłem z Freją po banice do ajranu..." publishDate: "2022-10-03" tags: ["archived"] +author: "Dawid" --- W czwartek rano już się upewniłem, że na skarpie zaparkował Groszek – zielony VW T4 który należy do [kampermaniaków](https://kampermaniak.pl). Skończyło mi się wolne, więc szybko tylko poszedłem z Freją po banice do ajranu, rozłożyłem "biuro" i zacząłem normalny dzień pracy. Jak to ja – nawet na popołudniowym spacerze nie zebrałem się, żeby zagadać, a wieczorem już widziałem, że wszyscy siedzieli i nie chciałem przeszkadzać. diff --git a/src/content/post/poniedzialek-5-wrzesnia-2022.md b/src/content/post/poniedzialek-5-wrzesnia-2022.md index d3456c0..369f091 100644 --- a/src/content/post/poniedzialek-5-wrzesnia-2022.md +++ b/src/content/post/poniedzialek-5-wrzesnia-2022.md @@ -3,6 +3,7 @@ title: "Poniedziałek 5 września 2022" description: "Postanowiliśmy zostać tutaj na dłużej. Miejsce do którego dojechaliśmy okazało się być plażą pełną przyczep kempingowych i kamperów. Mamy widok z okna na morze, szybki internet, dużo słońca (prądu) oraz proste podłoże." publishDate: "2022-09-05" tags: ["archived"] +author: "Dawid" --- Postanowiliśmy zostać tutaj na dłużej. Miejsce do którego dojechaliśmy okazało się być plażą pełną przyczep kempingowych i kamperów. Mamy widok z okna na morze, szybki internet, dużo słońca (prądu) oraz proste podłoże. Chyba gdzieś w okolicy jest źródło wody (przynajmniej na to wygląda sądząc po ludziach noszących butelki). diff --git a/src/content/post/sobota-3-wrzesnia-2022.md b/src/content/post/sobota-3-wrzesnia-2022.md index a77cdb4..0aeb464 100644 --- a/src/content/post/sobota-3-wrzesnia-2022.md +++ b/src/content/post/sobota-3-wrzesnia-2022.md @@ -3,6 +3,7 @@ title: "Sobota 3 września 2022" description: "Dzień wyjazdu z Bukaresztu i ogarniania auta po tygodniu w wynajętym mieszkaniu. Wodę pozwolili nam nalać na stacji po tankowaniu auta, kasete zlaliśmy na parkingu dla kamperów, a po drodze kupiliśmy jeszcze karmę dla Freji." publishDate: "2022-09-03" tags: ["archived"] +author: "Dawid" --- Dzień wyjazdu z Bukaresztu i ogarniania auta po tygodniu w wynajętym mieszkaniu. Wodę pozwolili nam nalać na stacji po tankowaniu auta, kasete zlaliśmy na parkingu dla kamperów, a po drodze kupiliśmy jeszcze karmę dla Freji. diff --git a/src/content/post/sroda-21-wrzesnia-2022.md b/src/content/post/sroda-21-wrzesnia-2022.md index ae2665a..1ff94b5 100644 --- a/src/content/post/sroda-21-wrzesnia-2022.md +++ b/src/content/post/sroda-21-wrzesnia-2022.md @@ -3,6 +3,7 @@ title: "Środa 21 września 2022" description: "W pierwszych dniach pobytu w Bułgarii mieliśmy nieco szczęścia. Warna przywitała nas burzą i oberwaniem chmury. W trakcie spaceru po mieście zerwał się deszcz i przemokliśmy do suchej nitki w przeciągu kilku minut." publishDate: "2022-09-21" tags: ["archived"] +author: "Dawid" --- W pierwszych dniach pobytu w Bułgarii mieliśmy nieco szczęścia. Warna przywitała nas burzą i oberwaniem chmury. W trakcie spaceru po mieście zerwał się deszcz i przemokliśmy do suchej nitki w przeciągu kilku minut. W tym samym czasie, kilkadziesiąt kilometrów na południe, przez Brugas przeszedł huragan który zrywał dachy i łamał drzewa. Dobrze, że zamarudziliśmy trochę i zwiedziliśmy jeszcze po drodze kamienny las. diff --git a/src/content/post/sroda-28-wrzesnia-2022.md b/src/content/post/sroda-28-wrzesnia-2022.md index 884ec2f..e0a456b 100644 --- a/src/content/post/sroda-28-wrzesnia-2022.md +++ b/src/content/post/sroda-28-wrzesnia-2022.md @@ -3,6 +3,7 @@ title: "Środa 28 września 2022" description: "Wziąłem parę dni wolnego, abyśmy mogli spokojnie pozwiedzać okolicę. Zaczęliśmy od oddania rzeczy do pralni. Niestety w Bułgarii pralki na monety nie są popularne." publishDate: "2022-09-28" tags: ["archived"] +author: "Dawid" --- ## Nesebar diff --git a/src/content/post/sroda-7-wrzesnia-2022.md b/src/content/post/sroda-7-wrzesnia-2022.md index 2b70da1..50b2e13 100644 --- a/src/content/post/sroda-7-wrzesnia-2022.md +++ b/src/content/post/sroda-7-wrzesnia-2022.md @@ -3,6 +3,7 @@ title: "Środa 7 września 2022" description: "Musieliśmy się dzisiaj ruszyć po wodę. Źródełko płynące z rury koło domku rybaka okazało się na tyle brudne, że nie ryzykowaliśmy zalewać nim zbiornika w kamperze." publishDate: "2022-09-07" tags: ["archived"] +author: "Dawid" --- Musieliśmy się dzisiaj ruszyć po wodę. Źródełko płynące z rury koło domku rybaka okazało się na tyle brudne, że nie ryzykowaliśmy zalewać nim zbiornika w kamperze. Może i dało by się w nim wykąpać, ale bez wstępnej filtracji tylko by zasyfiło pompę, przewody i krany. Przy okazji zrobiliśmy zakupy w lokalnym Lidlu i umyliśmy auto (było całe od błota po sobotnich "przygodach"). diff --git a/src/content/post/wtorek-13-wrzesnia-2022.md b/src/content/post/wtorek-13-wrzesnia-2022.md index 4023696..09dacc1 100644 --- a/src/content/post/wtorek-13-wrzesnia-2022.md +++ b/src/content/post/wtorek-13-wrzesnia-2022.md @@ -3,6 +3,7 @@ title: "Wtorek 13 września 2022" description: "Przez jeden dzień mieliśmy nowe zwierzątko – konkretnie nietoperza. W poniedziałek nad ranem coś wpadło pomiędzy moskitierę, a okno dachowe i strasznie hałasowało." publishDate: "2022-09-13" tags: ["archived"] +author: "Dawid" --- Przez jeden dzień mieliśmy nowe zwierzątko – konkretnie nietoperza. W poniedziałek nad ranem coś wpadło pomiędzy moskitierę, a okno dachowe i strasznie hałasowało. Na początku myśleliśmy, że to mały ptak lub ćma, ale kiedy próbowałem uchylić trochę bardziej okno, to "coś" zatrzymało się na moskitierze. Nietoperz wcisnął się w szczelinę pomiędzy dachem Sprintera, a drewnianym sufitem i poszedł spać na cały dzień. Swoją drogą tak dowiedzieliśmy się, że jest tam przejście znad moskitiery pod dach i trzeba się tym zająć. diff --git a/src/data/post.ts b/src/data/post.ts index 7cadb93..85cc0d0 100644 --- a/src/data/post.ts +++ b/src/data/post.ts @@ -1,16 +1,18 @@ import { type CollectionEntry, getCollection } from "astro:content"; -/** filter out draft posts based on the environment and optionally archived posts and micro posts */ -export async function getAllPosts( - includeArchived = false, - includeMicro = false, -): Promise<CollectionEntry<"post">[]> { - return await getCollection("post", ({ data }) => { +/** filter out draft posts based on the environment and optionally archived posts */ +export async function getAllPosts(includeArchived = false): Promise<CollectionEntry<"post">[]> { + const posts = await getCollection("post", ({ data }) => { const isDraftFilter = import.meta.env.PROD ? !data.draft : true; const isArchivedFilter = includeArchived || !data.tags.includes("archived"); - const isMicroFilter = includeMicro || !data.tags.includes("micro"); - return isDraftFilter && isArchivedFilter && isMicroFilter; + return isDraftFilter && isArchivedFilter; }); + + // Fetch pleroma posts and cast them to post type since schemas are now compatible + const pleromaPosts = await getCollection("pleroma").catch(() => []); + const pleromaAsPost = pleromaPosts as unknown as CollectionEntry<"post">[]; + + return [...posts, ...pleromaAsPost]; } /** Get tag metadata by tag name */ diff --git a/src/layouts/BlogPost.astro b/src/layouts/BlogPost.astro index 9c60900..59f7282 100644 --- a/src/layouts/BlogPost.astro +++ b/src/layouts/BlogPost.astro @@ -33,6 +33,20 @@ const readingTime: string = remarkPluginFrontmatter.readingTime; > <slot /> <WebMentions /> + { + post.data.sourceUrl && ( + <p class="mt-8 border-t border-gray-200 pt-6 text-sm dark:border-gray-700"> + <a + href={post.data.sourceUrl} + class="cactus-link" + target="_blank" + rel="noopener noreferrer" + > + View original post on Pleroma → + </a> + </p> + ) + } </div> </article> <button diff --git a/src/loaders/pleroma.ts b/src/loaders/pleroma.ts index c57a22b..b3fa8ff 100644 --- a/src/loaders/pleroma.ts +++ b/src/loaders/pleroma.ts @@ -265,12 +265,8 @@ function extractTrailingHashtags(content: string): { /** * Merge thread posts into a single content structure with image grids per segment */ -function mergeThreadContent(chain: PleromaStatus[]): { - content: string; - attachments: Array<{ url: string; type: string }>; -} { +function mergeThreadContent(chain: PleromaStatus[]): string { const segments: string[] = []; - const allAttachments: Array<{ url: string; type: string }> = []; const allTags = new Set<string>(); // Collect all tags from all segments for (const post of chain) { @@ -286,28 +282,9 @@ function mergeThreadContent(chain: PleromaStatus[]): { let segment = mainContent; // Add image attachments as HTML grid after the text - const imageAttachments = post.media_attachments.filter( - (attachment) => attachment.type === "image", - ); - - if (imageAttachments.length > 0) { - // Build HTML grid for images - const imageGrid = ` -<div class="mt-4 mb-4 grid grid-cols-1 gap-4 sm:grid-cols-2"> -${imageAttachments - .map((attachment) => { - const description = attachment.description || "Image"; - allAttachments.push({ - url: attachment.url, - type: `image/${attachment.url.split(".").pop() || "jpeg"}`, - }); - return `<a href="${attachment.url}" target="_blank" rel="noopener noreferrer" class="block overflow-hidden rounded-lg border border-gray-200 transition-colors hover:border-gray-300 dark:border-gray-700 dark:hover:border-gray-600"> -<img src="${attachment.url}" alt="${description}" class="h-48 w-full object-cover" loading="lazy" /> -</a>`; - }) - .join("\n")} -</div>`; + const imageGrid = buildImageGridHtml(post.media_attachments); + if (imageGrid) { segment = `${segment}\n\n${imageGrid}`; } @@ -323,7 +300,7 @@ ${imageAttachments content = `${content}\n\n${tagLine}`; } - return { content, attachments: [] }; // Return empty attachments to avoid duplicate grid at end + return content; } async function getAccountId( @@ -539,6 +516,30 @@ function cleanContent(htmlContent: string): string { } /** + * Build HTML grid for image attachments + * Returns empty string if no image attachments are provided + */ +function buildImageGridHtml(attachments: PleromaMediaAttachment[]): string { + const imageAttachments = attachments.filter((attachment) => attachment.type === "image"); + + if (imageAttachments.length === 0) { + return ""; + } + + return ` +<div class="mt-4 mb-4 grid grid-cols-1 gap-4 sm:grid-cols-2"> +${imageAttachments + .map((attachment) => { + const description = attachment.description || "Image"; + return `<a href="${attachment.url}" target="_blank" rel="noopener noreferrer" class="block overflow-hidden rounded-lg border border-gray-200 transition-colors hover:border-gray-300 dark:border-gray-700 dark:hover:border-gray-600"> +<img src="${attachment.url}" alt="${description}" class="h-48 w-full object-cover" loading="lazy" /> +</a>`; + }) + .join("\n")} +</div>`; +} + +/** * 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 @@ -587,7 +588,7 @@ function replacePleromaLinks( const markdownLinkRegex = new RegExp(`\\[([^\\]]+)\\]\\(${noticePattern}\\)`, "g"); let modifiedContent = content.replace(markdownLinkRegex, (match, linkText, statusId) => { if (existingPostIds.has(statusId)) { - return `[${linkText}](/micro/pleroma-${statusId}/)`; + return `[${linkText}](/posts/pleroma-${statusId}/)`; } return match; // Keep original if post doesn't exist }); @@ -597,7 +598,7 @@ function replacePleromaLinks( const plainUrlRegex = new RegExp(`(?<!\\()${noticePattern}(?!\\))`, "g"); modifiedContent = modifiedContent.replace(plainUrlRegex, (match, statusId) => { if (existingPostIds.has(statusId)) { - return `/micro/pleroma-${statusId}/`; + return `/posts/pleroma-${statusId}/`; } return match; // Keep original if post doesn't exist }); @@ -679,7 +680,6 @@ export function pleromaLoader(config: PleromaFeedConfig): Loader { try { const content = status.content || ""; let cleanedContent: string; - let attachments: Array<{ url: string; type: string }>; let postId: string; let sourceUrl: string; let tags: string[]; @@ -695,13 +695,14 @@ export function pleromaLoader(config: PleromaFeedConfig): Loader { logger.info(`Built chain with ${chain.length} post(s) for thread ${status.id}`); // Merge thread content - const merged = mergeThreadContent(chain); - const { content: contentWithTags, tags: extractedTags } = replaceHashtagsWithLinks( - merged.content, - ); - tags = [...extractedTags, "micro"]; + const mergedContent = mergeThreadContent(chain); + const { content: contentWithTags, tags: extractedTags } = + replaceHashtagsWithLinks(mergedContent); + // Add microblog tag if not already present + tags = extractedTags.includes("microblog") + ? extractedTags + : [...extractedTags, "microblog"]; cleanedContent = replacePleromaLinks(contentWithTags, instanceUrl, allPostIds); - attachments = merged.attachments; postId = status.id; sourceUrl = status.url; } else { @@ -709,31 +710,26 @@ export function pleromaLoader(config: PleromaFeedConfig): Loader { const rawContent = cleanContent(content); const { content: contentWithTags, tags: extractedTags } = replaceHashtagsWithLinks(rawContent); - tags = [...extractedTags, "micro"]; - cleanedContent = replacePleromaLinks(contentWithTags, instanceUrl, allPostIds); + // Add microblog tag if not already present + tags = extractedTags.includes("microblog") + ? extractedTags + : [...extractedTags, "microblog"]; + const contentWithLinks = replacePleromaLinks( + contentWithTags, + instanceUrl, + allPostIds, + ); + + // Build image grid HTML and append to content for RSS feeds + const imageGrid = buildImageGridHtml(status.media_attachments); + cleanedContent = imageGrid ? `${contentWithLinks}\n\n${imageGrid}` : contentWithLinks; + postId = status.id; sourceUrl = status.url; - - // Extract image attachments only - attachments = status.media_attachments - .filter((attachment) => attachment.type === "image") - .map((attachment) => ({ - url: attachment.url, - type: `image/${attachment.url.split(".").pop() || "jpeg"}`, - alt: attachment.description || undefined, - })); } const title = extractTitle(cleanedContent); - // Extract author information from status account - const author = { - username: status.account.username, - displayName: status.account.display_name || undefined, - acct: status.account.acct, - url: status.account.url || undefined, - }; - // Create note entry store.set({ id: `pleroma-${postId}`, @@ -743,10 +739,10 @@ export function pleromaLoader(config: PleromaFeedConfig): Loader { cleanedContent.substring(0, 160) + (cleanedContent.length > 160 ? "..." : ""), publishDate: new Date(status.created_at), sourceUrl, - author, - attachments, language: status.language || undefined, tags, + draft: false, + author: "Dawid", }, body: cleanedContent, rendered: { diff --git a/src/pages/index.astro b/src/pages/index.astro index 1bc088c..e3884ef 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,23 +1,27 @@ --- -import { type CollectionEntry, getCollection } from "astro:content"; +import type { CollectionEntry } from "astro:content"; import PostPreview from "@/components/blog/PostPreview.astro"; -import Note from "@/components/note/Note.astro"; import SocialList from "@/components/SocialList.astro"; import { getAllPosts } from "@/data/post"; import PageLayout from "@/layouts/Base.astro"; import { collectionDateSort } from "@/utils/date"; -// Posts -const MAX_POSTS = 10; +// Get all posts const allPosts = await getAllPosts(); -const allPostsByDate = allPosts + +// Posts section - exclude archived and microblog +const MAX_POSTS = 10; +const regularPosts = allPosts.filter( + (post) => !post.data.tags.includes("archived") && !post.data.tags.includes("microblog"), +); +const allPostsByDate = regularPosts .sort(collectionDateSort) .slice(0, MAX_POSTS) as CollectionEntry<"post">[]; -// Micro -const MAX_MICRO = 5; -const allMicro = await getCollection("micro").catch(() => []); // Fallback to empty array if micro collection fails -const latestMicro = allMicro.sort(collectionDateSort).slice(0, MAX_MICRO); +// Microblog posts section - only posts with microblog tag +const MAX_MICROBLOG = 5; +const allMicroblogPosts = allPosts.filter((post) => post.data.tags.includes("microblog")); +const latestMicroblog = allMicroblogPosts.sort(collectionDateSort).slice(0, MAX_MICROBLOG); --- <PageLayout meta={{ title: "Home" }}> @@ -46,15 +50,15 @@ const latestMicro = allMicro.sort(collectionDateSort).slice(0, MAX_MICRO); </ul> </section> { - latestMicro.length > 0 && ( + latestMicroblog.length > 0 && ( <section class="mt-16"> <h2 class="title text-accent mb-6 text-xl"> - <a href="/tags/micro/">Micro</a> + <a href="/tags/microblog/">Microblog</a> </h2> <ul class="space-y-6" role="list"> - {latestMicro.map((note) => ( - <li> - <Note note={note} as="h3" isPreview /> + {latestMicroblog.map((post) => ( + <li class="grid gap-2 sm:grid-cols-[auto_1fr]"> + <PostPreview post={post} as="h3" /> </li> ))} </ul> diff --git a/src/pages/micro/[...slug].astro b/src/pages/micro/[...slug].astro deleted file mode 100644 index 681c106..0000000 --- a/src/pages/micro/[...slug].astro +++ /dev/null @@ -1,34 +0,0 @@ ---- -import { getCollection } from "astro:content"; -import type { GetStaticPaths, InferGetStaticPropsType } from "astro"; -import Note from "@/components/note/Note.astro"; -import PageLayout from "@/layouts/Base.astro"; -import { siteConfig } from "@/site.config"; - -// if you're using an adaptor in SSR mode, getStaticPaths wont work -> https://docs.astro.build/en/guides/routing/#modifying-the-slug-example-for-ssr -export const getStaticPaths = (async () => { - // Get only Pleroma posts - const allMicro = await getCollection("micro").catch(() => []); // Fallback to empty array if micro collection fails - - return allMicro.map((post) => ({ - params: { slug: post.id }, - props: { note: post }, // Keep 'note' name for compatibility with existing component - })); -}) satisfies GetStaticPaths; - -export type Props = InferGetStaticPropsType<typeof getStaticPaths>; - -const { note } = Astro.props; - -const meta = { - description: - note.data.description || - `Read about my note posted on: ${note.data.publishDate.toLocaleDateString()}`, - title: note.data.title, - lang: note.data.language || siteConfig.lang, -}; ---- - -<PageLayout meta={meta}> - <Note as="h1" note={note} /> -</PageLayout> diff --git a/src/pages/posts/[...page].astro b/src/pages/posts/[...page].astro index acca040..d318525 100644 --- a/src/pages/posts/[...page].astro +++ b/src/pages/posts/[...page].astro @@ -12,7 +12,11 @@ export const getStaticPaths = (async ({ paginate }) => { const MAX_POSTS_PER_PAGE = 10; const MAX_TAGS = 7; const allPosts = await getAllPosts(); - const sortedPosts = allPosts.sort(collectionDateSort); + // Filter out archived and microblog posts from main posts page + const filteredPosts = allPosts.filter( + (post) => !post.data.tags.includes("archived") && !post.data.tags.includes("microblog"), + ); + const sortedPosts = filteredPosts.sort(collectionDateSort); const uniqueTags = getUniqueTags(sortedPosts).slice(0, MAX_TAGS); return paginate(sortedPosts, { pageSize: MAX_POSTS_PER_PAGE, diff --git a/src/pages/rss.xml.ts b/src/pages/rss.xml.ts index 39f3964..d428cc9 100644 --- a/src/pages/rss.xml.ts +++ b/src/pages/rss.xml.ts @@ -15,6 +15,7 @@ export const GET = async (context: APIContext) => { description: post.data.description, pubDate: post.data.publishDate, link: `posts/${post.id}/`, + author: post.data.author, })), customData: `<atom:link href="${context.site}rss.xml" rel="self" type="application/rss+xml" xmlns:atom="http://www.w3.org/2005/Atom" />`, }); diff --git a/src/pages/tags/[tag]/[...page].astro b/src/pages/tags/[tag]/[...page].astro index 9556309..8ae9716 100644 --- a/src/pages/tags/[tag]/[...page].astro +++ b/src/pages/tags/[tag]/[...page].astro @@ -1,35 +1,27 @@ --- -import { getCollection, render } from "astro:content"; +import { render } from "astro:content"; import type { GetStaticPaths, InferGetStaticPropsType } from "astro"; import { Icon } from "astro-icon/components"; import PostPreview from "@/components/blog/PostPreview.astro"; -import Note from "@/components/note/Note.astro"; import Pagination from "@/components/Paginator.astro"; import { getAllPosts, getTagMeta, getUniqueTags } from "@/data/post"; import PageLayout from "@/layouts/Base.astro"; import { collectionDateSort } from "@/utils/date"; -import { getUniqueMicroTags } from "@/utils/micro"; export const getStaticPaths = (async ({ paginate }) => { - const allPosts = await getAllPosts(true, true); // Include archived and micro posts for tag filtering - const allMicro = await getCollection("micro", ({ data }) => data.tags?.includes("micro")).catch( - () => [], - ); + const allPosts = await getAllPosts(true); // Include archived posts (now includes pleroma too) - // Get unique tags from both collections - const postTags = getUniqueTags(allPosts); - const microTags = getUniqueMicroTags(allMicro); - const allTags = [...new Set([...postTags, ...microTags])]; + // Get unique tags from all posts + const allTags = getUniqueTags(allPosts); return allTags.flatMap((tag) => { - // Filter posts and micro posts by tag + // Filter posts by tag const postsWithTag = allPosts.filter((post) => post.data.tags.includes(tag)); - const microWithTag = allMicro.filter((micro) => micro.data.tags?.includes(tag)); - // Combine and sort chronologically - const allItems = [...postsWithTag, ...microWithTag].sort(collectionDateSort); + // Sort chronologically + const sortedPosts = postsWithTag.sort(collectionDateSort); - return paginate(allItems, { + return paginate(sortedPosts, { pageSize: 10, params: { tag }, }); @@ -55,13 +47,13 @@ const meta = { const paginationProps = { ...(page.url.prev && { prevUrl: { - text: "← Previous Tags", + text: "← Previous posts", url: page.url.prev, }, }), ...(page.url.next && { nextUrl: { - text: "Next Tags →", + text: "Next posts →", url: page.url.next, }, }), @@ -96,17 +88,11 @@ const paginationProps = { </div> <ul class="space-y-6"> { - page.data.map((item) => - item.collection === "post" ? ( - <li class="grid gap-2 sm:grid-cols-[auto_1fr]"> - <PostPreview as="h2" post={item} /> - </li> - ) : ( - <li> - <Note note={item} as="h2" isPreview /> - </li> - ), - ) + page.data.map((post) => ( + <li class="grid gap-2 sm:grid-cols-[auto_1fr]"> + <PostPreview as="h2" post={post} /> + </li> + )) } </ul> <Pagination {...paginationProps} /> diff --git a/src/pages/tags/[tag]/rss.xml.ts b/src/pages/tags/[tag]/rss.xml.ts index 3fc8ff3..3a61414 100644 --- a/src/pages/tags/[tag]/rss.xml.ts +++ b/src/pages/tags/[tag]/rss.xml.ts @@ -1,21 +1,14 @@ -import { getCollection } from "astro:content"; import rss from "@astrojs/rss"; import type { APIContext } from "astro"; import { getAllPosts, getUniqueTags } from "@/data/post"; import { siteConfig } from "@/site.config"; -import { getUniqueMicroTags } from "@/utils/micro"; export async function getStaticPaths() { - // Get all posts (including archived) and micro posts to extract all possible tags - const allPosts = await getAllPosts(true, true); // Include archived and micro - const allMicro = await getCollection("micro", ({ data }) => data.tags?.includes("micro")).catch( - () => [], - ); + // Get all posts (including archived, now includes pleroma too) + const allPosts = await getAllPosts(true); - // Get unique tags from both collections - const postTags = getUniqueTags(allPosts); - const microTags = getUniqueMicroTags(allMicro); - const allTags = [...new Set([...postTags, ...microTags])]; + // Get unique tags from all posts + const allTags = getUniqueTags(allPosts); return allTags.map((tag) => ({ params: { tag }, @@ -29,33 +22,14 @@ export const GET = async (context: APIContext) => { throw new Error("Tag parameter is required"); } - // Get posts with this tag (include archived and micro) - const allPosts = await getAllPosts(true, true); + // Get posts with this tag (include archived) + const allPosts = await getAllPosts(true); const postsWithTag = allPosts.filter((post) => post.data.tags.includes(tag)); - // Get micro posts with this tag - const allMicro = await getCollection("micro", ({ data }) => data.tags?.includes("micro")).catch( - () => [], + // Sort chronologically + const sortedPosts = postsWithTag.sort( + (a, b) => b.data.publishDate.getTime() - a.data.publishDate.getTime(), ); - const microWithTag = allMicro.filter((micro) => micro.data.tags?.includes(tag)); - - // Combine and sort chronologically - const allItems = [ - ...postsWithTag.map((post) => ({ - title: post.data.title, - description: post.data.description, - pubDate: post.data.publishDate, - link: `posts/${post.id}/`, - content: undefined, - })), - ...microWithTag.map((micro) => ({ - title: micro.data.title, - description: micro.data.description, - pubDate: micro.data.publishDate, - link: `micro/${micro.id}/`, - content: micro.rendered?.html || micro.body || "", - })), - ].sort((a, b) => b.pubDate.getTime() - a.pubDate.getTime()); const site = context.site || import.meta.env.SITE; @@ -63,7 +37,13 @@ export const GET = async (context: APIContext) => { title: `${siteConfig.title} - ${tag}`, description: `Posts tagged with ${tag}`, site, - items: allItems, + items: sortedPosts.map((post) => ({ + title: post.data.title, + description: post.data.description, + pubDate: post.data.publishDate, + link: `posts/${post.id}/`, + author: post.data.author, + })), customData: `<atom:link href="${site}tags/${tag}/rss.xml" rel="self" type="application/rss+xml" xmlns:atom="http://www.w3.org/2005/Atom" />`, }); }; diff --git a/src/pages/tags/index.astro b/src/pages/tags/index.astro index 2c7b07b..260a4fa 100644 --- a/src/pages/tags/index.astro +++ b/src/pages/tags/index.astro @@ -1,29 +1,12 @@ --- -import { getCollection } from "astro:content"; import { getAllPosts, getUniqueTagsWithCount } from "@/data/post"; import PageLayout from "@/layouts/Base.astro"; -import { getUniqueMicroTagsWithCount } from "@/utils/micro"; -const allPostsIncludingArchived = await getAllPosts(true, true); // Include archived and micro -const allMicro = await getCollection("micro", ({ data }) => data.tags?.includes("micro")).catch( - () => [], -); +// Get all posts including archived (now includes pleroma posts too) +const allPostsIncludingArchived = await getAllPosts(true); -// Get tags with counts from both collections -const postTags = getUniqueTagsWithCount(allPostsIncludingArchived); -const microTags = getUniqueMicroTagsWithCount(allMicro); - -// Merge tags and sum counts -const tagMap = new Map<string, number>(); -for (const [tag, count] of postTags) { - tagMap.set(tag, count); -} -for (const [tag, count] of microTags) { - tagMap.set(tag, (tagMap.get(tag) || 0) + count); -} - -// Convert back to array and sort by count -const allTags = Array.from(tagMap.entries()).sort((a, b) => b[1] - a[1]); +// Get tags with counts from all posts +const allTags = getUniqueTagsWithCount(allPostsIncludingArchived); const meta = { description: "A list of all the topics I've written about in my posts", diff --git a/src/site.config.ts b/src/site.config.ts index d9b395c..d2fa871 100644 --- a/src/site.config.ts +++ b/src/site.config.ts @@ -46,8 +46,8 @@ export const menuLinks: { path: string; title: string }[] = [ title: "Blog", }, { - path: "/tags/micro/", - title: "Micro", + path: "/tags/microblog/", + title: "Microblog", }, { path: "/privacy-policy/", diff --git a/src/utils/date.ts b/src/utils/date.ts index b8c0376..314a837 100644 --- a/src/utils/date.ts +++ b/src/utils/date.ts @@ -15,9 +15,6 @@ export function getFormattedDate( }).format(date); } -export function collectionDateSort( - a: CollectionEntry<"post" | "micro">, - b: CollectionEntry<"post" | "micro">, -) { +export function collectionDateSort(a: CollectionEntry<"post">, b: CollectionEntry<"post">) { return b.data.publishDate.getTime() - a.data.publishDate.getTime(); } diff --git a/src/utils/micro.ts b/src/utils/micro.ts deleted file mode 100644 index 7f06b41..0000000 --- a/src/utils/micro.ts +++ /dev/null @@ -1,40 +0,0 @@ -import type { CollectionEntry } from "astro:content"; - -export type MicroEntry = CollectionEntry<"micro">; - -export function sortMicroEntries(entries: MicroEntry[]): MicroEntry[] { - return entries.sort((a, b) => b.data.publishDate.getTime() - a.data.publishDate.getTime()); -} - -export async function getAllMicroPosts(): Promise<MicroEntry[]> { - const { getCollection } = await import("astro:content"); - - // Get only Pleroma micro posts - try { - const microPosts = await getCollection("micro"); - return sortMicroEntries(microPosts); - } catch (error) { - console.warn("Micro collection not available:", error); - return []; - } -} - -/** Extract all tags from micro posts */ -export function getAllMicroTags(entries: MicroEntry[]): string[] { - return entries.flatMap((entry) => entry.data.tags ?? []); -} - -/** Get unique tags from micro posts */ -export function getUniqueMicroTags(entries: MicroEntry[]): string[] { - return [...new Set(getAllMicroTags(entries))]; -} - -/** Get unique tags with counts from micro posts */ -export function getUniqueMicroTagsWithCount(entries: MicroEntry[]): [string, number][] { - return [ - ...getAllMicroTags(entries).reduce( - (acc, t) => acc.set(t, (acc.get(t) ?? 0) + 1), - new Map<string, number>(), - ), - ].sort((a, b) => b[1] - a[1]); -} |
