refactor: deduplicates our sorting function
This commit is contained in:
parent
8209d036cd
commit
384ca71f89
3 changed files with 14 additions and 19 deletions
|
|
@ -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();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 };
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue