refactor: deduplicates our sorting function

This commit is contained in:
Lewis Wynne 2026-03-27 18:23:24 +00:00
parent 8209d036cd
commit 384ca71f89
3 changed files with 14 additions and 19 deletions

View file

@ -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 `<span class="list-meta"><span class="muted">${formatDate(date)}</span></span><span class="entry-content"><a href="${url}" title="${title}">${title}</a>${pinnedBadge}</span>`;
const suffix = options?.suffix ? ` ${options.suffix}` : '';
return `<span class="list-meta"><span class="muted">${formatDate(date)}</span></span><span class="entry-content"><a href="${url}" title="${title}">${title}</a>${pinnedBadge}${suffix}</span>`;
}
interface Sortable {
@ -41,10 +42,12 @@ interface Sortable {
pinned?: boolean;
}
export function sortByPinnedThenDate<T extends Sortable>(items: T[]): T[] {
export function sortEntries<T>(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();
});
}

View file

@ -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<T extends { id: string }>(
slugs: string[],
allPosts: T[],
@ -25,7 +17,7 @@ export function resolveRelatedPosts<T extends { id: string }>(
return slugs.flatMap(s => bySlug.get(s) ?? []);
}
export function organizePostsByCategory(posts: Post[], { sortAlphabetically = false } = {}): {
export function organizePostsByCategory(posts: Post[]): {
grouped: Record<string, Post[]>;
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 };

View file

@ -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);
}