1
0
Fork 0
forked from swablab/website
website/src/components/Mastodon.astro

94 lines
2.2 KiB
Text

---
import { getImage } from "astro:assets"
import { formatDate } from "../helper"
type Post = {
content: string
url: string
created_at: string
media_attachments: {
id: string
preview_url: string
description: string
}[]
emojis: {
shortcode: string
url: string
}[]
}
const posts: Post[] = await (
await fetch(
"https://mastodon.social/api/v1/accounts/112282328572683277/statuses?exclude_replies=true&limit=5",
)
).json()
const attachments = await Promise.all(
posts.map(async (post) => {
if (post.media_attachments.length == 0) return null
return await getImage({
src: post.media_attachments[0].preview_url,
inferSize: true,
})
}),
)
const emojis = await Promise.all(
posts
.flatMap((post) => post.emojis)
.map(async (emoji) => {
return {
shortcode: emoji.shortcode,
...(await getImage({
src: emoji.url,
inferSize: true,
})),
}
}),
)
function replaceEmojis(content: string) {
for (const emoji of emojis) {
content = content.replaceAll(
`:${emoji.shortcode}:`,
`<img src="${emoji.src}" class="w-[1em] h-[1em] inline-block" />`,
)
}
return content
}
---
{
posts.map((post, i) => (
<div class="card md:card-side bg-base-300 shadow-xl">
{attachments[i] == null ? null : (
<figure class="max-h-64 md:flex-none md:max-h-none md:max-w-64 md:min-h-full">
<a class="w-full" href={post.url}>
<img
class="w-full md:h-full object-cover"
src={attachments[i]?.src}
alt={post.media_attachments[0].description}
/>
</a>
</figure>
)}
<div class="card-body text-left text-lg">
<h2 class="card-title justify-between">
<a href={post.url}>@swablab</a>
<time class="text-xs opacity-50">
{formatDate(post.created_at, "long")}
</time>
</h2>
<div set:html={replaceEmojis(post.content)} />
</div>
</div>
))
}
<a
class="link link-primary"
href="https://mastodon.social/@swablab"
rel="noopener noreferrer me"
target="_blank"
>
Mehr auf Mastodon
</a>