feat(shell-core): thread localised strings through LayerPanel + AIChatPanel paint
Theme + locale toggle infrastructure landed in ed36df56, but the visible chrome strings were still hardcoded so flipping the Globe icon didn't actually change anything. Now: - LayerPanel resolves '页面' / '图层' from doc.t() at construction and stores as String fields; paint reads those instead of hardcoded literals. - AIChatPlaceholder resolves 'New Chat' / '用 AI 开始设计' / '用 Agent 设计…' the same way; paint_examples takes the hint label as a parameter. TopBar 'untitled' label was already wired (for_document uses doc.t). 67 lib tests still pass.
This commit is contained in:
parent
91d9e99a94
commit
9506341da0
|
|
@ -88,6 +88,12 @@ pub struct AIChatPlaceholder<'a> {
|
|||
/// [`jian_core::anim::blink_visible`]. `0` = host hasn't
|
||||
/// installed a clock yet (caret stays solid).
|
||||
pub now_ms: u64,
|
||||
/// Localised chrome strings — resolved at construction time
|
||||
/// from `Document::t` so the panel reflows when the user
|
||||
/// flips the TopBar Globe icon.
|
||||
pub label_new_chat: String,
|
||||
pub label_start_with_ai: String,
|
||||
pub label_input_placeholder: String,
|
||||
}
|
||||
|
||||
impl<'a> AIChatPlaceholder<'a> {
|
||||
|
|
@ -103,6 +109,9 @@ impl<'a> AIChatPlaceholder<'a> {
|
|||
theme: doc.theme(),
|
||||
state: &doc.chat,
|
||||
now_ms,
|
||||
label_new_chat: doc.t("chat.new_chat").to_string(),
|
||||
label_start_with_ai: doc.t("chat.start_with_ai").to_string(),
|
||||
label_input_placeholder: doc.t("chat.input_placeholder").to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -207,7 +216,7 @@ impl<'a> Widget for AIChatPlaceholder<'a> {
|
|||
);
|
||||
// "New Chat" label.
|
||||
let title = TextLayout::single_run(
|
||||
"New Chat",
|
||||
&self.label_new_chat,
|
||||
"system-ui",
|
||||
13.0,
|
||||
to_jian_color(self.theme.foreground),
|
||||
|
|
@ -246,7 +255,7 @@ impl<'a> Widget for AIChatPlaceholder<'a> {
|
|||
1.4,
|
||||
);
|
||||
let title = TextLayout::single_run(
|
||||
"New Chat",
|
||||
&self.label_new_chat,
|
||||
"system-ui",
|
||||
14.0,
|
||||
to_jian_color(self.theme.foreground),
|
||||
|
|
@ -282,7 +291,7 @@ impl<'a> Widget for AIChatPlaceholder<'a> {
|
|||
};
|
||||
|
||||
if self.state.messages.is_empty() {
|
||||
paint_examples(cx, &self.theme, rect);
|
||||
paint_examples(cx, &self.theme, rect, &self.label_start_with_ai);
|
||||
} else {
|
||||
paint_messages(cx, &self.theme, body_rect, &self.state.messages);
|
||||
}
|
||||
|
|
@ -311,7 +320,10 @@ impl<'a> Widget for AIChatPlaceholder<'a> {
|
|||
|
||||
// Input text — buffer if non-empty, placeholder otherwise.
|
||||
let (text, color) = if self.state.input.is_empty() {
|
||||
("用 Agent 设计…", self.theme.muted_foreground)
|
||||
(
|
||||
self.label_input_placeholder.as_str(),
|
||||
self.theme.muted_foreground,
|
||||
)
|
||||
} else {
|
||||
(self.state.input.as_str(), self.theme.foreground)
|
||||
};
|
||||
|
|
@ -400,9 +412,9 @@ impl<'a> Widget for AIChatPlaceholder<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn paint_examples(cx: &mut PaintCx<'_>, theme: &Theme, rect: Rect) {
|
||||
fn paint_examples(cx: &mut PaintCx<'_>, theme: &Theme, rect: Rect, hint_label: &str) {
|
||||
let hint = TextLayout::single_run(
|
||||
"用 AI 开始设计",
|
||||
hint_label,
|
||||
"system-ui",
|
||||
12.0,
|
||||
to_jian_color(theme.muted_foreground),
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@ pub struct LayerPanel {
|
|||
pub pages: Vec<PageItem>,
|
||||
pub items: Vec<LayerItem>,
|
||||
pub theme: Theme,
|
||||
pub pages_label: String,
|
||||
pub layers_label: String,
|
||||
}
|
||||
|
||||
impl LayerPanel {
|
||||
|
|
@ -77,6 +79,8 @@ impl LayerPanel {
|
|||
pages,
|
||||
items,
|
||||
theme: doc.theme(),
|
||||
pages_label: doc.t("layer_panel.pages").to_string(),
|
||||
layers_label: doc.t("layer_panel.layers").to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -86,6 +90,8 @@ impl LayerPanel {
|
|||
pages: Vec::new(),
|
||||
items: Vec::new(),
|
||||
theme: Theme::dark(),
|
||||
pages_label: "Pages".to_string(),
|
||||
layers_label: "Layers".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -187,7 +193,7 @@ impl Widget for LayerPanel {
|
|||
let mut y = rect.origin.y + 8.0;
|
||||
|
||||
// Pages section header.
|
||||
paint_section_header(cx, &self.theme, rect.origin.x, y, rect.size.x, "页面");
|
||||
paint_section_header(cx, &self.theme, rect.origin.x, y, rect.size.x, &self.pages_label);
|
||||
// "+" add-page affordance, top-right of header row.
|
||||
let plus_x = rect.origin.x + rect.size.x - ROW_PAD_X - 12.0;
|
||||
let plus_y = y + (SECTION_HEADER_HEIGHT - 14.0) / 2.0;
|
||||
|
|
@ -232,7 +238,7 @@ impl Widget for LayerPanel {
|
|||
y += SECTION_GAP;
|
||||
|
||||
// Layers section header.
|
||||
paint_section_header(cx, &self.theme, rect.origin.x, y, rect.size.x, "图层");
|
||||
paint_section_header(cx, &self.theme, rect.origin.x, y, rect.size.x, &self.layers_label);
|
||||
y += SECTION_HEADER_HEIGHT;
|
||||
|
||||
// Layer rows.
|
||||
|
|
|
|||
Loading…
Reference in a new issue