Skip to content

Commit a892ed1

Browse files
committed
i18n: internationalize 37 hardcoded UI strings, fix 3 ZacharyZcR compatibility issues
- Added menu_label() calls for 37 hardcoded English strings across 18 files (zero_state blocks, conversation list, usage stats, notifications, resource center, MCP servers list, teams page, skills, SSH uploads, search) - Added 37 new keys to en.yml and ru.yml with Russian translations - Fixed 3 en.yml values to match ZacharyZcR/i18n-zh-cn canonical English - Updated corresponding hardcoded fallbacks in Rust code - Updated AGENTS.md with ZacharyZcR compatibility rules cargo check -p warp: 0 warnings. cargo test -p i18n: 9/9 pass.
1 parent be5e097 commit a892ed1

23 files changed

Lines changed: 295 additions & 55 deletions

File tree

app/src/ai/agent_management/notifications/toast_stack.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ fn render_keybinding_hint(keystroke: Keystroke, appearance: &Appearance) -> Box<
459459

460460
let hint_text = appearance
461461
.ui_builder()
462-
.wrappable_text("Open conversation".to_string(), false)
462+
.wrappable_text(crate::menu_label("agent.notifications.open_conversation", "Open conversation").to_string(), false)
463463
.with_style(UiComponentStyles {
464464
font_size: Some(12.),
465465
font_color: Some(theme.disabled_text_color(theme.surface_2()).into()),

app/src/ai/agent_management/notifications/view.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -128,11 +128,14 @@ impl NotificationMailboxView {
128128
});
129129

130130
let mark_all_read_button = ctx.add_typed_action_view(|_| {
131-
ActionButton::new(crate::menu_label("agent.notifications.mark_all_read", "Mark all as read"), NakedTheme)
132-
.with_size(ButtonSize::Small)
133-
.on_click(|ctx| {
134-
ctx.dispatch_typed_action(NotificationMailboxViewAction::MarkAllRead);
135-
})
131+
ActionButton::new(
132+
crate::menu_label("agent.notifications.mark_all_read", "Mark all as read"),
133+
NakedTheme,
134+
)
135+
.with_size(ButtonSize::Small)
136+
.on_click(|ctx| {
137+
ctx.dispatch_typed_action(NotificationMailboxViewAction::MarkAllRead);
138+
})
136139
});
137140

138141
Self {
@@ -546,7 +549,11 @@ impl NotificationMailboxView {
546549
Container::new(
547550
appearance
548551
.ui_builder()
549-
.wrappable_text("No notifications".to_string(), false)
552+
.wrappable_text(
553+
crate::menu_label("agent.notifications.no_notifications", "No notifications")
554+
.to_string(),
555+
false,
556+
)
550557
.with_style(UiComponentStyles {
551558
font_size: Some(14.),
552559
font_color: Some(theme.sub_text_color(theme.surface_2()).into()),

app/src/ai/blocklist/agent_view/agent_message_bar.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,7 @@ impl MessageProvider<AgentMessageArgs<'_>> for BootstrappingMessageProducer {
462462
{
463463
None
464464
} else {
465-
Some(Message::from_text("Starting shell..."))
465+
Some(Message::from_text(crate::menu_label("agent.message_bar.starting_shell", "Starting shell...")))
466466
}
467467
}
468468
}

app/src/ai/blocklist/agent_view/zero_state_block.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -411,8 +411,11 @@ impl View for AgentViewZeroStateBlock {
411411
icon: Icon::OzCloud,
412412
}
413413
} else {
414-
let mut local_description =
415-
"Send a prompt below to start a new conversation".to_owned();
414+
let mut local_description = crate::menu_label(
415+
"agent.zero_state.send_prompt",
416+
"Send a prompt below to start a new conversation",
417+
)
418+
.to_owned();
416419
let active_session = self.active_session(app);
417420
let location_label = active_session.as_deref().and_then(|session| {
418421
format_session_location(session, self.current_working_directory.as_deref())
@@ -422,7 +425,11 @@ impl View for AgentViewZeroStateBlock {
422425
}
423426

424427
HeaderProps {
425-
title: "New Oz agent conversation".into(),
428+
title: crate::menu_label(
429+
"agent.zero_state.new_conversation",
430+
"New Oz agent conversation",
431+
)
432+
.into(),
426433
description: AgentViewDescription::PlainText(vec![local_description.into()]),
427434
icon: Icon::Oz,
428435
}

app/src/ai/blocklist/block/view_impl/output.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1339,7 +1339,7 @@ fn render_search_codebase(
13391339
RadioButtonItem::text(
13401340
"Always allow file access for coding tasks",
13411341
),
1342-
RadioButtonItem::text("Always allow file access for this repo"),
1342+
RadioButtonItem::text(crate::menu_label("agent.output.always_allow_file_access", "Always allow file access for this repo")),
13431343
],
13441344
props
13451345
.state_handles
@@ -2372,7 +2372,7 @@ fn create_formatted_text_for_grep(
23722372
.expect("Queries slice should have an element");
23732373
let mut fragments = if is_cancelled || is_queued {
23742374
vec![
2375-
FormattedTextFragment::plain_text("Grep for "),
2375+
FormattedTextFragment::plain_text(crate::menu_label("agent.output.grep_for", "Grep for ")),
23762376
FormattedTextFragment::inline_code(query),
23772377
]
23782378
} else {
@@ -2469,7 +2469,7 @@ fn create_formatted_text_for_file_glob(
24692469

24702470
let mut fragments = if is_cancelled || is_queued {
24712471
vec![
2472-
FormattedTextFragment::plain_text("Search for files that match "),
2472+
FormattedTextFragment::plain_text(crate::menu_label("agent.output.search_files", "Search for files that match ")),
24732473
FormattedTextFragment::inline_code(pattern),
24742474
]
24752475
} else {

app/src/ai/blocklist/inline_action/search_codebase.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,12 @@ impl SearchCodebaseView {
241241
font_size: Some(appearance.monospace_font_size()),
242242
..Default::default()
243243
};
244-
self.render_formatted_text("No results found".to_string(), no_results_style, appearance)
244+
self.render_formatted_text(
245+
crate::menu_label("agent.search_codebase.no_results", "No results found")
246+
.to_string(),
247+
no_results_style,
248+
appearance,
249+
)
245250
} else {
246251
render_read_files_text(
247252
render_read_file_args,

app/src/ai/blocklist/usage/conversation_usage_view.rs

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -301,14 +301,20 @@ impl ConversationUsageView {
301301
appearance,
302302
));
303303

304-
labels.push(render_label_text("Credits spent (total)", appearance));
304+
labels.push(render_label_text(
305+
&crate::menu_label("agent.usage.credits_total", "Credits spent (total)"),
306+
appearance,
307+
));
305308
values.push(self.render_total_credits_value_row(
306309
total_credits_value,
307310
rollup.as_ref(),
308311
appearance,
309312
));
310313
} else {
311-
labels.push(render_label_text("Credits spent", appearance));
314+
labels.push(render_label_text(
315+
&crate::menu_label("agent.usage.credits_spent", "Credits spent"),
316+
appearance,
317+
));
312318
values.push(self.render_total_credits_value_row(
313319
total_credits_value,
314320
rollup.as_ref(),
@@ -324,7 +330,10 @@ impl ConversationUsageView {
324330
// existing flex spacing handles indentation.
325331
self.append_per_agent_rows(&mut labels, &mut values, rollup.as_ref(), appearance);
326332

327-
labels.push(render_label_text("Tool calls", appearance));
333+
labels.push(render_label_text(
334+
&crate::menu_label("agent.usage.tool_calls", "Tool calls"),
335+
appearance,
336+
));
328337
values.push(render_value_text(
329338
format_value_text(self.usage_info.tool_calls, "call"),
330339
appearance,
@@ -422,7 +431,10 @@ impl ConversationUsageView {
422431
);
423432
}
424433

425-
labels.push(render_label_text("Context window used", appearance));
434+
labels.push(render_label_text(
435+
&crate::menu_label("agent.usage.context_window", "Context window used"),
436+
appearance,
437+
));
426438
let context_usage_str =
427439
format!("{}%", (self.usage_info.context_window_usage * 100.).round());
428440
let context_window_element = Flex::row()
@@ -465,13 +477,19 @@ impl ConversationUsageView {
465477
));
466478
values.push(render_section_header("".to_string(), appearance));
467479

468-
labels.push(render_label_text("Files changed", appearance));
480+
labels.push(render_label_text(
481+
&crate::menu_label("agent.usage.files_changed", "Files changed"),
482+
appearance,
483+
));
469484
values.push(render_value_text(
470485
format_value_text(self.usage_info.files_changed, "file"),
471486
appearance,
472487
));
473488

474-
labels.push(render_label_text("Diffs applied", appearance));
489+
labels.push(render_label_text(
490+
&crate::menu_label("agent.usage.diffs_applied", "Diffs applied"),
491+
appearance,
492+
));
475493
let diffs_element = Flex::row()
476494
.with_cross_axis_alignment(CrossAxisAlignment::Center)
477495
.with_child(
@@ -508,7 +526,10 @@ impl ConversationUsageView {
508526
.finish();
509527
values.push(diffs_element);
510528

511-
labels.push(render_label_text("Commands executed", appearance));
529+
labels.push(render_label_text(
530+
&crate::menu_label("agent.usage.commands_executed", "Commands executed"),
531+
appearance,
532+
));
512533
values.push(render_value_text(
513534
format_value_text(self.usage_info.commands_executed, "command"),
514535
appearance,
@@ -540,7 +561,13 @@ impl ConversationUsageView {
540561
));
541562
values.push(render_section_header("".to_string(), appearance));
542563

543-
labels.push(render_label_text("Time to first token", appearance));
564+
labels.push(render_label_text(
565+
&crate::menu_label(
566+
"agent.usage.time_to_first_token",
567+
"Time to first token",
568+
),
569+
appearance,
570+
));
544571
values.push(render_value_text(
545572
format!(
546573
"{:.1} seconds",
@@ -549,7 +576,13 @@ impl ConversationUsageView {
549576
appearance,
550577
));
551578

552-
labels.push(render_label_text("Total agent response time", appearance));
579+
labels.push(render_label_text(
580+
&crate::menu_label(
581+
"agent.usage.total_response_time",
582+
"Total agent response time",
583+
),
584+
appearance,
585+
));
553586
values.push(render_value_text(
554587
format!(
555588
"{:.1} seconds",

app/src/app_menus.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -843,7 +843,7 @@ fn debug_menu_items() -> Vec<MenuItem> {
843843
}) {
844844
crate::menu_label(
845845
"menu.disable_in_band_generators",
846-
"Disable In-band Generators for New Sessions",
846+
"Disable in-band generators for new sessions",
847847
)
848848
} else {
849849
crate::menu_label(

app/src/auth/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ pub fn maybe_log_out(app: &mut AppContext) {
9797
{
9898
send_telemetry_sync_from_app_ctx!(TelemetryEvent::LogOutModalShown, app);
9999
let mut button_data = vec![ModalButton::for_app(
100-
crate::menu_label("auth.log_out_confirm", "Yes, log out"),
100+
crate::menu_label("auth.log_out_confirm", "Log out?"),
101101
|ctx| {
102102
log_out(ctx);
103103
},

app/src/notebooks/editor/view.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2838,7 +2838,7 @@ impl TypedActionView for RichTextEditorView {
28382838
crate::workspace::ToastStack::handle(ctx).update(ctx, |toast_stack, ctx| {
28392839
let toast = DismissibleToast::default(crate::menu_label(
28402840
"notebook.link_copied",
2841-
"Link copied",
2841+
"Link copied to clipboard",
28422842
));
28432843
toast_stack.add_ephemeral_toast(toast, window_id, ctx);
28442844
});

0 commit comments

Comments
 (0)