import { newestSaves, type RepoStats, repoStats, type Save } from "../mirror/queries.ts"; import { publicRepoNames } from "../server/db.ts"; import { type Html, html } from "./html.ts"; import { openPublicRepo, type PageContext, type PublicRepo, plural } from "./layout.ts"; import { repoIntro } from "./repo.ts"; /** A public repo as the front page, browse and the profile show it. */ export type LibraryRepo = PublicRepo & { stats: RepoStats; description: string }; export type RecentSave = { repo: string; save: Save }; /** Every public repo in card order (ยง20: private ones never reach a page, count or card). */ export function publicLibrary(ctx: PageContext): LibraryRepo[] { return publicRepoNames(ctx.kepr).flatMap((name) => { const repo = openPublicRepo(ctx, name); if (!repo) return []; const description = repoIntro(repo)?.text ?? ""; return [{ ...repo, stats: repoStats(repo.mirror), description }]; }); } /** The newest saves across the library, checkpoints never among them. */ export function recentSaves(library: LibraryRepo[], limit: number): RecentSave[] { return library .flatMap((repo) => newestSaves(repo.mirror, limit).map((save) => ({ repo: repo.settings.name, save })), ) .sort((a, b) => b.save.created_at - a.save.created_at) .slice(0, limit); } export function repoCards(library: LibraryRepo[]): Html { return html`
${library.map(repoCard)}
`; } // Kepr 2's card: name, save count, the description, and the category. function repoCard(repo: LibraryRepo): Html { const { name, category } = repo.settings; return html`
${ name }${plural(repo.stats.saves, "save")}
${repo.description && html`

${repo.description}

`} ${category && html`

${category}

`}
`; }