From 00fa1fb1648c5ccbbfc9612fcf05d082fd6976ae Mon Sep 17 00:00:00 2001
From: Bad Manners <me@badmanners.xyz>
Date: Mon, 25 Mar 2024 15:35:24 -0300
Subject: [PATCH] Fix typo and add latest uploads to index

---
 scripts/export-story.ts              |  2 +-
 src/content/stories/tiny-accident.md |  2 +-
 src/pages/feed.xml.ts                |  8 ++--
 src/pages/games.astro                | 16 +++----
 src/pages/index.astro                | 62 ++++++++++++++++++++++++++++
 src/pages/stories/[page].astro       | 16 +++----
 src/pages/tags/[slug].astro          | 26 ++++++------
 7 files changed, 101 insertions(+), 31 deletions(-)

diff --git a/scripts/export-story.ts b/scripts/export-story.ts
index 63f668a..d410e0e 100644
--- a/scripts/export-story.ts
+++ b/scripts/export-story.ts
@@ -48,7 +48,7 @@ async function exportStory(slug: string, options: { outputDir: string }) {
   } catch {
     /* Spawn Astro dev server */
     console.log("Starting Astro development server...");
-    devServerProcess = exec("npm run dev");
+    devServerProcess = exec("./node_modules/.bin/astro dev");
     await setTimeout(2000);
     try {
       await fetchRetry(healthcheckURL, { retries: 5, retryDelay: 2000 });
diff --git a/src/content/stories/tiny-accident.md b/src/content/stories/tiny-accident.md
index 15c3533..6333b8c 100644
--- a/src/content/stories/tiny-accident.md
+++ b/src/content/stories/tiny-accident.md
@@ -69,7 +69,7 @@ With all of his attention on the micro shifting against his palm, the rat slowly
 
 The rodent was quickly losing his patience. "You didn't mean to...what? Be a creepy pervert and sneak your way to my fucking dick?!"
 
-Too nervous to lie his way out of this, the wolf simply looked away from the giant face and closed his lies. "I didn't think you'd feel o-or notice me..."
+Too nervous to lie his way out of this, the wolf simply looked away from the giant face and closed his eyes. "I didn't think you'd feel o-or notice me..."
 
 Kolo's face turned red with anger.
 
diff --git a/src/pages/feed.xml.ts b/src/pages/feed.xml.ts
index 84a1379..e0df54a 100644
--- a/src/pages/feed.xml.ts
+++ b/src/pages/feed.xml.ts
@@ -7,9 +7,11 @@ type FeedItem = RSSFeedItem & {
   pubDate: Date;
 };
 
+const MAX_ITEMS = 10;
+
 export const GET: APIRoute = async ({ site }) => {
-  const stories = await getCollection("stories", (story) => !story.data.isDraft);
-  const games = await getCollection("games", (game) => !game.data.isDraft);
+  const stories = (await getCollection("stories", (story) => !story.data.isDraft)).sort((a, b) => getUnixTime(b.data.pubDate) - getUnixTime(a.data.pubDate)).slice(0, MAX_ITEMS);
+  const games = (await getCollection("games", (game) => !game.data.isDraft)).sort((a, b) => getUnixTime(b.data.pubDate) - getUnixTime(a.data.pubDate)).slice(0, MAX_ITEMS);
   return rss({
     title: "Gallery | Bad Manners",
     description: "Stories, games, and (possibly) more by Bad Manners",
@@ -37,6 +39,6 @@ export const GET: APIRoute = async ({ site }) => {
     ]
       .flat()
       .sort((a, b) => getUnixTime(b.pubDate) - getUnixTime(a.pubDate))
-      .slice(0, 10),
+      .slice(0, MAX_ITEMS),
   });
 };
diff --git a/src/pages/games.astro b/src/pages/games.astro
index 84e68bb..9e13955 100644
--- a/src/pages/games.astro
+++ b/src/pages/games.astro
@@ -14,18 +14,20 @@ const games = (await getCollection("games", (game) => !game.data.isDraft)).sort(
   <meta slot="head-description" content="Bad Manners || A game that I've gone and done." property="og:description" />
   <h1 class="m-2 text-2xl font-semibold text-stone-800 dark:text-stone-100">Games</h1>
   <p class="my-4">A game that I've gone and done.</p>
-  <ul class="my-6 flex flex-wrap justify-center gap-4 text-center md:justify-normal">
+  <ul class="my-6 flex flex-wrap justify-center gap-4 text-center md:justify-normal items-start">
     {
       games.map((game) => (
         <li>
           <a class="text-link hover:underline focus:underline" href={`/games/${game.slug}`}>
             {game.data.thumbnail ? (
-              <Image
-                class="max-w-[288px]"
-                src={game.data.thumbnail}
-                alt={`Thumbnail for ${game.data.title}`}
-                width={288}
-              />
+              <div class="max-w-[288px] aspect-[630/500] flex justify-center">
+                <Image
+                  class="m-auto"
+                  src={game.data.thumbnail}
+                  alt={`Thumbnail for ${game.data.title}`}
+                  width={288}
+                />
+              </div>
             ) : null}
             <div class="max-w-[288px] text-sm">
               <>
diff --git a/src/pages/index.astro b/src/pages/index.astro
index d88f6d9..8012ce0 100644
--- a/src/pages/index.astro
+++ b/src/pages/index.astro
@@ -1,5 +1,39 @@
 ---
+import { type CollectionEntry, getCollection } from "astro:content";
+import { Image } from "astro:assets";
+import { getUnixTime, format as formatDate } from "date-fns";
+import { enUS as enUSLocale } from "date-fns/locale/en-US";
 import GalleryLayout from "../layouts/GalleryLayout.astro";
+
+const MAX_ITEMS = 5;
+
+interface LatestItemsEntry {
+  type: string;
+  thumbnail: CollectionEntry<"stories">["data"]["thumbnail"];
+  href: string;
+  title: string;
+  pubDate: Date;
+}
+
+const stories = (await getCollection("stories", (story) => !story.data.isDraft)).sort((a, b) => getUnixTime(b.data.pubDate) - getUnixTime(a.data.pubDate)).slice(0, MAX_ITEMS);
+const games = (await getCollection("games", (game) => !game.data.isDraft)).sort((a, b) => getUnixTime(b.data.pubDate) - getUnixTime(a.data.pubDate)).slice(0, MAX_ITEMS);
+
+const latestItems: LatestItemsEntry[] = [
+  stories.map<LatestItemsEntry>(story => ({
+    type: "Story",
+    thumbnail: story.data.thumbnail,
+    href: `/stories/${story.slug}`,
+    title: story.data.title,
+    pubDate: story.data.pubDate,
+  })),
+  games.map<LatestItemsEntry>(game => ({
+    type: "Game",
+    thumbnail: game.data.thumbnail,
+    href: `/games/${game.slug}`,
+    title: game.data.title,
+    pubDate: game.data.pubDate,
+  })),
+].flat().sort((a, b) => getUnixTime(b.pubDate) - getUnixTime(a.pubDate)).slice(0, MAX_ITEMS);
 ---
 
 <GalleryLayout pageTitle="Gallery">
@@ -18,4 +52,32 @@ import GalleryLayout from "../layouts/GalleryLayout.astro";
       target="_blank">my main website</a
     >.
   </p>
+  <section class="my-2" aria-labelledby="latest-uploads">
+    <h2 id="latest-uploads" class="p-2 text-xl font-semibold text-stone-800 dark:text-stone-100">Latest uploads</h2>
+    <ul class="flex flex-wrap justify-center gap-4 text-center md:justify-normal items-start">
+      {
+        latestItems.map((entry) => (
+          <li class="break-inside-avoid">
+            <a class="text-link hover:underline focus:underline" href={entry.href}>
+              {entry.thumbnail ? (
+                <div class="max-w-[192px] aspect-square flex justify-center">
+                  <Image
+                    class="m-auto"
+                    src={entry.thumbnail}
+                    alt={`Thumbnail for ${entry.title}`}
+                    width={192}
+                  />
+                </div>
+              ) : null}
+              <div class="max-w-[192px] text-sm">
+                <span>{entry.title}</span>
+                <br />
+                <span class="italic">{entry.type} &ndash; {formatDate(entry.pubDate, "MMM d, yyyy", { locale: enUSLocale })}</span>
+              </div>
+            </a>
+          </li>
+        ))
+      }
+    </ul>
+  </section>
 </GalleryLayout>
diff --git a/src/pages/stories/[page].astro b/src/pages/stories/[page].astro
index 6144f39..cee229e 100644
--- a/src/pages/stories/[page].astro
+++ b/src/pages/stories/[page].astro
@@ -62,18 +62,20 @@ const totalPages = Math.ceil(page.total / page.size);
       )
     }
   </div>
-  <ul class="flex flex-wrap justify-center gap-4 text-center md:justify-normal">
+  <ul class="flex flex-wrap justify-center gap-4 text-center md:justify-normal items-start">
     {
       page.data.map((story) => (
         <li class="break-inside-avoid">
           <a class="text-link hover:underline focus:underline" href={`/stories/${story.slug}`}>
             {story.data.thumbnail ? (
-              <Image
-                class="max-w-[192px]"
-                src={story.data.thumbnail}
-                alt={`Thumbnail for ${story.data.title}`}
-                width={192}
-              />
+              <div class="max-w-[192px] aspect-square flex justify-center">
+                <Image
+                  class="m-auto"
+                  src={story.data.thumbnail}
+                  alt={`Thumbnail for ${story.data.title}`}
+                  width={192}
+                />
+              </div>
             ) : null}
             <div class="max-w-[192px] text-sm">
               <span>{story.data.title}</span>
diff --git a/src/pages/tags/[slug].astro b/src/pages/tags/[slug].astro
index ff7e7f9..950fe0e 100644
--- a/src/pages/tags/[slug].astro
+++ b/src/pages/tags/[slug].astro
@@ -69,18 +69,19 @@ if (count == 1) {
         <h2 id="content-stories" class="p-2 text-xl font-semibold text-stone-800 dark:text-stone-100">
           Stories
         </h2>
-        <ul class="flex flex-wrap justify-center gap-4 text-center md:justify-normal">
+        <ul class="flex flex-wrap justify-center gap-4 text-center md:justify-normal items-start">
           {stories.map((story) => (
             <li class="break-inside-avoid">
               <a class="text-link hover:underline focus:underline" href={`/stories/${story.slug}`}>
                 {story.data.thumbnail ? (
-                  <Image
-                    class="w-48"
-                    src={story.data.thumbnail}
-                    alt={`Thumbnail for ${story.data.title}`}
-                    width={story.data.thumbnailWidth}
-                    height={story.data.thumbnailHeight}
-                  />
+                  <div class="max-w-[192px] aspect-square flex justify-center">
+                    <Image
+                      class="m-auto"
+                      src={story.data.thumbnail}
+                      alt={`Thumbnail for ${story.data.title}`}
+                      width={192}
+                    />
+                  </div>
                 ) : null}
                 <div class="max-w-48 text-sm">{story.data.title}</div>
               </a>
@@ -96,18 +97,19 @@ if (count == 1) {
         <h2 id="content-games" class="p-2 text-xl font-semibold text-stone-800 dark:text-stone-100">
           Games
         </h2>
-        <ul class="flex flex-wrap justify-center gap-4 text-center md:justify-normal">
+        <ul class="flex flex-wrap justify-center gap-4 text-center md:justify-normal items-start">
           {games.map((game) => (
             <li class="break-inside-avoid">
               <a class="text-link hover:underline focus:underline" href={`/games/${game.slug}`}>
                 {game.data.thumbnail ? (
+                  <div class="max-w-[192px] aspect-[630/500] flex justify-center">
                   <Image
-                    class="w-48"
+                    class="m-auto"
                     src={game.data.thumbnail}
                     alt={`Thumbnail for ${game.data.title}`}
-                    width={game.data.thumbnailWidth}
-                    height={game.data.thumbnailHeight}
+                    width={192}
                   />
+                </div>
                 ) : null}
                 <div class="max-w-48 text-sm">{game.data.title}</div>
               </a>