fix(i18n): translate the GitHub pull request operations' progress and failure titles (#1169)

The GitHub tool window's long operations passed an untagged banner title and appended " failed" for the error, so the banner stayed English and failures read half translated. withBusy now takes a tx-tagged progress title and its own failure title per operation (checkout, fetch for diff, worktree, apply/commit suggestion, resolve thread).
This commit is contained in:
l0ng-ai
2026-11-04 12:02:06 +08:00
committed by GitHub
parent d3b9a39831
commit c5e188d1e3
3 changed files with 33 additions and 10 deletions
+15 -6
View File
@@ -23,9 +23,12 @@ export const useGhBusy = create<{ busy: { title: string; line: string; request:
busy: null,
}));
/** Runs a cancellable, streaming gh / git operation; null when it failed, was cancelled or another one runs. */
/**
* Runs a cancellable, streaming gh / git operation; null when it failed, was cancelled or another one runs.
* `title` shows in the banner while it runs, `failure` titles the error notification.
*/
export async function withBusy<T>(
title: string,
{ title, failure }: { title: string; failure: string },
run: (request: RequestId, out: Channel<string>) => Promise<T>,
): Promise<T | null> {
if (useGhBusy.getState().busy) {
@@ -48,7 +51,7 @@ export async function withBusy<T>(
notifications().notify({
group: "vcs",
level: "error",
title: `${title.replace(/…$/, "")} failed`,
title: failure,
body: errorMessage(e),
key: "github-op",
});
@@ -66,7 +69,8 @@ export function cancelBusy() {
/** "Checkout Branch": fetches and checks out the pull request's branch (gh's local name). */
export async function checkoutPullRequest(number: number): Promise<boolean> {
// The command resolves with nothing (`null`), which `withBusy` reports as a failure.
const done = await withBusy(`Checking out #${number}…`, async (r, out) => {
const op = { title: tx`Checking out #${number}…`, failure: tx`Couldn't check out #${number}` };
const done = await withBusy(op, async (r, out) => {
await call(commands.ghPrCheckout(connectedRoot(), r, number, out));
return true;
});
@@ -89,7 +93,8 @@ export async function prepareDiff(pr: GHPullRequest): Promise<PrDiffRevisions |
if (hit) return hit;
const { coordinates, root } = requireConnection();
const repo = nameWithOwner(coordinates);
const revs = await withBusy(`Fetching #${pr.number}…`, (r, out) =>
const op = { title: tx`Fetching #${pr.number}…`, failure: tx`Couldn't fetch #${pr.number}` };
const revs = await withBusy(op, (r, out) =>
call(commands.ghPrPrepareDiff(root, r, pr.number, pr.headRefOid, pr.baseRefOid, pr.baseRefName, repo, out)),
);
if (revs) diffCache.set(key, revs);
@@ -185,7 +190,11 @@ export async function openInWorktree(number: number): Promise<void> {
const revs = await prepareDiff(pr);
if (!revs) return;
const path = `${String(revs.root).replace(/[\\/]+$/, "")}_PR_${number}`;
const added = await withBusy(`Creating worktree for #${number}…`, async () => {
const op = {
title: tx`Creating worktree for #${number}…`,
failure: tx`Couldn't create the worktree for #${number}`,
};
const added = await withBusy(op, async () => {
await call(commands.vcsAddWorktree(revs.root, path, pr.headRefOid, null));
return true;
});
@@ -31,8 +31,10 @@ export async function applySuggestion(
suggestion: readonly string[],
commitMessage?: string,
): Promise<boolean> {
const title = commitMessage ? tx("Committing suggested change") : tx("Applying suggested change");
const done = await withBusy(title, async () => {
const op = commitMessage
? { title: tx("Committing suggested change"), failure: tx("Couldn't commit the suggested change") }
: { title: tx("Applying suggested change"), failure: tx("Couldn't apply the suggested change") };
const done = await withBusy(op, async () => {
const root = await repositoryRoot();
const abs = `${root}/${target.path}`;
const text = await call(commands.fsReadText(abs));
@@ -61,7 +63,10 @@ export async function applySuggestion(
return true;
});
if (!done) return false;
if (thread.viewerCanResolve) await withBusy(tx("Resolving thread"), () => resolveThread(number, thread.id));
if (thread.viewerCanResolve)
await withBusy({ title: tx("Resolving thread"), failure: tx("Couldn't resolve the thread") }, () =>
resolveThread(number, thread.id),
);
return true;
}
+10 -1
View File
@@ -5912,5 +5912,14 @@
"Delete shelved changes “{name}”": "删除搁置的更改“{name}”",
"Rename shelved changes": "重命名搁置的更改",
"Passed to the agent process, replacing variables of the same name. Changes apply to new sessions.": "传给智能体进程,覆盖同名变量。对新会话生效。",
"Expected NAME=value: {pair}": "应为 NAME=value:{pair}"
"Expected NAME=value: {pair}": "应为 NAME=value:{pair}",
"Checking out #{number}…": "正在检出 #{number}…",
"Couldn't check out #{number}": "无法检出 #{number}",
"Fetching #{number}…": "正在获取 #{number}…",
"Couldn't fetch #{number}": "无法获取 #{number}",
"Creating worktree for #{number}…": "正在为 #{number} 创建工作树…",
"Couldn't create the worktree for #{number}": "无法为 #{number} 创建工作树",
"Couldn't commit the suggested change": "无法提交建议的更改",
"Couldn't apply the suggested change": "无法应用建议的更改",
"Couldn't resolve the thread": "无法解决讨论串"
}