diff --git a/src/lib/components/archive/ArchiveCard.svelte b/src/lib/components/archive/ArchiveCard.svelte index 273fe51..ddbbc84 100644 --- a/src/lib/components/archive/ArchiveCard.svelte +++ b/src/lib/components/archive/ArchiveCard.svelte @@ -2,6 +2,12 @@ import { fly, fade } from "svelte/transition"; import { quintOut } from "svelte/easing"; import { formatDate } from "$lib/utils/dateFormatter"; + import DocumentIcon from "$lib/components/icons/utility/DocumentIcon.svelte"; + import LinkExternalIcon from "$lib/components/icons/utility/LinkExternalIcon.svelte"; + import CoffeeIcon from "$lib/components/icons/utility/CoffeeIcon.svelte"; + import ClockIcon from "$lib/components/icons/utility/ClockIcon.svelte"; + import BookIcon from "$lib/components/icons/utility/BookIcon.svelte"; + import BooksIcon from "$lib/components/icons/utility/BooksIcon.svelte"; export let type: 'post' | 'link'; export let post: any = {}; // For post type @@ -62,21 +68,12 @@
{#if type === 'post'}
- - - - - - - + Blog post
{:else} {/if} @@ -99,32 +96,13 @@
{#if getReadingTimeIcon(readingTime) === 'quick'} - - - - - - - - + {:else if getReadingTimeIcon(readingTime) === 'short'} - - - - - + {:else if getReadingTimeIcon(readingTime) === 'medium'} - - - - - + {:else} - - - - - + {/if}
{Math.ceil(post.wordCount / 200)} diff --git a/src/lib/components/icons/index.ts b/src/lib/components/icons/index.ts index 8195fc8..5fd6e29 100644 --- a/src/lib/components/icons/index.ts +++ b/src/lib/components/icons/index.ts @@ -10,4 +10,12 @@ export { default as HomeIcon } from './utility/HomeIcon.svelte'; export { default as LinkIcon } from './utility/LinkIcon.svelte'; export { default as MoonIcon } from './utility/MoonIcon.svelte'; export { default as PostIcon } from './utility/PostIcon.svelte'; -export { default as SunIcon } from './utility/SunIcon.svelte'; \ No newline at end of file +export { default as SunIcon } from './utility/SunIcon.svelte'; +export { default as DocumentIcon } from "./utility/DocumentIcon.svelte"; +export { default as LinkExternalIcon } from "./utility/LinkExternalIcon.svelte"; +export { default as CoffeeIcon } from "./utility/CoffeeIcon.svelte"; +export { default as ClockIcon } from "./utility/ClockIcon.svelte"; +export { default as BookIcon } from "./utility/BookIcon.svelte"; +export { default as BooksIcon } from "./utility/BooksIcon.svelte"; +export { default as EditIcon } from "./utility/EditIcon.svelte"; +export { default as ArrowRightUpIcon } from "./utility/ArrowRightUpIcon.svelte"; \ No newline at end of file diff --git a/src/lib/components/icons/utility/ArrowRightUpIcon.svelte b/src/lib/components/icons/utility/ArrowRightUpIcon.svelte new file mode 100644 index 0000000..8db6201 --- /dev/null +++ b/src/lib/components/icons/utility/ArrowRightUpIcon.svelte @@ -0,0 +1,20 @@ + + + + + + \ No newline at end of file diff --git a/src/lib/components/icons/utility/BookIcon.svelte b/src/lib/components/icons/utility/BookIcon.svelte new file mode 100644 index 0000000..628fcdb --- /dev/null +++ b/src/lib/components/icons/utility/BookIcon.svelte @@ -0,0 +1,20 @@ + + + + + + \ No newline at end of file diff --git a/src/lib/components/icons/utility/BooksIcon.svelte b/src/lib/components/icons/utility/BooksIcon.svelte new file mode 100644 index 0000000..ffb4cc4 --- /dev/null +++ b/src/lib/components/icons/utility/BooksIcon.svelte @@ -0,0 +1,20 @@ + + + + + + \ No newline at end of file diff --git a/src/lib/components/icons/utility/ClockIcon.svelte b/src/lib/components/icons/utility/ClockIcon.svelte new file mode 100644 index 0000000..1dba008 --- /dev/null +++ b/src/lib/components/icons/utility/ClockIcon.svelte @@ -0,0 +1,20 @@ + + + + + + \ No newline at end of file diff --git a/src/lib/components/icons/utility/CoffeeIcon.svelte b/src/lib/components/icons/utility/CoffeeIcon.svelte new file mode 100644 index 0000000..63d824f --- /dev/null +++ b/src/lib/components/icons/utility/CoffeeIcon.svelte @@ -0,0 +1,23 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/lib/components/icons/utility/DocumentIcon.svelte b/src/lib/components/icons/utility/DocumentIcon.svelte new file mode 100644 index 0000000..d6290e2 --- /dev/null +++ b/src/lib/components/icons/utility/DocumentIcon.svelte @@ -0,0 +1,23 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/lib/components/icons/utility/EditIcon.svelte b/src/lib/components/icons/utility/EditIcon.svelte new file mode 100644 index 0000000..8e4ab49 --- /dev/null +++ b/src/lib/components/icons/utility/EditIcon.svelte @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/src/lib/components/icons/utility/LinkExternalIcon.svelte b/src/lib/components/icons/utility/LinkExternalIcon.svelte new file mode 100644 index 0000000..73050cf --- /dev/null +++ b/src/lib/components/icons/utility/LinkExternalIcon.svelte @@ -0,0 +1,20 @@ + + + + + + \ No newline at end of file diff --git a/src/lib/components/layout/ThemeToggle.svelte b/src/lib/components/layout/ThemeToggle.svelte index cbacab3..34da16b 100644 --- a/src/lib/components/layout/ThemeToggle.svelte +++ b/src/lib/components/layout/ThemeToggle.svelte @@ -1,6 +1,7 @@ + +{#if latestPost} +
+
+

Latest Blog Post

+ + View All Posts + + +
+ +
+ +
+
+{/if} + + \ No newline at end of file diff --git a/src/lib/components/layout/main/index.ts b/src/lib/components/layout/main/index.ts index 64220e5..abc178b 100644 --- a/src/lib/components/layout/main/index.ts +++ b/src/lib/components/layout/main/index.ts @@ -1 +1,2 @@ -export { default as DynamicLinks } from "./DynamicLinks.svelte"; \ No newline at end of file +export { default as DynamicLinks } from "./DynamicLinks.svelte"; +export { default as LatestBlogPost } from "./LatestBlogPost.svelte"; \ No newline at end of file diff --git a/src/routes/+layout.ts b/src/routes/+layout.ts index 929f0fe..16e7817 100644 --- a/src/routes/+layout.ts +++ b/src/routes/+layout.ts @@ -1,19 +1,17 @@ import { getProfile } from "$lib/components/profile/profile"; -import type { Profile, LinkBoard } from "$lib/components/shared"; +import type { Profile, LinkBoard, MarkdownPost, Post } from "$lib/components/shared"; +import { parse } from "$lib/parser"; // Profile data cache let profile: Profile; let dynamicLinks: LinkBoard | undefined; +let latestPosts: Post[] = []; export async function load({ fetch }) { if (profile === undefined) { profile = await getProfile(fetch); } - if (profile === undefined) { - profile = await getProfile(fetch); - } - // Fetch dynamic links only if not already cached if (dynamicLinks === undefined) { try { @@ -29,12 +27,86 @@ export async function load({ fetch }) { } } + // Fetch latest blog posts if not already cached + if (latestPosts.length === 0) { + try { + const rawResponse = await fetch( + `${profile.pds}/xrpc/com.atproto.repo.listRecords?repo=${profile.did}&collection=com.whtwnd.blog.entry` + ); + + if (rawResponse.ok) { + const response = await rawResponse.json(); + + if (response.records && response.records.length > 0) { + const mdposts: Map = new Map(); + + // Process only the latest few posts to keep it lightweight + const recentRecords = response.records + .filter((data: any) => { + const matches = data["uri"].split("/"); + const record = data["value"] || data.value; + return matches && matches.length === 5 && + record && + (record["visibility"] === "public" || !record["visibility"]); + }) + .slice(0, 3); // Only process the latest 3 posts for the homepage + + for (const data of recentRecords) { + const matches = data["uri"].split("/"); + const rkey = matches[matches.length - 1]; + const record = data["value"] || data.value; + + const content = record["content"] || record.content; + const title = record["title"] || record.title; + const createdAt = record["createdAt"] || record.createdAt; + + const actualContent = content || (record.value && record.value.content); + const actualTitle = title || (record.value && record.value.title); + const actualCreatedAt = createdAt || (record.value && record.value.createdAt); + + // Skip posts without content + if (!actualContent) continue; + + let createdAtDate: Date; + if (!actualCreatedAt) { + createdAtDate = new Date(); + } else { + createdAtDate = new Date(actualCreatedAt); + if (isNaN(createdAtDate.getTime())) { + continue; + } + } + + const finalTitle = actualTitle || `Untitled Post (${rkey})`; + + mdposts.set(rkey, { + title: finalTitle, + createdAt: createdAtDate, + mdcontent: actualContent, + rkey, + }); + } + + if (mdposts.size > 0) { + const parsedPosts = await parse(mdposts); + latestPosts = Array.from(parsedPosts.values()).sort( + (a, b) => b.createdAt.getTime() - a.createdAt.getTime() + ); + } + } + } + } catch (error) { + console.error("Error fetching latest blog posts:", error); + latestPosts = []; + } + } + return { profile, - pdsUrl: profile.pds, // Add pdsUrl from profile - did: profile.did, // Add did from profile - posts: new Map(), // Add empty posts map to match the expected type + pdsUrl: profile.pds, + did: profile.did, + posts: new Map(), // Keep this for compatibility with existing Footer component dynamicLinks, - + latestPosts, // Add latest posts for the homepage }; -} +} \ No newline at end of file diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 85b443c..cf38ede 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -1,9 +1,20 @@ @@ -41,5 +52,9 @@ - - + +{#if data.latestPosts && data.latestPosts.length > 0} + +{/if} + + \ No newline at end of file