diff --git a/.idea/mercury.iml b/.idea/mercury.iml index 24643cc..6deb029 100644 --- a/.idea/mercury.iml +++ b/.idea/mercury.iml @@ -5,6 +5,7 @@ + diff --git a/src/content/config.ts b/src/content/config.ts index b250015..2de2aa4 100644 --- a/src/content/config.ts +++ b/src/content/config.ts @@ -3,7 +3,7 @@ import {posts} from './posts/_schemas'; import {pages} from "./pages/_schemas"; import {file} from 'astro/loaders'; import { z } from 'astro:content'; -import {siteConfig} from "../config.ts"; +import {authors} from '../data/authors._schema.ts'; const blogCollection = defineCollection({ type: 'content', @@ -24,15 +24,7 @@ const blogRollData = defineCollection({ const authorsData = defineCollection({ loader: file("src/data/authors.yaml"), - schema: z.object({ - name: z.string().default(siteConfig.defaultAuthor.name), - email: z.string().email().default(siteConfig.defaultAuthor.email), - mcplayerid: z.string().optional(), - social: z.object({ - twitter: z.string().optional(), - fediverse: z.string().optional(), - }).optional(), - }) + schema: authors, }); export const collections = { diff --git a/src/data/authors._schema.ts b/src/data/authors._schema.ts new file mode 100644 index 0000000..3630bd8 --- /dev/null +++ b/src/data/authors._schema.ts @@ -0,0 +1,13 @@ +import {z} from "astro:content"; +import {siteConfig} from "../config.ts"; + +export const authors = ({ image }) => z.object({ + name: z.string().default(siteConfig.defaultAuthor.name), + email: z.string().email().default(siteConfig.defaultAuthor.email), + avatar: image().optional(), + mcplayerid: z.string().optional(), + social: z.object({ + twitter: z.string().optional(), + fediverse: z.string().optional(), + }).optional(), +}); \ No newline at end of file diff --git a/src/data/authors.yaml b/src/data/authors.yaml index 5cf773a..81590b3 100644 --- a/src/data/authors.yaml +++ b/src/data/authors.yaml @@ -1,7 +1,8 @@ Wheatley: # the key name (id) of the author, which is used in the front matter name: "Wheatley" # the display name of the author email: "hello@example.org" # the email address of the author - mcplayerid: "Wheatley" # the Minecraft player ID of the author, if applicable + avatar: "https://minotar.net/helm/Wheatley/64.png" # the URL of the author's avatar image (takes precedence over the minecraft player avatar, a square image with no more than 64*64 is recommended) + mcplayerid: "Wheatley" # the Minecraft player ID of the author, if applicable (used for generating player avatars) social: # the social media accounts of the author, if any (there is no reference for this yet except for the twitter handle) twitter: "@wheatley" fediverse: "@" diff --git a/src/pages/images/avatars/[author].png.js b/src/pages/images/avatars/[author].png.js index 57360b4..7ffe78f 100644 --- a/src/pages/images/avatars/[author].png.js +++ b/src/pages/images/avatars/[author].png.js @@ -1,4 +1,5 @@ import { getCollection } from 'astro:content'; +import { getImage } from "astro:assets"; export async function getStaticPaths() { const authorsData = await getCollection('authors'); @@ -11,6 +12,35 @@ export async function getStaticPaths() { export async function GET({ props }) { const { author } = props; + if (author.data.avatar) { + try { + const optimizedImage = await getImage({ + src: author.data.avatar, + width: 64, + height: 64, + format: 'png' + }); + + // Fetch the optimized image + const imageResponse = await fetch(optimizedImage.src); + if (!imageResponse.ok) { + throw new Error('Failed to fetch optimized image'); + } + + const imageBuffer = await imageResponse.arrayBuffer(); + + return new Response(imageBuffer, { + headers: { + 'Content-Type': 'image/png', + 'Cache-Control': 'public, max-age=86400' // Cache for 24 hours + } + }); + } catch (error) { + console.error('Error processing avatar image:', error); + // Fall through to the mcplayerid check if avatar processing fails + } + } + if (!author.data.mcplayerid) { return new Response(null, { status: 404 }); }