diff --git a/core/embed/rust/src/translations/generated/translated_string.rs b/core/embed/rust/src/translations/generated/translated_string.rs index 32c5f99e77..fd2a139f15 100644 --- a/core/embed/rust/src/translations/generated/translated_string.rs +++ b/core/embed/rust/src/translations/generated/translated_string.rs @@ -840,7 +840,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" diff --git a/core/embed/rust/src/ui/layout_eckhart/firmware/text_screen.rs b/core/embed/rust/src/ui/layout_eckhart/firmware/text_screen.rs index 2cdb737507..a25f9c16eb 100644 --- a/core/embed/rust/src/ui/layout_eckhart/firmware/text_screen.rs +++ b/core/embed/rust/src/ui/layout_eckhart/firmware/text_screen.rs @@ -1,7 +1,7 @@ use crate::ui::{ component::{ swipe_detect::SwipeConfig, - text::paragraphs::{ParagraphSource, Paragraphs}, + text::paragraphs::{Checklist, ParagraphSource, Paragraphs}, Component, Event, EventCtx, FormattedText, PaginateFull, }, flow::Swipable, @@ -151,6 +151,7 @@ where pub trait AllowedTextContent: Component + PaginateFull {} impl AllowedTextContent for FormattedText {} impl<'a, T> AllowedTextContent for Paragraphs where T: ParagraphSource<'a> {} +impl<'a, T> AllowedTextContent for Checklist where T: ParagraphSource<'a> {} #[cfg(feature = "ui_debug")] impl crate::trace::Trace for TextScreen diff --git a/core/embed/rust/src/ui/layout_eckhart/res/checkmark_mini.png b/core/embed/rust/src/ui/layout_eckhart/res/checkmark_mini.png new file mode 100644 index 0000000000..b6069cef31 Binary files /dev/null and b/core/embed/rust/src/ui/layout_eckhart/res/checkmark_mini.png differ diff --git a/core/embed/rust/src/ui/layout_eckhart/res/checkmark_mini.toif b/core/embed/rust/src/ui/layout_eckhart/res/checkmark_mini.toif new file mode 100644 index 0000000000..8a79ce82b4 Binary files /dev/null and b/core/embed/rust/src/ui/layout_eckhart/res/checkmark_mini.toif differ diff --git a/core/embed/rust/src/ui/layout_eckhart/res/chevron_right_mini.png b/core/embed/rust/src/ui/layout_eckhart/res/chevron_right_mini.png new file mode 100644 index 0000000000..ade43ae447 Binary files /dev/null and b/core/embed/rust/src/ui/layout_eckhart/res/chevron_right_mini.png differ diff --git a/core/embed/rust/src/ui/layout_eckhart/res/chevron_right_mini.toif b/core/embed/rust/src/ui/layout_eckhart/res/chevron_right_mini.toif new file mode 100644 index 0000000000..e2712b8c05 Binary files /dev/null and b/core/embed/rust/src/ui/layout_eckhart/res/chevron_right_mini.toif differ diff --git a/core/embed/rust/src/ui/layout_eckhart/theme/mod.rs b/core/embed/rust/src/ui/layout_eckhart/theme/mod.rs index 5e7f50c95b..77a868d1cb 100644 --- a/core/embed/rust/src/ui/layout_eckhart/theme/mod.rs +++ b/core/embed/rust/src/ui/layout_eckhart/theme/mod.rs @@ -57,6 +57,14 @@ include_icon!( ICON_CHEVRON_DOWN_MINI, "layout_eckhart/res/chevron_down_mini.toif" ); +include_icon!( + ICON_CHEVRON_RIGHT_MINI, + "layout_eckhart/res/chevron_right_mini.toif" +); +include_icon!( + ICON_CHECKMARK_MINI, + "layout_eckhart/res/checkmark_mini.toif" +); include_icon!(ICON_CHEVRON_LEFT, "layout_eckhart/res/chevron_left.toif"); include_icon!(ICON_CHEVRON_RIGHT, "layout_eckhart/res/chevron_right.toif"); include_icon!(ICON_CHEVRON_UP, "layout_eckhart/res/chevron_up.toif"); 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 e193753661..ff869bfce8 100644 --- a/core/translations/en.json +++ b/core/translations/en.json @@ -723,7 +723,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",