返回 DeepSeek-Reasonix
historyPanelPresentation.ts
根目录 / desktop / frontend / src / lib / historyPanelPresentation.ts
1 import { t, useT } from "./i18n";
2 import { sessionActivityTime } from "./session";
3 import type { HistoryMessage, SessionMeta } from "./types";
4 import { historyMessagesToItems, type Item } from "./useController";
5
6 export function historyDayLabel(ms: number): string {
7 const startOfDay = (d: Date) => new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime();
8 const days = Math.round((startOfDay(new Date()) - startOfDay(new Date(ms))) / 86_400_000);
9 if (days <= 0) return t("history.today");
10 if (days === 1) return t("history.yesterday");
11 return new Date(ms).toLocaleDateString();
12 }
13
14 export function historyTimeLabel(ms: number): string {
15 return new Date(ms).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
16 }
17
18 export function historyDateBucket(ms: number): "today" | "yesterday" | "older" {
19 const startOfDay = (d: Date) => new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime();
20 const days = Math.round((startOfDay(new Date()) - startOfDay(new Date(ms))) / 86_400_000);
21 if (days <= 0) return "today";
22 if (days === 1) return "yesterday";
23 return "older";
24 }
25
26 export function historySessionTime(s: SessionMeta, trash: boolean): number {
27 return trash ? s.deletedAt || sessionActivityTime(s) : sessionActivityTime(s);
28 }
29
30 export function historySessionScope(s: SessionMeta): "project" | "global" {
31 return s.scope === "project" ? "project" : "global";
32 }
33
34 export function isChannelHistorySession(s: SessionMeta): boolean {
35 return s.kind === "channel" || s.sessionSource === "auto";
36 }
37
38 export function historySessionLocation(s: SessionMeta, tr: ReturnType<typeof useT>): string {
39 if (isChannelHistorySession(s)) return [s.channelLabel || s.channel || tr("history.channel"), s.remoteId].filter(Boolean).join(" · ");
40 if (s.workspaceRoot) {
41 const parts = s.workspaceRoot.split(/[\\/]/).filter(Boolean);
42 return parts[parts.length - 1] || s.workspaceRoot;
43 }
44 return historySessionScope(s) === "project" ? tr("history.filterProject") : tr("history.filterGlobal");
45 }
46
47 export function historySessionMetaLine(s: SessionMeta, tr: ReturnType<typeof useT>, trash = false): string {
48 const time = historyTimeLabel(historySessionTime(s, trash));
49 const suffix = trash && s.deletedAt ? ` · ${tr("history.deleted")}` : "";
50 const prefix = isChannelHistorySession(s) ? `${tr("history.channelReadOnly")} · ` : "";
51 const turns = s.turnsState === "unknown"
52 ? tr("history.indexing")
53 : tr(s.turns === 1 ? "history.turnOne" : "history.turnOther", { n: s.turns });
54 return `${prefix}${turns} · ${time}${suffix}`;
55 }
56
57 export function historyPreviewItems(messages: HistoryMessage[]): Item[] {
58 return historyMessagesToItems(messages, "hp").items;
59 }
60
60 lines TYPESCRIPT