diff --git a/src/features/project-tree/operations.ts b/src/features/project-tree/operations.ts index 09b1938d..528dc3b0 100644 --- a/src/features/project-tree/operations.ts +++ b/src/features/project-tree/operations.ts @@ -294,8 +294,14 @@ async function refreshAfterCreate(parent: string, path: string) { // --------------------------------------------------------------------------- // Delete -function describe(paths: string[]): string { - return paths.length === 1 ? `'${nameOf(paths[0]!)}'` : `${paths.length} items`; +/** The Delete dialog's question, e.g. "Delete 'src' and its contents?". */ +function deleteQuestion(paths: string[], folders: boolean): string { + if (paths.length === 1) { + const name = nameOf(paths[0]!); + return folders ? tx`Delete '${name}' and its contents?` : tx`Delete '${name}'?`; + } + const count = paths.length; + return folders ? tx`Delete ${count} items (including folder contents)?` : tx`Delete ${count} items?`; } /** Visible rows in display order (roots, then children of expanded folders). */ @@ -441,9 +447,9 @@ export async function deleteSelection(nodes: ProjectNode[] = selectedNodes()) { message: createElement( Fragment, null, - `Delete ${describe(paths)}${folders ? (paths.length === 1 ? " and its contents" : " (including folder contents)") : ""}?`, + deleteQuestion(paths, folders > 0), createElement("br"), - "Items are moved to the Trash.", + tx("Items are moved to the Trash."), ), }); if (!answer) return; diff --git a/src/features/settings/keymap/StrokeRecorder.tsx b/src/features/settings/keymap/StrokeRecorder.tsx index c6d9500a..0fe7afb2 100644 --- a/src/features/settings/keymap/StrokeRecorder.tsx +++ b/src/features/settings/keymap/StrokeRecorder.tsx @@ -5,6 +5,7 @@ import { forwardRef, useEffect, useRef, type KeyboardEvent } from "react"; import clsx from "clsx"; import { formatBinding, strokeOf, suspendKeyboardDispatch } from "@/platform/keymap"; +import { T } from "@/ui"; import styles from "./Keymap.module.css"; export interface StrokeRecorderProps { @@ -81,7 +82,9 @@ export const StrokeRecorder = forwardRef(fu {value ? ( {formatBinding(value)} ) : ( - {placeholder} + + {placeholder} + )} ); diff --git a/src/features/vcs/dialogs.tsx b/src/features/vcs/dialogs.tsx index d976a8c7..401c0236 100644 --- a/src/features/vcs/dialogs.tsx +++ b/src/features/vcs/dialogs.tsx @@ -94,7 +94,11 @@ function PromptDialog(props: PromptOptions & { onDone: (r: PromptResult | null) submit(); }} > - {label && } + {label && ( + + )} {customLabel && ( <> - + setCustom(e.target.value)} /> )} diff --git a/src/platform/locales/text/zh.json b/src/platform/locales/text/zh.json index 837a4513..aa6fcb9e 100644 --- a/src/platform/locales/text/zh.json +++ b/src/platform/locales/text/zh.json @@ -649,6 +649,11 @@ "Default value": "默认值", "Definition": "定义", "Delete": "删除", + "Delete '{name}'?": "删除 '{name}'?", + "Delete '{name}' and its contents?": "删除 '{name}' 及其内容?", + "Delete {count} items?": "删除 {count} 个项目?", + "Delete {count} items (including folder contents)?": "删除 {count} 个项目(包括文件夹内容)?", + "Items are moved to the Trash.": "项目将被移到回收站。", "Delete Anyway": "仍然删除", "Delete Bookmark": "删除书签", "Delete Branch": "删除分支",