Complete client UI i18n migration
Adds client-side i18n support, language settings, translated UI copy, and locale parity coverage.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { Image, Text, View } from "react-native";
|
||||
import { StyleSheet } from "react-native-unistyles";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { createNameId } from "mnemonic-id";
|
||||
import { AdaptiveModalSheet, type SheetHeader } from "@/components/adaptive-modal-sheet";
|
||||
import { Composer } from "@/composer";
|
||||
@@ -96,8 +97,13 @@ async function callWorkspaceCreation({
|
||||
return connectedClient.openProject(input.cwd);
|
||||
}
|
||||
|
||||
function failureMessageForCreationMethod(method: "create_worktree" | "open_project") {
|
||||
return method === "create_worktree" ? "Failed to create worktree" : "Failed to open project";
|
||||
function failureMessageForCreationMethod(
|
||||
method: "create_worktree" | "open_project",
|
||||
t: ReturnType<typeof useTranslation>["t"],
|
||||
) {
|
||||
return method === "create_worktree"
|
||||
? t("workspaceSetup.errors.failedCreateWorktree")
|
||||
: t("workspaceSetup.errors.failedOpenProject");
|
||||
}
|
||||
|
||||
function buildCreateAgentOptions({
|
||||
@@ -140,6 +146,7 @@ function buildCreateAgentOptions({
|
||||
}
|
||||
|
||||
export function WorkspaceSetupDialog() {
|
||||
const { t } = useTranslation();
|
||||
const toast = useToast();
|
||||
const pendingWorkspaceSetup = useWorkspaceSetupStore((state) => state.pendingWorkspaceSetup);
|
||||
const clearWorkspaceSetup = useWorkspaceSetupStore((state) => state.clearWorkspaceSetup);
|
||||
@@ -170,7 +177,7 @@ export function WorkspaceSetupDialog() {
|
||||
});
|
||||
const composerState = chatDraft.composerState;
|
||||
if (!composerState && pendingWorkspaceSetup) {
|
||||
throw new Error("Workspace setup composer state is required");
|
||||
throw new Error(t("workspaceSetup.errors.composerStateRequired"));
|
||||
}
|
||||
|
||||
const { icon: projectIcon } = useProjectIconQuery({
|
||||
@@ -218,15 +225,15 @@ export function WorkspaceSetupDialog() {
|
||||
|
||||
const withConnectedClient = useCallback(() => {
|
||||
if (!client || !isConnected) {
|
||||
throw new Error("Host is not connected");
|
||||
throw new Error(t("workspaceSetup.errors.hostDisconnected"));
|
||||
}
|
||||
return client;
|
||||
}, [client, isConnected]);
|
||||
}, [client, isConnected, t]);
|
||||
|
||||
const ensureWorkspace = useCallback(
|
||||
async (input: { cwd: string; attachments: MessagePayload["attachments"] }) => {
|
||||
if (!pendingWorkspaceSetup) {
|
||||
throw new Error("No workspace setup is pending");
|
||||
throw new Error(t("workspaceSetup.errors.pendingRequired"));
|
||||
}
|
||||
|
||||
if (createdWorkspace) {
|
||||
@@ -242,7 +249,7 @@ export function WorkspaceSetupDialog() {
|
||||
|
||||
if (payload.error || !payload.workspace) {
|
||||
throw new Error(
|
||||
payload.error ?? failureMessageForCreationMethod(pendingWorkspaceSetup.creationMethod),
|
||||
payload.error ?? failureMessageForCreationMethod(pendingWorkspaceSetup.creationMethod, t),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -259,6 +266,7 @@ export function WorkspaceSetupDialog() {
|
||||
mergeWorkspaces,
|
||||
pendingWorkspaceSetup,
|
||||
setHasHydratedWorkspaces,
|
||||
t,
|
||||
withConnectedClient,
|
||||
],
|
||||
);
|
||||
@@ -284,10 +292,10 @@ export function WorkspaceSetupDialog() {
|
||||
const ensuredWorkspace = await ensureWorkspace({ cwd, attachments });
|
||||
const connectedClient = withConnectedClient();
|
||||
if (!composerState) {
|
||||
throw new Error("Workspace setup composer state is required");
|
||||
throw new Error(t("workspaceSetup.errors.composerStateRequired"));
|
||||
}
|
||||
if (!composerState.selectedProvider) {
|
||||
throw new Error("Select a model");
|
||||
throw new Error(t("workspaceSetup.errors.selectModel"));
|
||||
}
|
||||
|
||||
const wirePayload = splitComposerAttachmentsForSubmit(attachments);
|
||||
@@ -334,6 +342,7 @@ export function WorkspaceSetupDialog() {
|
||||
serverId,
|
||||
setAgents,
|
||||
ensureWorkspace,
|
||||
t,
|
||||
toast,
|
||||
withConnectedClient,
|
||||
],
|
||||
@@ -392,8 +401,8 @@ export function WorkspaceSetupDialog() {
|
||||
);
|
||||
|
||||
const sheetHeader = useMemo<SheetHeader>(
|
||||
() => ({ title: "Create workspace", subtitle: subtitleContent }),
|
||||
[subtitleContent],
|
||||
() => ({ title: t("workspaceSetup.title"), subtitle: subtitleContent }),
|
||||
[subtitleContent, t],
|
||||
);
|
||||
|
||||
if (!pendingWorkspaceSetup || !sourceDirectory) {
|
||||
|
||||
Reference in New Issue
Block a user