import { getCollection } from 'astro:content';
import { SITES } from '@eratic/core';
export interface Latest {
title: string;
summary: string;
pubDate: Date;
/** Absolute — these point at another origin. */
href: string;
kicker?: string;
}
function isPublished(data: { draft: boolean; pubDate: Date }): boolean {
if (import.meta.env.DEV) return true;
return !data.draft && data.pubDate.getTime() <= Date.now();
}
function newestFirst(a: Latest, b: Latest): number {
return b.pubDate.getTime() - a.pubDate.getTime();
}
/** Posts and photo sets from blog.eratic.ro, interleaved as they are there. */
export async function latestFromBlog(limit = 4): Promise<Latest[]> {
const [posts, photos] = await Promise.all([getCollection('posts'), getCollection('photos')]);
const items: Latest[] = [
...posts.filter((e) => isPublished(e.data)).map((e) => ({
title: e.data.title,
summary: e.data.summary,
pubDate: e.data.pubDate,
href: new URL(`/${e.id}/`, SITES.blog.url).href,
kicker: 'Writing',
})),
...photos.filter((e) => isPublished(e.data)).map((e) => {
const count = e.data.photos?.length ?? 0;
const place = e.data.place ? `${e.data.place}, ` : '';
return {
title: e.data.title,
summary: e.data.summary,
pubDate: e.data.pubDate,
href: new URL(`/${e.id}/`, SITES.blog.url).href,
kicker: count ? `${place}${count} photograph${count === 1 ? '' : 's'}` : 'Photographs',
};
}),
];
return items.sort(newestFirst).slice(0, limit);
}
export async function latestFromFav(limit = 4): Promise<Latest[]> {
const favs = await getCollection('favs');
return favs
.filter((e) => isPublished(e.data))
.map((e) => ({
title: e.data.title,
summary: e.data.summary,
pubDate: e.data.pubDate,
href: new URL(`/${e.id}/`, SITES.fav.url).href,
kicker: [e.data.kind.charAt(0).toUpperCase() + e.data.kind.slice(1), e.data.creator]
.filter(Boolean)
.join(' · '),
}))
.sort(newestFirst)
.slice(0, limit);
}
export async function latestFromIo(limit = 3): Promise<Latest[]> {
const issues = await getCollection('issues');
return issues
.filter((e) => isPublished(e.data))
.map((e) => {
const count = e.data.links?.length ?? 0;
return {
title: e.data.title ?? `Issue ${e.data.issue}`,
summary: e.data.summary,
pubDate: e.data.pubDate,
href: new URL(`/${e.id}/`, SITES.io.url).href,
kicker: count ? `${count} thing${count === 1 ? '' : 's'}` : undefined,
};
})
.sort(newestFirst)
.slice(0, limit);
}