diff --git a/www/src/lib/format.ts b/www/src/lib/format.ts index cd07266..41468a2 100644 --- a/www/src/lib/format.ts +++ b/www/src/lib/format.ts @@ -30,10 +30,11 @@ export function formatListItem( date: Date, url: string, title: string, - options?: { pinned?: boolean } + options?: { pinned?: boolean; suffix?: string } ): string { const pinnedBadge = options?.pinned ? ' [pinned]' : ''; - return `${formatDate(date)}${title}${pinnedBadge}`; + const suffix = options?.suffix ? ` ${options.suffix}` : ''; + return `${formatDate(date)}${title}${pinnedBadge}${suffix}`; } interface Sortable { @@ -41,10 +42,12 @@ interface Sortable { pinned?: boolean; } -export function sortByPinnedThenDate(items: T[]): T[] { +export function sortEntries(items: T[], key?: (item: T) => Sortable): T[] { + const get = key ?? (item => item as unknown as Sortable); return items.slice().sort((a, b) => { - if (a.pinned && !b.pinned) return -1; - if (!a.pinned && b.pinned) return 1; - return b.date.getTime() - a.date.getTime(); + const ak = get(a), bk = get(b); + if (ak.pinned && !bk.pinned) return -1; + if (!ak.pinned && bk.pinned) return 1; + return bk.date.getTime() - ak.date.getTime(); }); } diff --git a/www/src/lib/md.ts b/www/src/lib/md.ts index 378c2c6..eb1a1e0 100644 --- a/www/src/lib/md.ts +++ b/www/src/lib/md.ts @@ -1,5 +1,6 @@ import type { CollectionEntry } from 'astro:content'; import { DEFAULT_CATEGORY } from './consts'; +import { sortEntries } from './format'; type Post = CollectionEntry<'md'>; @@ -8,15 +9,6 @@ export function getSlug(postId: string): string { return parts[parts.length - 1]; } -function sortPosts(posts: Post[], { alphabetically = false } = {}): Post[] { - return posts.slice().sort((a, b) => { - if (a.data.pinned && !b.data.pinned) return -1; - if (!a.data.pinned && b.data.pinned) return 1; - if (alphabetically) return a.data.title.localeCompare(b.data.title); - return b.data.date.getTime() - a.data.date.getTime(); - }); -} - export function resolveRelatedPosts( slugs: string[], allPosts: T[], @@ -25,7 +17,7 @@ export function resolveRelatedPosts( return slugs.flatMap(s => bySlug.get(s) ?? []); } -export function organizePostsByCategory(posts: Post[], { sortAlphabetically = false } = {}): { +export function organizePostsByCategory(posts: Post[]): { grouped: Record; categories: string[]; } { @@ -43,7 +35,7 @@ export function organizePostsByCategory(posts: Post[], { sortAlphabetically = fa }); for (const category of categories) { - grouped[category] = sortPosts(grouped[category], { alphabetically: sortAlphabetically }); + grouped[category] = sortEntries(grouped[category], p => p.data); } return { grouped, categories }; diff --git a/www/src/lib/txt.ts b/www/src/lib/txt.ts index ee03984..2f0dea4 100644 --- a/www/src/lib/txt.ts +++ b/www/src/lib/txt.ts @@ -1,7 +1,7 @@ import fs from 'node:fs'; import path from 'node:path'; import yaml from 'js-yaml'; -import { sortByPinnedThenDate } from './format'; +import { sortEntries } from './format'; export interface TxtFile { name: string; @@ -44,6 +44,6 @@ export function getTxtFiles(): TxtFile[] { pinned: pinnedSet.has(name), description: descriptions[name], })); - return sortByPinnedThenDate(files); + return sortEntries(files); }