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, date: Date,
url: string, url: string,
title: string, title: string,
options?: { pinned?: boolean } options?: { pinned?: boolean; suffix?: string }
): string { ): string {
const pinnedBadge = options?.pinned ? ' [pinned]' : ''; 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 { interface Sortable {
@ -41,10 +42,12 @@ interface Sortable {
pinned?: boolean; 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) => { return items.slice().sort((a, b) => {
if (a.pinned && !b.pinned) return -1; const ak = get(a), bk = get(b);
if (!a.pinned && b.pinned) return 1; if (ak.pinned && !bk.pinned) return -1;
return b.date.getTime() - a.date.getTime(); 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 type { CollectionEntry } from 'astro:content';
import { DEFAULT_CATEGORY } from './consts'; import { DEFAULT_CATEGORY } from './consts';
import { sortEntries } from './format';
type Post = CollectionEntry<'md'>; type Post = CollectionEntry<'md'>;
@ -8,15 +9,6 @@ export function getSlug(postId: string): string {
return parts[parts.length - 1]; 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 }>( export function resolveRelatedPosts<T extends { id: string }>(
slugs: string[], slugs: string[],
allPosts: T[], allPosts: T[],
@ -25,7 +17,7 @@ export function resolveRelatedPosts<T extends { id: string }>(
return slugs.flatMap(s => bySlug.get(s) ?? []); return slugs.flatMap(s => bySlug.get(s) ?? []);
} }
export function organizePostsByCategory(posts: Post[], { sortAlphabetically = false } = {}): { export function organizePostsByCategory(posts: Post[]): {
grouped: Record<string, Post[]>; grouped: Record<string, Post[]>;
categories: string[]; categories: string[];
} { } {
@ -43,7 +35,7 @@ export function organizePostsByCategory(posts: Post[], { sortAlphabetically = fa
}); });
for (const category of categories) { for (const category of categories) {
grouped[category] = sortPosts(grouped[category], { alphabetically: sortAlphabetically }); grouped[category] = sortEntries(grouped[category], p => p.data);
} }
return { grouped, categories }; return { grouped, categories };

View file

@ -1,7 +1,7 @@
import fs from 'node:fs'; import fs from 'node:fs';
import path from 'node:path'; import path from 'node:path';
import yaml from 'js-yaml'; import yaml from 'js-yaml';
import { sortByPinnedThenDate } from './format'; import { sortEntries } from './format';
export interface TxtFile { export interface TxtFile {
name: string; name: string;
@ -44,6 +44,6 @@ export function getTxtFiles(): TxtFile[] {
pinned: pinnedSet.has(name), pinned: pinnedSet.has(name),
description: descriptions[name], description: descriptions[name],
})); }));
return sortByPinnedThenDate(files); return sortEntries(files);
} }