Complete client UI i18n migration

Adds client-side i18n support, language settings, translated UI copy, and locale parity coverage.
This commit is contained in:
chyendongnhanh338
2026-06-11 14:15:35 +08:00
committed by GitHub
parent 41cf070fd8
commit 08ebe5e7e1
199 changed files with 16426 additions and 1821 deletions
+18 -9
View File
@@ -1,6 +1,7 @@
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import type { TextInput } from "react-native";
import { router, usePathname, type Href } from "expo-router";
import { useTranslation } from "react-i18next";
import { useKeyboardShortcutsStore } from "@/stores/keyboard-shortcuts-store";
import { keyboardActionDispatcher } from "@/keyboard/keyboard-action-dispatcher";
import { useAllAgentsList } from "@/hooks/use-all-agents-list";
@@ -52,7 +53,10 @@ function sortAgents(left: AggregatedAgent, right: AggregatedAgent): number {
interface CommandCenterActionDefinition {
id: string;
title: string;
titleKey:
| "shell.commandCenter.openProject"
| "shell.commandCenter.home"
| "sidebar.actions.settings";
icon?: "plus" | "settings" | "home";
actionId?: string;
keywords: string[];
@@ -62,7 +66,7 @@ interface CommandCenterActionDefinition {
const COMMAND_CENTER_ACTIONS: readonly CommandCenterActionDefinition[] = [
{
id: "new-agent",
title: "Open project",
titleKey: "shell.commandCenter.openProject",
icon: "plus",
actionId: "new-agent",
keywords: ["open", "project", "folder", "workspace", "repo"],
@@ -70,24 +74,28 @@ const COMMAND_CENTER_ACTIONS: readonly CommandCenterActionDefinition[] = [
},
{
id: "home",
title: "Home",
titleKey: "shell.commandCenter.home",
icon: "home",
keywords: ["home", "start", "import", "session", "pair", "device", "providers"],
routeKind: "home",
},
{
id: "settings",
title: "Settings",
titleKey: "sidebar.actions.settings",
icon: "settings",
keywords: ["settings", "preferences", "config", "configuration"],
routeKind: "settings",
},
];
function matchesActionQuery(query: string, action: CommandCenterActionDefinition): boolean {
function matchesActionQuery(
query: string,
action: CommandCenterActionDefinition,
title: string,
): boolean {
const normalized = query.trim().toLowerCase();
if (!normalized) return true;
if (action.title.toLowerCase().includes(normalized)) {
if (title.toLowerCase().includes(normalized)) {
return true;
}
return action.keywords.some((keyword) => keyword.includes(normalized));
@@ -129,6 +137,7 @@ function resolveActionShortcutKeys(
}
export function useCommandCenter() {
const { t } = useTranslation();
const pathname = usePathname();
const routeActiveServerId = useActiveServerId();
const { overrides } = useKeyboardShortcutOverrides();
@@ -174,7 +183,7 @@ export function useCommandCenter() {
}
return COMMAND_CENTER_ACTIONS.filter((action) => {
if (action.routeKind === "home" && !homeRoute) return false;
return matchesActionQuery(query, action);
return matchesActionQuery(query, action, t(action.titleKey));
}).map<CommandCenterActionItem>((action) => {
let route: Href | undefined;
if (action.routeKind === "settings") route = settingsRoute;
@@ -182,13 +191,13 @@ export function useCommandCenter() {
return {
kind: "action",
id: action.id,
title: action.title,
title: t(action.titleKey),
icon: action.icon,
route,
shortcutKeys: resolveActionShortcutKeys(action.actionId, overrides),
};
});
}, [open, query, settingsRoute, homeRoute, overrides]);
}, [open, query, settingsRoute, homeRoute, overrides, t]);
const items = useMemo(() => {
if (!open) {