1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-08-03 12:28:13 +00:00

chore(eckhart): minor improvements

- update trace function for firmware components
- add missing button requests
- update get address flow
- require long press to lock even with disabled animations
This commit is contained in:
Lukas Bielesch 2025-03-19 09:58:16 +01:00 committed by Vít Obrusník
parent fa8e93d64a
commit 3f1b5a9e28
10 changed files with 77 additions and 63 deletions

View File

@ -147,9 +147,6 @@ impl Homescreen {
ctx.request_anim_frame();
ctx.request_paint();
ctx.enable_swipe();
} else {
// Animations disabled
return true;
}
}
ButtonMsg::Released => {

View File

@ -105,6 +105,9 @@ impl Component for SelectWordScreen {
impl crate::trace::Trace for SelectWordScreen {
fn trace(&self, t: &mut dyn crate::trace::Tracer) {
t.component("SelectWordScreen");
t.child("Header", &self.header);
t.child("subtitle", &self.description);
t.child("Content", &self.menu);
}
}

View File

@ -192,11 +192,11 @@ impl<'a> Component for ShareWordsScreen<'a> {
#[cfg(feature = "ui_debug")]
impl<'a> crate::trace::Trace for ShareWordsScreen<'a> {
fn trace(&self, t: &mut dyn crate::trace::Tracer) {
t.component("TextComponent");
self.header.trace(t);
self.content.trace(t);
self.hint.trace(t);
self.action_bar.trace(t);
t.component("TextScreen");
t.child("Header", &self.header);
t.child("Content", &self.content);
t.child("Hint", &self.hint);
t.child("ActionBar", &self.action_bar);
}
}

View File

@ -186,19 +186,19 @@ where
T: AllowedTextContent + crate::trace::Trace,
{
fn trace(&self, t: &mut dyn crate::trace::Tracer) {
t.component("TextComponent");
t.component("TextScreen");
if let Some(header) = self.header.as_ref() {
header.trace(t);
t.child("Header", header);
}
if let Some(subtitle) = self.subtitle.as_ref() {
subtitle.trace(t);
t.child("subtitle", subtitle);
}
self.content.trace(t);
t.child("Content", &self.content);
if let Some(hint) = self.hint.as_ref() {
hint.trace(t);
t.child("Hint", hint);
}
if let Some(ab) = self.action_bar.as_ref() {
ab.trace(t);
t.child("ActionBar", ab);
}
}
}

View File

@ -187,5 +187,7 @@ impl Swipable for VerticalMenuScreen {
impl crate::trace::Trace for VerticalMenuScreen {
fn trace(&self, t: &mut dyn crate::trace::Tracer) {
t.component("VerticalMenuScreen");
t.child("Header", &self.header);
t.child("Menu", &self.menu);
}
}

View File

@ -2,7 +2,8 @@ use crate::{
error,
translations::TR,
ui::{
component::{text::op::OpTextLayout, ComponentExt, FormattedText},
button_request::ButtonRequestCode,
component::{text::op::OpTextLayout, ButtonRequestExt, ComponentExt, FormattedText},
flow::{
base::{Decision, DecisionBuilder as _},
FlowController, FlowMsg, SwipeFlow,
@ -48,10 +49,16 @@ impl FlowController for ConfirmReset {
}
pub fn new_confirm_reset(recovery: bool) -> Result<SwipeFlow, error::Error> {
let title = if recovery {
TR::recovery__title_recover.into()
let (title, br) = if recovery {
(
TR::recovery__title_recover.into(),
ButtonRequestCode::ProtectCall.with_name("recover_device"),
)
} else {
TR::reset__title_create_wallet.into()
(
TR::reset__title_create_wallet.into(),
ButtonRequestCode::ResetDevice.with_name("setup_device"),
)
};
let op = OpTextLayout::new(theme::TEXT_REGULAR)
@ -73,7 +80,8 @@ pub fn new_confirm_reset(recovery: bool) -> Result<SwipeFlow, error::Error> {
TextScreenMsg::Menu => Some(FlowMsg::Info),
TextScreenMsg::Confirmed => Some(FlowMsg::Confirmed),
_ => None,
});
})
.one_button_request(br);
let content_menu = VerticalMenuScreen::new(
VerticalMenu::empty().item(

View File

@ -4,16 +4,16 @@ use crate::{
strutil::TString,
translations::TR,
ui::{
button_request::ButtonRequest,
component::{
text::paragraphs::{Paragraph, ParagraphSource, ParagraphVecShort, VecExt},
ComponentExt, Qr,
ButtonRequestExt, ComponentExt, Qr,
},
flow::{
base::{Decision, DecisionBuilder as _},
FlowController, FlowMsg, SwipeFlow,
},
geometry::{Alignment, Direction, LinearPlacement, Offset},
layout::util::ConfirmValueParams,
},
};
@ -26,7 +26,6 @@ use super::super::{
theme,
};
const TIMEOUT_MS: u32 = 2000;
const ITEM_PADDING: i16 = 16;
const GROUP_PADDING: i16 = 20;
@ -72,7 +71,7 @@ impl FlowController for GetAddress {
pub fn new_get_address(
title: TString<'static>,
_description: Option<TString<'static>>,
extra: Option<TString<'static>>,
_extra: Option<TString<'static>>,
address: Obj, // TODO: get rid of Obj
chunkify: bool,
address_qr: TString<'static>,
@ -81,28 +80,25 @@ pub fn new_get_address(
path: Option<TString<'static>>,
_xpubs: Obj, // TODO: get rid of Obj
title_success: TString<'static>,
_br_code: u16,
_br_name: TString<'static>,
br_code: u16,
br_name: TString<'static>,
) -> Result<SwipeFlow, error::Error> {
// Address
let flow_title: TString = TR::words__receive.into();
let paragraphs = ConfirmValueParams {
description: title,
extra: extra.unwrap_or_else(|| "".into()),
value: address.try_into()?,
font: if chunkify {
let address: TString = address.try_into()?;
theme::get_chunkified_text_style(address.len())
} else {
&theme::TEXT_MONO_ADDRESS
},
description_font: &theme::TEXT_MEDIUM_EXTRA_LIGHT,
extra_font: &theme::TEXT_SMALL,
}
.into_paragraphs()
.with_placement(LinearPlacement::vertical().with_spacing(14));
let test_style = if chunkify {
let address: TString = address.try_into()?;
theme::get_chunkified_text_style(address.len())
} else {
&theme::TEXT_MONO_ADDRESS
};
let paragraphs = Paragraph::new(test_style, address.try_into().unwrap_or(TString::empty()))
.into_paragraphs()
.with_placement(LinearPlacement::vertical());
let content_address = TextScreen::new(paragraphs)
.with_header(Header::new(flow_title).with_menu_button())
.with_subtitle(title)
.with_action_bar(ActionBar::new_single(
Button::with_text(TR::buttons__confirm.into()).styled(theme::button_confirm()),
))
@ -114,20 +110,24 @@ pub fn new_get_address(
TextScreenMsg::Cancelled => Some(FlowMsg::Cancelled),
TextScreenMsg::Confirmed => Some(FlowMsg::Confirmed),
TextScreenMsg::Menu => Some(FlowMsg::Info),
});
})
.one_button_request(ButtonRequest::from_num(br_code, br_name))
.with_pages(|address_pages| address_pages + 1);
let content_confirmed =
TextScreen::new(Paragraph::new(&theme::TEXT_REGULAR, title_success).into_paragraphs())
.with_header(
Header::new(TR::words__title_done.into())
.with_icon(theme::ICON_DONE, theme::GREEN_LIGHT)
.with_text_style(theme::label_title_confirm()),
)
.with_action_bar(ActionBar::new_timeout(
Button::with_text(TR::instructions__continue_in_app.into()),
TIMEOUT_MS,
))
.map(|_| Some(FlowMsg::Confirmed));
let content_confirmed = TextScreen::new(
Paragraph::new(&theme::TEXT_REGULAR, title_success)
.into_paragraphs()
.with_placement(LinearPlacement::vertical()),
)
.with_header(
Header::new(TR::words__title_done.into())
.with_icon(theme::ICON_DONE, theme::GREEN_LIGHT)
.with_text_style(theme::label_title_confirm()),
)
.with_action_bar(ActionBar::new_single(Button::with_text(
TR::instructions__continue_in_app.into(),
)))
.map(|_| Some(FlowMsg::Confirmed));
// Menu
let content_menu = VerticalMenuScreen::new(

View File

@ -3,9 +3,10 @@ use crate::{
strutil::TString,
translations::TR,
ui::{
button_request::ButtonRequestCode,
component::{
text::paragraphs::{Paragraph, ParagraphSource, ParagraphVecShort},
ComponentExt,
ButtonRequestExt, ComponentExt,
},
flow::{
base::{Decision, DecisionBuilder as _},
@ -63,6 +64,7 @@ pub fn new_show_share_words_flow(
instructions_paragraphs: ParagraphVecShort<'static>,
text_confirm: TString<'static>,
) -> Result<SwipeFlow, error::Error> {
let nwords = words.len();
let instruction = TextScreen::new(
instructions_paragraphs
.into_paragraphs()
@ -76,7 +78,9 @@ pub fn new_show_share_words_flow(
TextScreenMsg::Cancelled => Some(FlowMsg::Cancelled),
TextScreenMsg::Confirmed => Some(FlowMsg::Confirmed),
_ => Some(FlowMsg::Cancelled),
});
})
.one_button_request(ButtonRequestCode::ResetDevice.with_name("share_words"))
.with_pages(move |_| nwords + 2);
let share_words = ShareWordsScreen::new(words).map(|msg| match msg {
ShareWordsScreenMsg::Cancelled => Some(FlowMsg::Cancelled),

View File

@ -892,7 +892,7 @@ class DebugUI:
self.debuglink.press_yes()
elif self.debuglink.model is models.T3W1:
layout = self.debuglink.read_layout()
if "TextComponent" in layout.all_components():
if "TextScreen" in layout.all_components():
self.debuglink.click(self.debuglink.screen_buttons.ok())
else:
self.debuglink.press_yes()

View File

@ -484,7 +484,7 @@ class InputFlowShowAddressQRCode(InputFlowBase):
# cancel
self.debug.click(self.debug.screen_buttons.cancel())
# address
self.debug.synchronize_at("TextComponent")
self.debug.synchronize_at("TextScreen")
self.debug.click(self.debug.screen_buttons.ok())
# continue to the app
self.debug.press_yes()
@ -558,7 +558,7 @@ class InputFlowShowAddressQRCodeCancel(InputFlowBase):
# menu
self.debug.click(self.debug.screen_buttons.vertical_menu_items()[2])
# cancel
self.debug.synchronize_at("TextComponent")
self.debug.synchronize_at("TextScreen")
self.debug.click(self.debug.screen_buttons.ok())
@ -728,7 +728,7 @@ class InputFlowShowMultisigXPUBs(InputFlowBase):
# menu
assert "VerticalMenu" in self.all_components()
self.debug.click(self.debug.screen_buttons.vertical_menu_items()[1])
layout = self.debug.synchronize_at("TextComponent")
layout = self.debug.synchronize_at("TextScreen")
# address details
assert "Multisig 2 of 3" in layout.screen_content()
assert TR.address_details__derivation_path in layout.screen_content()
@ -740,7 +740,7 @@ class InputFlowShowMultisigXPUBs(InputFlowBase):
# cancel
self.debug.click(self.debug.screen_buttons.cancel())
# address
layout = self.debug.synchronize_at("TextComponent")
layout = self.debug.synchronize_at("TextScreen")
self.debug.press_yes()
@ -881,7 +881,7 @@ class InputFlowShowXpubQRCode(InputFlowBase):
# menu
assert "VerticalMenu" in self.all_components()
self.debug.click(self.debug.screen_buttons.vertical_menu_items()[1])
layout = self.debug.synchronize_at("TextComponent")
layout = self.debug.synchronize_at("TextScreen")
# address details
assert TR.address_details__derivation_path in layout.screen_content()
@ -892,7 +892,7 @@ class InputFlowShowXpubQRCode(InputFlowBase):
# cancel
self.debug.click(self.debug.screen_buttons.cancel())
# address
layout = self.debug.synchronize_at("TextComponent")
layout = self.debug.synchronize_at("TextScreen")
self.debug.press_yes()
@ -1241,7 +1241,7 @@ class InputFlowSignTxInformationCancel(InputFlowBase):
yield from sign_tx_go_to_info_eckhart(self.client)
self.debug.click(self.debug.screen_buttons.menu())
self.debug.click(self.debug.screen_buttons.vertical_menu_items()[2])
self.debug.synchronize_at("TextComponent")
self.debug.synchronize_at("TextScreen")
self.debug.click(self.debug.screen_buttons.ok())
self.debug.click(self.debug.screen_buttons.ok())