This commit is contained in:
parent
b1ebe2ad57
commit
561b28bebf
6 changed files with 223 additions and 38 deletions
52
src/lib/admin-speeches.ts
Normal file
52
src/lib/admin-speeches.ts
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
import type { ArchiveEntry } from "./archive";
|
||||
|
||||
export type SpeechAdminEntry = {
|
||||
id: string;
|
||||
path: string;
|
||||
title: string;
|
||||
publishedDate: string;
|
||||
speechYear: string;
|
||||
speaker: "rev" | "mrs" | "other";
|
||||
source: string;
|
||||
categories: string[];
|
||||
tags: string[];
|
||||
bodyUrl: string;
|
||||
};
|
||||
|
||||
function encodePath(value: string): string {
|
||||
return value.split("/").map(encodeURIComponent).join("/");
|
||||
}
|
||||
|
||||
export function speechAdminEntryFromArchiveEntry(entry: ArchiveEntry, fallbackDate: string): SpeechAdminEntry {
|
||||
const categories = entry.data.categories ?? [];
|
||||
const tags = entry.data.tags ?? [];
|
||||
const publishedDate = entry.data.published?.slice(0, 10) ?? fallbackDate;
|
||||
const speechYear = entry.data.speechYear ?? entry.id.match(/\b(1\d{3}|20\d{2})\b/)?.[1] ?? new Date().getFullYear().toString();
|
||||
const categoryText = categories.join(" ").toLowerCase();
|
||||
const collection = entry.data.speechCollection ?? "";
|
||||
const speaker = categoryText.includes("hak ja han") || collection === "mrs-hak-ja-han-moon"
|
||||
? "mrs"
|
||||
: categoryText.includes("rev sun myung moon") || /^\d{4}$/.test(collection) || /^\d{4}$/.test(speechYear)
|
||||
? "rev"
|
||||
: "other";
|
||||
|
||||
return {
|
||||
id: entry.id,
|
||||
path: `content/${entry.id}.md`,
|
||||
title: entry.data.title ?? entry.id,
|
||||
publishedDate,
|
||||
speechYear,
|
||||
speaker,
|
||||
source: entry.data.source ?? "",
|
||||
categories,
|
||||
tags,
|
||||
bodyUrl: `/admin/content/${encodePath(entry.id)}.json`,
|
||||
};
|
||||
}
|
||||
|
||||
export function speechAdminEntryWithBody(entry: ArchiveEntry, fallbackDate: string) {
|
||||
return {
|
||||
...speechAdminEntryFromArchiveEntry(entry, fallbackDate),
|
||||
body: entry.body ?? "",
|
||||
};
|
||||
}
|
||||
|
|
@ -32,6 +32,14 @@ export type SpeechArchiveItem = {
|
|||
searchText: string;
|
||||
};
|
||||
|
||||
export type SpeechSearchIndexItem = Omit<SpeechArchiveItem, "searchText">;
|
||||
|
||||
export type CompactSpeechSearchIndex = {
|
||||
version: 2;
|
||||
items: SpeechSearchIndexItem[];
|
||||
index: Record<string, string>;
|
||||
};
|
||||
|
||||
const entityMap: Record<string, string> = {
|
||||
amp: "&",
|
||||
apos: "'",
|
||||
|
|
@ -215,6 +223,39 @@ export function getSpeechArchive(): SpeechArchiveItem[] {
|
|||
});
|
||||
}
|
||||
|
||||
function packDocumentIds(documentIds: number[]): string {
|
||||
return documentIds.map((documentId) => documentId.toString(36)).join(",");
|
||||
}
|
||||
|
||||
export function getCompactSpeechSearchIndex(): CompactSpeechSearchIndex {
|
||||
const items = getSpeechArchive();
|
||||
const index = new Map<string, number[]>();
|
||||
|
||||
items.forEach((item, documentId) => {
|
||||
const terms = new Set(item.searchText.match(/[a-z0-9]+/g) ?? []);
|
||||
|
||||
terms.forEach((term) => {
|
||||
if (term.length < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
const documentIds = index.get(term) ?? [];
|
||||
documentIds.push(documentId);
|
||||
index.set(term, documentIds);
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
version: 2,
|
||||
items: items.map(({ searchText, ...item }) => item),
|
||||
index: Object.fromEntries(
|
||||
Array.from(index)
|
||||
.sort(([a], [b]) => a.localeCompare(b))
|
||||
.map(([term, documentIds]) => [term, packDocumentIds(documentIds)]),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
export function uniqueSorted(values: string[], direction: "asc" | "desc" = "asc"): string[] {
|
||||
const unique = Array.from(new Set(values.filter(Boolean)));
|
||||
return unique.sort((a, b) => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue