63 lines
1.6 KiB
TypeScript
63 lines
1.6 KiB
TypeScript
|
|
import { useMemo } from "react";
|
||
|
|
import type { Post } from "../../../types/post";
|
||
|
|
|
||
|
|
export type DayGroup = {
|
||
|
|
dayKey: string;
|
||
|
|
dayLabel: string;
|
||
|
|
items: Post[];
|
||
|
|
};
|
||
|
|
|
||
|
|
function localeFor(lang: string): string {
|
||
|
|
if (lang === "zh-TW") return "zh-TW";
|
||
|
|
if (lang === "zh-CN") return "zh-CN";
|
||
|
|
return "en-US";
|
||
|
|
}
|
||
|
|
|
||
|
|
function dayKey(iso: string): string {
|
||
|
|
const d = new Date(iso);
|
||
|
|
return `${d.getFullYear()}-${d.getMonth() + 1}-${d.getDate()}`;
|
||
|
|
}
|
||
|
|
|
||
|
|
function dayLabel(iso: string, lang: string): string {
|
||
|
|
const d = new Date(iso);
|
||
|
|
const today = new Date();
|
||
|
|
const yesterday = new Date();
|
||
|
|
yesterday.setDate(today.getDate() - 1);
|
||
|
|
const isSameDay = (a: Date, b: Date) =>
|
||
|
|
a.getFullYear() === b.getFullYear() &&
|
||
|
|
a.getMonth() === b.getMonth() &&
|
||
|
|
a.getDate() === b.getDate();
|
||
|
|
if (isSameDay(d, today)) {
|
||
|
|
if (lang === "en") return "Today";
|
||
|
|
return "今天";
|
||
|
|
}
|
||
|
|
if (isSameDay(d, yesterday)) {
|
||
|
|
if (lang === "en") return "Yesterday";
|
||
|
|
return "昨天";
|
||
|
|
}
|
||
|
|
return new Intl.DateTimeFormat(localeFor(lang), {
|
||
|
|
month: "long",
|
||
|
|
day: "numeric",
|
||
|
|
}).format(d);
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useGroupedByDay(posts: Post[], lang: string): DayGroup[] {
|
||
|
|
return useMemo(() => {
|
||
|
|
const groups: DayGroup[] = [];
|
||
|
|
const seen = new Map<string, DayGroup>();
|
||
|
|
for (const p of posts) {
|
||
|
|
const k = dayKey(p.publishedAt);
|
||
|
|
let g = seen.get(k);
|
||
|
|
if (!g) {
|
||
|
|
g = { dayKey: k, dayLabel: dayLabel(p.publishedAt, lang), items: [] };
|
||
|
|
seen.set(k, g);
|
||
|
|
groups.push(g);
|
||
|
|
}
|
||
|
|
g.items.push(p);
|
||
|
|
}
|
||
|
|
return groups;
|
||
|
|
}, [posts, lang]);
|
||
|
|
}
|
||
|
|
|
||
|
|
export { dayKey as _dayKey, dayLabel as _dayLabel };
|