1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-01-12 00:10:58 +00:00

WIP: core(rust): format translated strings

This commit is contained in:
obrusvit 2025-01-11 21:28:38 +01:00
parent c9b50f3cde
commit 2a18a6fb3e
3 changed files with 67 additions and 16 deletions

View File

@ -136,6 +136,33 @@ impl<'a> OpTextLayout<'a> {
}
}
}
Op::TextFmt(tmpl, arg) => {
// Split the template on {0}
tmpl.map(|t| {
let mut parts = heapless::Vec::<&str, 3>::new();
let mut start = 0;
while let Some(pos) = t[start..].find("{0}") {
let abs_pos = start + pos;
// Add the part before {0}
unwrap!(parts.push(&t[start..abs_pos]));
// Skip the {0}
start = abs_pos + 3;
}
// Add remaining text after last {0}
if start < t.len() {
unwrap!(parts.push(&t[start..]));
}
for (i, part) in parts.iter().enumerate() {
if i > 0 {
// Insert the argument between parts
arg.map(|t| layout.layout_text(t, cursor, sink));
}
// Layout the template part
layout.layout_text(part, cursor, sink);
}
});
}
}
}
@ -202,6 +229,10 @@ impl<'a> OpTextLayout<'a> {
self.with_new_item(Op::Text(text, false))
}
pub fn text_fmt(self, text_tmpl: TString<'a>, arg1: TString<'a>) -> Self {
self.with_new_item(Op::TextFmt(text_tmpl, arg1))
}
pub fn newline(self) -> Self {
self.text("\n".into())
}
@ -276,6 +307,7 @@ pub enum Op<'a> {
/// Bool signifies whether this is a split Text Op continued from previous
/// page. If true, a leading ellipsis will be rendered.
Text(TString<'a>, bool),
TextFmt(TString<'a>, TString<'a>),
/// Set current text color.
Color(Color),
/// Set currently used font.

View File

@ -4,7 +4,7 @@ use crate::{
error::{value_error, Error},
io::BinaryData,
micropython::{gc::Gc, iter::IterBuf, list::List, obj::Obj, util},
strutil::TString,
strutil::{format_i64, TString},
translations::TR,
ui::{
component::{
@ -20,7 +20,8 @@ use crate::{
},
Border, ComponentExt, Empty, FormattedText, Jpeg, Label, Never, Timeout,
},
geometry,
display::Font,
geometry::{self, Offset},
layout::{
obj::{LayoutMaybeTrace, LayoutObj, RootComponent},
util::{ConfirmBlob, PropsList, RecoveryType},
@ -57,30 +58,42 @@ impl FirmwareUI for UIBolt {
_prompt_screen: bool,
_prompt_title: Option<TString<'static>>,
) -> Result<impl LayoutMaybeTrace, Error> {
let paragraphs = {
let formatted = {
let action = action.unwrap_or("".into());
let description = description.unwrap_or("".into());
let mut paragraphs = ParagraphVecShort::new();
if !reverse {
paragraphs
.add(Paragraph::new(&theme::TEXT_DEMIBOLD, action))
.add(Paragraph::new(&theme::TEXT_NORMAL, description));
let action_tmpl: TString = TR::reset__select_word_template.into();
let arg1: TString = TString::from("3rd");
let ops = if !reverse {
let mut ops_text = OpTextLayout::new(theme::TEXT_NORMAL);
OpTextLayout::new(theme::TEXT_NORMAL)
// .text_demibold(action)
.text_fmt(action_tmpl, arg1)
.newline()
.text_normal(description)
.offset(Offset::x(Font::NORMAL.text_width(" ")))
.text_demibold(description)
} else {
paragraphs
.add(Paragraph::new(&theme::TEXT_NORMAL, description))
.add(Paragraph::new(&theme::TEXT_DEMIBOLD, action));
}
paragraphs.into_paragraphs()
OpTextLayout::new(theme::TEXT_NORMAL)
.text_normal(description)
.newline()
.text_demibold(action)
};
FormattedText::new(ops).vertically_centered()
};
let mut page = if hold {
ButtonPage::new(paragraphs, theme::BG).with_hold()?
ButtonPage::new(formatted, theme::BG).with_hold()?
} else {
ButtonPage::new(paragraphs, theme::BG).with_cancel_confirm(verb_cancel, verb)
ButtonPage::new(formatted, theme::BG).with_cancel_confirm(verb_cancel, verb)
};
if hold && hold_danger {
page = page.with_confirm_style(theme::button_danger())
}
let layout = RootComponent::new(Frame::left_aligned(theme::label_title(), title, page));
Ok(layout)
}

View File

@ -274,7 +274,13 @@ async def handle_Ping(msg: Ping) -> Success:
from trezor.enums import ButtonRequestType as B
from trezor.ui.layouts import confirm_action
await confirm_action("ping", TR.words__confirm, "ping", br_code=B.ProtectCall)
await confirm_action(
"ping",
TR.words__confirm,
"action",
description="description",
br_code=B.ProtectCall,
)
return Success(message=msg.message)