summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/components/note/Note.astro17
-rw-r--r--src/loaders/pleroma.ts27
2 files changed, 42 insertions, 2 deletions
diff --git a/src/components/note/Note.astro b/src/components/note/Note.astro
index 54d1fc0..a8cf205 100644
--- a/src/components/note/Note.astro
+++ b/src/components/note/Note.astro
@@ -44,5 +44,22 @@ const { Content } = await render(note);
class:list={{ "line-clamp-6": isPreview }}
>
<Content />
+ {
+ !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/loaders/pleroma.ts b/src/loaders/pleroma.ts
index dc6a05c..a0b169f 100644
--- a/src/loaders/pleroma.ts
+++ b/src/loaders/pleroma.ts
@@ -1,6 +1,7 @@
import type { Loader } from "astro/loaders";
import { XMLParser } from "fast-xml-parser";
import TurndownService from "turndown";
+import { marked } from "marked";
interface PleromaFeedConfig {
instanceUrl: string;
@@ -192,6 +193,20 @@ function cleanContent(htmlContent: string): string {
return markdown.trim().replace(/\n\s*\n\s*\n/g, "\n\n");
}
+function markdownToHtml(markdown: string): string {
+ // Configure marked options for safe rendering
+ marked.setOptions({
+ breaks: true, // Convert line breaks to <br>
+ gfm: true, // GitHub flavored markdown
+ });
+
+ // Convert markdown to HTML
+ const html = marked.parse(markdown);
+
+ // Return as string (marked.parse can return string or Promise<string>)
+ return typeof html === 'string' ? html : '';
+}
+
function extractTitle(content: string): string {
// Extract first line or first sentence as title
const firstLine = content.split("\n")[0];
@@ -296,6 +311,9 @@ export function pleromaLoader(config: PleromaFeedConfig): Loader {
// Extract post ID from the entry ID
const postId = entry.id.split("/").pop() || entry.id;
+ // Extract source URL from the entry
+ const sourceUrl = entry.link?.find(link => link["@_rel"] === "alternate")?.["@_href"] || entry.id;
+
// Create note entry
store.set({
id: `pleroma-${postId}`,
@@ -304,10 +322,11 @@ export function pleromaLoader(config: PleromaFeedConfig): Loader {
description:
cleanedContent.substring(0, 160) + (cleanedContent.length > 160 ? "..." : ""),
publishDate: new Date(entry.published),
+ sourceUrl,
},
body: cleanedContent,
rendered: {
- html: `<p>${cleanedContent.replace(/\n\n/g, "</p><p>")}</p>`,
+ html: markdownToHtml(cleanedContent),
},
});
@@ -341,6 +360,9 @@ export function pleromaLoader(config: PleromaFeedConfig): Loader {
(typeof item.link === "string" ? item.link.split("/").pop() : null) ||
Math.random().toString(36);
+ // Use the link as source URL
+ const sourceUrl = typeof item.link === "string" ? item.link : item.guid || "";
+
// Create note entry
store.set({
id: `pleroma-${postId}`,
@@ -349,10 +371,11 @@ export function pleromaLoader(config: PleromaFeedConfig): Loader {
description:
cleanedContent.substring(0, 160) + (cleanedContent.length > 160 ? "..." : ""),
publishDate: new Date(item.pubDate),
+ sourceUrl,
},
body: cleanedContent,
rendered: {
- html: `<p>${cleanedContent.replace(/\n\n/g, "</p><p>")}</p>`,
+ html: markdownToHtml(cleanedContent),
},
});