121 lines
3.5 KiB
Plaintext
121 lines
3.5 KiB
Plaintext
---
|
|
import type { CollectionEntry, ContentEntryMap } from "astro:content";
|
|
import { getCollection, type CollectionKey } from "astro:content";
|
|
import CategorySummary from "./CategorySummary.astro";
|
|
|
|
import * as pinyinpro from "pinyin-pro";
|
|
|
|
interface Props {
|
|
collectionName: CollectionKey;
|
|
sortedByTimeline: boolean;
|
|
}
|
|
const { collectionName, sortedByTimeline } = Astro.props;
|
|
|
|
type CategoriedPosts = {
|
|
[categoryName: string]: Array<CollectionEntry<CollectionKey>>;
|
|
};
|
|
|
|
const allPosts: CollectionEntry<CollectionKey>[] =
|
|
await getCollection(collectionName);
|
|
|
|
const allCategories: Array<string> = Array.from(
|
|
new Set(
|
|
allPosts.map((entry) => {
|
|
return entry.data.category;
|
|
})
|
|
)
|
|
);
|
|
|
|
const categoriedPostList: Array<CategoriedPosts> = allCategories.map((key) => {
|
|
let object: CategoriedPosts = {};
|
|
object[key] = allPosts.filter((post) => post.data.category === key);
|
|
|
|
// article sort function by article title
|
|
function sortPostByTitlePinyin(
|
|
postA: CollectionEntry<CollectionKey>,
|
|
postB: CollectionEntry<CollectionKey>
|
|
): number {
|
|
let postATitle = pinyinpro.convert(pinyinpro.pinyin(postA.data.title), {
|
|
format: "symbolToNum",
|
|
});
|
|
let postBTitle = pinyinpro.convert(pinyinpro.pinyin(postB.data.title), {
|
|
format: "symbolToNum",
|
|
});
|
|
return postATitle.localeCompare(postBTitle, "en");
|
|
}
|
|
|
|
if (sortedByTimeline) {
|
|
// sort article by update date
|
|
object[key].sort((postA, postB) => {
|
|
// if two articles is updated on the same day, sort them by title
|
|
if (postA.data.lastUpdate !== postB.data.lastUpdate) {
|
|
return postA.data.lastUpdate < postB.data.lastUpdate ? 1 : -1;
|
|
}
|
|
return sortPostByTitlePinyin(postA, postB);
|
|
});
|
|
} else {
|
|
// sort article by title
|
|
// get articles with titles started in Chinese or the alphabet
|
|
let postWithAlphabetStartedTitle: CollectionEntry<keyof ContentEntryMap>[] =
|
|
object[key].filter((post) => /^[a-zA-Z]/.test(post.data.title));
|
|
let postWithChineseStartedTitle: CollectionEntry<keyof ContentEntryMap>[] =
|
|
object[key].filter((post) => /^[^a-zA-Z]/.test(post.data.title));
|
|
// sort two Array by article title
|
|
postWithAlphabetStartedTitle.sort((postA, postB) =>
|
|
sortPostByTitlePinyin(postA, postB)
|
|
);
|
|
postWithChineseStartedTitle.sort((postA, postB) =>
|
|
sortPostByTitlePinyin(postA, postB)
|
|
);
|
|
// articles that have title start with Chinese prior to
|
|
// those which have titles start with the alphabet
|
|
object[key] = postWithChineseStartedTitle.concat(
|
|
postWithAlphabetStartedTitle
|
|
);
|
|
}
|
|
return object;
|
|
});
|
|
|
|
const categoriedPostListSortedByArticleAmount: Array<CategoriedPosts> =
|
|
JSON.parse(JSON.stringify(categoriedPostList)).sort(
|
|
(a: CategoriedPosts, b: CategoriedPosts) => {
|
|
const aKey: string = Object.keys(a)[0];
|
|
const bKey: string = Object.keys(b)[0];
|
|
return b[bKey].length - a[aKey].length;
|
|
}
|
|
);
|
|
---
|
|
|
|
<div class="collection-desc">
|
|
{
|
|
categoriedPostListSortedByArticleAmount.map((obj) => (
|
|
<div class="collection-desc-item">
|
|
<CategorySummary
|
|
collectionName={collectionName}
|
|
categoryName={Object.keys(obj)[0]}
|
|
posts={obj[Object.keys(obj)[0]]}
|
|
/>
|
|
</div>
|
|
))
|
|
}
|
|
</div>
|
|
|
|
<style>
|
|
@media screen and (max-width: 125ex) {
|
|
.collection-desc-item {
|
|
width: 100%;
|
|
}
|
|
}
|
|
@media screen and (min-width: 125ex) {
|
|
.collection-desc-item {
|
|
width: 50%;
|
|
float: left;
|
|
}
|
|
}
|
|
.collection-desc::after {
|
|
display: block;
|
|
content: "";
|
|
clear: both;
|
|
}
|
|
</style>
|