From c5d7397fe5ee519e9c9f52db29a15eee3584c155 Mon Sep 17 00:00:00 2001 From: Lukas Bielesch Date: Tue, 25 Feb 2025 11:56:21 +0100 Subject: [PATCH] feat(eckhart): implement show checklist --- .../generated/translated_string.rs | 9 +++- .../src/ui/layout_eckhart/theme/firmware.rs | 8 ++++ .../rust/src/ui/layout_eckhart/ui_firmware.rs | 47 ++++++++++++++++--- core/translations/en.json | 7 ++- 4 files changed, 62 insertions(+), 9 deletions(-) diff --git a/core/embed/rust/src/translations/generated/translated_string.rs b/core/embed/rust/src/translations/generated/translated_string.rs index ba027f5085..a6b1ae163b 100644 --- a/core/embed/rust/src/translations/generated/translated_string.rs +++ b/core/embed/rust/src/translations/generated/translated_string.rs @@ -862,7 +862,7 @@ pub enum TranslatedString { reset__slip39_checklist_set_num_shares = 578, // "Set number of shares" reset__slip39_checklist_set_sizes = 579, // "Set sizes and thresholds" reset__slip39_checklist_set_sizes_longer = 580, // "Set size and threshold for each group" - reset__slip39_checklist_set_threshold = 581, // "Set threshold" + reset__slip39_checklist_set_threshold = 581, // {"Bolt": "Set threshold", "Caesar": "Set threshold", "Delizia": "Set threshold", "Eckhart": "Set recovery threshold"} reset__slip39_checklist_title = 582, // "Backup checklist" reset__slip39_checklist_write_down = 583, // "Write down and check all shares" reset__slip39_checklist_write_down_recovery = 584, // "Write down & check all wallet backup shares" @@ -2291,7 +2291,14 @@ impl TranslatedString { Self::reset__slip39_checklist_set_num_shares => "Set number of shares", Self::reset__slip39_checklist_set_sizes => "Set sizes and thresholds", Self::reset__slip39_checklist_set_sizes_longer => "Set size and threshold for each group", + #[cfg(feature = "layout_bolt")] Self::reset__slip39_checklist_set_threshold => "Set threshold", + #[cfg(feature = "layout_caesar")] + Self::reset__slip39_checklist_set_threshold => "Set threshold", + #[cfg(feature = "layout_delizia")] + Self::reset__slip39_checklist_set_threshold => "Set threshold", + #[cfg(feature = "layout_eckhart")] + Self::reset__slip39_checklist_set_threshold => "Set recovery threshold", Self::reset__slip39_checklist_title => "Backup checklist", Self::reset__slip39_checklist_write_down => "Write down and check all shares", Self::reset__slip39_checklist_write_down_recovery => "Write down & check all wallet backup shares", diff --git a/core/embed/rust/src/ui/layout_eckhart/theme/firmware.rs b/core/embed/rust/src/ui/layout_eckhart/theme/firmware.rs index caabc8267c..6beda9e07d 100644 --- a/core/embed/rust/src/ui/layout_eckhart/theme/firmware.rs +++ b/core/embed/rust/src/ui/layout_eckhart/theme/firmware.rs @@ -117,6 +117,14 @@ pub const TEXT_MONO_EXTRA_LIGHT: TextStyle = TextStyle::new( GREY_EXTRA_LIGHT, ); +pub const TEXT_CHECKLIST_INACTIVE: TextStyle = TextStyle::new( + fonts::FONT_SATOSHI_MEDIUM_26, + GREY_DARK, + BG, + GREY_DARK, + GREY_DARK, +); + // Macro for styles differing only in text color macro_rules! label_title { ($color:expr) => { diff --git a/core/embed/rust/src/ui/layout_eckhart/ui_firmware.rs b/core/embed/rust/src/ui/layout_eckhart/ui_firmware.rs index 00dd65cf6b..6ac24e7cd3 100644 --- a/core/embed/rust/src/ui/layout_eckhart/ui_firmware.rs +++ b/core/embed/rust/src/ui/layout_eckhart/ui_firmware.rs @@ -1,3 +1,5 @@ +use core::cmp::Ordering; + use crate::{ error::Error, io::BinaryData, @@ -8,11 +10,13 @@ use crate::{ component::{ text::{ op::OpTextLayout, - paragraphs::{Paragraph, ParagraphSource, ParagraphVecShort, Paragraphs, VecExt}, + paragraphs::{ + Checklist, Paragraph, ParagraphSource, ParagraphVecShort, Paragraphs, VecExt, + }, }, Empty, FormattedText, }, - geometry::LinearPlacement, + geometry::{LinearPlacement, Offset}, layout::{ obj::{LayoutMaybeTrace, LayoutObj, RootComponent}, util::{ConfirmValueParams, RecoveryType, StrOrBytes}, @@ -521,12 +525,41 @@ impl FirmwareUI for UIEckhart { } fn show_checklist( - _title: TString<'static>, - _button: TString<'static>, - _active: usize, - _items: [TString<'static>; MAX_CHECKLIST_ITEMS], + title: TString<'static>, + button: TString<'static>, + active: usize, + items: [TString<'static>; MAX_CHECKLIST_ITEMS], ) -> Result { - Err::, Error>(Error::ValueError(c"not implemented")) + let mut paragraphs = ParagraphVecShort::new(); + for (i, item) in items.into_iter().enumerate() { + let style = match i.cmp(&active) { + Ordering::Less => &theme::TEXT_CHECKLIST_INACTIVE, + Ordering::Equal => &theme::TEXT_MEDIUM, + Ordering::Greater => &theme::TEXT_CHECKLIST_INACTIVE, + }; + paragraphs.add(Paragraph::new(style, item)); + } + + let checklist_content = Checklist::from_paragraphs( + theme::ICON_CHEVRON_RIGHT_MINI, + theme::ICON_CHECKMARK_MINI, + active, + paragraphs.into_paragraphs().with_spacing(40), + ) + .with_check_width(32) + .with_icon_done_color(theme::GREEN_LIGHT) + .with_done_offset(Offset::y(7)) + .with_current_offset(Offset::y(4)); + + let layout = RootComponent::new( + TextScreen::new(checklist_content) + .with_header(Header::new(title).with_menu_button()) + .with_action_bar(ActionBar::new_single( + Button::with_text(button).styled(theme::button_default()), + )), + ); + + Ok(layout) } fn show_danger( diff --git a/core/translations/en.json b/core/translations/en.json index d53b286a18..f2a81e3309 100644 --- a/core/translations/en.json +++ b/core/translations/en.json @@ -724,7 +724,12 @@ "reset__slip39_checklist_set_num_shares": "Set number of shares", "reset__slip39_checklist_set_sizes": "Set sizes and thresholds", "reset__slip39_checklist_set_sizes_longer": "Set size and threshold for each group", - "reset__slip39_checklist_set_threshold": "Set threshold", + "reset__slip39_checklist_set_threshold": { + "Bolt": "Set threshold", + "Caesar": "Set threshold", + "Delizia": "Set threshold", + "Eckhart": "Set recovery threshold" + }, "reset__slip39_checklist_threshold_x_template": "Recovery threshold: {0}", "reset__slip39_checklist_title": "Backup checklist", "reset__slip39_checklist_write_down": "Write down and check all shares",