fix(i18n): replace hardcoded Chinese strings in Session Manager

- Add i18n keys for relative time (justNow, minutesAgo, hoursAgo, daysAgo)
- Add i18n keys for role labels (roleUser, roleSystem, roleTool)
- Add i18n keys for UI elements (tocTitle, searchSessions, clickToCopyPath)
- Update formatRelativeTime and getRoleLabel to accept t function
- Add useTranslation hook to SessionToc component
This commit is contained in:
Jason
2026-02-02 12:15:05 +08:00
parent 68a0c304d8
commit d98183f3da
8 changed files with 58 additions and 19 deletions
+1 -1
View File
@@ -70,7 +70,7 @@ export function SessionItem({
<div className="flex items-center gap-1 text-[11px] text-muted-foreground">
<Clock className="size-3" />
<span>
{lastActive ? formatRelativeTime(lastActive) : t("common.unknown")}
{lastActive ? formatRelativeTime(lastActive, t) : t("common.unknown")}
</span>
</div>
</button>
@@ -288,7 +288,7 @@ export function SessionManagerPage() {
<Search className="size-3.5" />
</Button>
</TooltipTrigger>
<TooltipContent></TooltipContent>
<TooltipContent>{t("sessionManager.searchSessions")}</TooltipContent>
</Tooltip>
<Select
@@ -482,7 +482,7 @@ export function SessionManagerPage() {
{selectedSession.projectDir}
</p>
<p className="text-muted-foreground mt-1">
{t("sessionManager.clickToCopyPath")}
</p>
</TooltipContent>
</Tooltip>
@@ -59,7 +59,7 @@ export function SessionMessageItem({
</Tooltip>
<div className="flex items-center justify-between text-xs mb-1.5 pr-6">
<span className={cn("font-semibold", getRoleTone(message.role))}>
{getRoleLabel(message.role)}
{getRoleLabel(message.role, t)}
</span>
{message.ts && (
<span className="text-muted-foreground">
+6 -3
View File
@@ -1,4 +1,5 @@
import { List, X } from "lucide-react";
import { useTranslation } from "react-i18next";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import { ScrollArea } from "@/components/ui/scroll-area";
@@ -26,6 +27,7 @@ export function SessionTocSidebar({
items,
onItemClick,
}: SessionTocSidebarProps) {
const { t } = useTranslation();
if (items.length <= 2) return null;
return (
@@ -33,7 +35,7 @@ export function SessionTocSidebar({
<div className="p-3 border-b">
<div className="flex items-center gap-1.5 text-xs font-medium text-muted-foreground">
<List className="size-3.5" />
<span></span>
<span>{t("sessionManager.tocTitle")}</span>
</div>
</div>
<ScrollArea className="h-[calc(100%-40px)]">
@@ -74,6 +76,7 @@ export function SessionTocDialog({
open,
onOpenChange,
}: SessionTocDialogProps) {
const { t } = useTranslation();
if (items.length <= 2) return null;
return (
@@ -95,11 +98,11 @@ export function SessionTocDialog({
<DialogHeader className="px-4 py-3 relative border-b">
<DialogTitle className="flex items-center gap-2 text-base font-semibold">
<List className="size-4 text-primary" />
{t("sessionManager.tocTitle")}
</DialogTitle>
<DialogClose
className="absolute right-3 top-1/2 -translate-y-1/2 rounded-full p-1.5 hover:bg-muted transition-colors focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2"
aria-label="关闭"
aria-label={t("common.close")}
>
<X className="size-4 text-muted-foreground" />
</DialogClose>
+15 -9
View File
@@ -17,7 +17,10 @@ export const formatTimestamp = (value?: number) => {
return new Date(value).toLocaleString();
};
export const formatRelativeTime = (value?: number) => {
export const formatRelativeTime = (
value: number | undefined,
t: (key: string, options?: Record<string, unknown>) => string
) => {
if (!value) return "";
const now = Date.now();
const diff = now - value;
@@ -25,10 +28,10 @@ export const formatRelativeTime = (value?: number) => {
const hours = Math.floor(diff / 3600000);
const days = Math.floor(diff / 86400000);
if (minutes < 1) return "刚刚";
if (minutes < 60) return `${minutes} 分钟前`;
if (hours < 24) return `${hours} 小时前`;
if (days < 7) return `${days} 天前`;
if (minutes < 1) return t("sessionManager.justNow");
if (minutes < 60) return t("sessionManager.minutesAgo", { count: minutes });
if (hours < 24) return t("sessionManager.hoursAgo", { count: hours });
if (days < 7) return t("sessionManager.daysAgo", { count: days });
return new Date(value).toLocaleDateString();
};
@@ -57,12 +60,15 @@ export const getRoleTone = (role: string) => {
return "text-muted-foreground";
};
export const getRoleLabel = (role: string) => {
export const getRoleLabel = (
role: string,
t: (key: string) => string
) => {
const normalized = role.toLowerCase();
if (normalized === "assistant") return "AI";
if (normalized === "user") return "用户";
if (normalized === "system") return "系统";
if (normalized === "tool") return "工具";
if (normalized === "user") return t("sessionManager.roleUser");
if (normalized === "system") return t("sessionManager.roleSystem");
if (normalized === "tool") return t("sessionManager.roleTool");
return role;
};