import type { ChatSession } from "@/lib/home-types"; export const SESSION_RECENCY_LABELS = { today: "今天", yesterday: "昨天", week: "最近 7 天", month: "最近 30 天", older: "更早", } as const; export type SessionRecencyKey = keyof typeof SESSION_RECENCY_LABELS; export type SessionRecencyGroup = { readonly key: SessionRecencyKey; readonly label: string; readonly sessions: readonly T[]; }; function startOfLocalDay(now: Date): number { return new Date(now.getFullYear(), now.getMonth(), now.getDate()).getTime(); } export function sortSessions(sessions: readonly T[]): T[] { return sessions .map((session, index) => ({ session, index })) .sort((left, right) => { const pinned = Number(right.session.pinned) - Number(left.session.pinned); if (pinned !== 0) return pinned; const time = right.session.updatedAt - left.session.updatedAt; if (time !== 0) return time; return left.index - right.index; }) .map((item) => item.session); } export function recencyKeyFor(updatedAt: number, now = Date.now()): SessionRecencyKey { const todayStart = startOfLocalDay(new Date(now)); const dayMs = 24 * 60 * 60 * 1000; if (updatedAt >= todayStart) return "today"; if (updatedAt >= todayStart - dayMs) return "yesterday"; if (updatedAt >= todayStart - 6 * dayMs) return "week"; if (updatedAt >= todayStart - 29 * dayMs) return "month"; return "older"; } export function groupSessionsByRecency( sessions: readonly T[], now = Date.now(), ): SessionRecencyGroup[] { const buckets: Record = { today: [], yesterday: [], week: [], month: [], older: [], }; for (const session of sessions) { buckets[recencyKeyFor(session.updatedAt, now)].push(session); } const order: SessionRecencyKey[] = ["today", "yesterday", "week", "month", "older"]; return order.flatMap((key) => { const group = buckets[key]; if (group.length === 0) return []; return [{ key, label: SESSION_RECENCY_LABELS[key], sessions: group }]; }); } export function mergeSessionPage( existing: readonly T[], incoming: readonly T[], ): T[] { const seen = new Map(existing.map((session) => [session.id, session])); const next = [...existing]; for (const row of incoming) { const current = seen.get(row.id); if (current) continue; seen.set(row.id, row); next.push(row); } return next; } export function beginSessionPageLoad( inFlight: { current: boolean }, cursor: string | null, ): boolean { if (inFlight.current || !cursor) return false; inFlight.current = true; return true; }