diff --git a/core/embed/rust/src/ui/model_tt/component/keyboard/mnemonic.rs b/core/embed/rust/src/ui/model_tt/component/keyboard/mnemonic.rs index 90357882c3..49332c86d6 100644 --- a/core/embed/rust/src/ui/model_tt/component/keyboard/mnemonic.rs +++ b/core/embed/rust/src/ui/model_tt/component/keyboard/mnemonic.rs @@ -33,7 +33,7 @@ where Self { prompt: Child::new(Maybe::visible( theme::BG, - Label::centered(prompt, theme::label_keyboard()), + Label::centered(prompt, theme::label_keyboard_prompt()), )), back: Child::new(Maybe::hidden( theme::BG, diff --git a/core/embed/rust/src/ui/model_tt/component/keyboard/slip39.rs b/core/embed/rust/src/ui/model_tt/component/keyboard/slip39.rs index 65dd614f33..1f9cb31a93 100644 --- a/core/embed/rust/src/ui/model_tt/component/keyboard/slip39.rs +++ b/core/embed/rust/src/ui/model_tt/component/keyboard/slip39.rs @@ -194,7 +194,8 @@ impl Component for Slip39Input { impl Slip39Input { pub fn new() -> Self { Self { - button: Button::empty(), + // Button has the same style the whole time + button: Button::empty().styled(theme::button_pin_confirm()), textbox: TextBox::empty(), multi_tap: MultiTapKeyboard::new(), final_word: None, @@ -232,13 +233,11 @@ impl Slip39Input { if self.final_word.is_some() { // Confirm button. self.button.enable(ctx); - self.button.set_stylesheet(ctx, theme::button_pin_confirm()); self.button .set_content(ctx, ButtonContent::Icon(theme::ICON_LIST_CHECK)); } else { // Disabled button. self.button.disable(ctx); - self.button.set_stylesheet(ctx, theme::button_pin()); self.button.set_content(ctx, ButtonContent::Text("")); } } diff --git a/core/embed/rust/src/ui/model_tt/component/keyboard/word_count.rs b/core/embed/rust/src/ui/model_tt/component/keyboard/word_count.rs index d46e472af2..8202a03fad 100644 --- a/core/embed/rust/src/ui/model_tt/component/keyboard/word_count.rs +++ b/core/embed/rust/src/ui/model_tt/component/keyboard/word_count.rs @@ -9,7 +9,7 @@ use crate::ui::{ const NUMBERS: [u32; 5] = [12, 18, 20, 24, 33]; const LABELS: [&str; 5] = ["12", "18", "20", "24", "33"]; -const CELLS: [(usize, usize); 5] = [(0, 0), (0, 2), (0, 4), (1, 1), (1, 3)]; +const CELLS: [(usize, usize); 5] = [(0, 0), (0, 2), (0, 4), (1, 0), (1, 2)]; pub struct SelectWordCount { button: [Button<&'static str>; NUMBERS.len()], diff --git a/core/embed/rust/src/ui/model_tt/layout.rs b/core/embed/rust/src/ui/model_tt/layout.rs index f9985baadd..0610285248 100644 --- a/core/embed/rust/src/ui/model_tt/layout.rs +++ b/core/embed/rust/src/ui/model_tt/layout.rs @@ -1393,19 +1393,20 @@ extern "C" fn new_confirm_recovery(n_args: usize, args: *const Obj, kwargs: *mut let info_button: bool = kwargs.get_or(Qstr::MP_QSTR_info_button, false)?; let paragraphs = Paragraphs::new([ - Paragraph::new(&theme::TEXT_DEMIBOLD, title).centered(), - Paragraph::new(&theme::TEXT_NORMAL_OFF_WHITE, description).centered(), + Paragraph::new(&theme::TEXT_DEMIBOLD, title), + Paragraph::new(&theme::TEXT_NORMAL, description), ]) .with_spacing(theme::RECOVERY_SPACING); let notification = if dry_run { "BACKUP CHECK" } else { - "RECOVERY MODE" + "RECOVER WALLET" }; let obj = if info_button { - LayoutObj::new(NotificationFrame::new( + LayoutObj::new(Frame::left_aligned( + theme::label_title(), notification, Dialog::new( paragraphs, @@ -1413,7 +1414,8 @@ extern "C" fn new_confirm_recovery(n_args: usize, args: *const Obj, kwargs: *mut ), ))? } else { - LayoutObj::new(NotificationFrame::new( + LayoutObj::new(Frame::left_aligned( + theme::label_title(), notification, Dialog::new(paragraphs, Button::cancel_confirm_text(None, Some(button))), ))? @@ -1432,13 +1434,10 @@ extern "C" fn new_select_word_count(n_args: usize, args: *const Obj, kwargs: *mu "RECOVER WALLET" }; - let paragraphs = Paragraphs::new( - Paragraph::new( - &theme::TEXT_DEMIBOLD, - StrBuffer::from("Select number of words in your recovery seed."), - ) - .centered(), - ); + let paragraphs = Paragraphs::new(Paragraph::new( + &theme::TEXT_DEMIBOLD, + StrBuffer::from("Select the number of words in your backup."), + )); let obj = LayoutObj::new(Frame::left_aligned( theme::label_title(), diff --git a/core/embed/rust/src/ui/model_tt/theme.rs b/core/embed/rust/src/ui/model_tt/theme.rs index 4169829211..4fe66fe9b9 100644 --- a/core/embed/rust/src/ui/model_tt/theme.rs +++ b/core/embed/rust/src/ui/model_tt/theme.rs @@ -121,6 +121,10 @@ pub const fn label_keyboard() -> TextStyle { TextStyle::new(Font::DEMIBOLD, OFF_WHITE, BG, GREY_LIGHT, GREY_LIGHT) } +pub const fn label_keyboard_prompt() -> TextStyle { + TextStyle::new(Font::DEMIBOLD, GREY_LIGHT, BG, GREY_LIGHT, GREY_LIGHT) +} + pub const fn label_keyboard_warning() -> TextStyle { TextStyle::new(Font::DEMIBOLD, RED, BG, GREY_LIGHT, GREY_LIGHT) } @@ -380,7 +384,7 @@ pub const fn button_pin() -> ButtonStyleSheet { disabled: &ButtonStyle { font: Font::MONO, text_color: GREY_LIGHT, - button_color: GREY_DARK, + button_color: BG, // so there is no "button" itself, just the text background_color: BG, border_color: BG, border_radius: RADIUS, @@ -412,7 +416,7 @@ pub const fn button_pin_confirm() -> ButtonStyleSheet { disabled: &ButtonStyle { font: Font::MONO, text_color: GREY_LIGHT, - button_color: GREEN, + button_color: GREY_DARK, background_color: BG, border_color: BG, border_radius: RADIUS, @@ -426,7 +430,7 @@ pub const fn button_pin_autocomplete() -> ButtonStyleSheet { normal: &ButtonStyle { font: Font::MONO, text_color: FG, - button_color: BG, + button_color: GREY_DARK, // same as PIN buttons background_color: BG, border_color: BG, border_radius: RADIUS, diff --git a/core/src/apps/management/recovery_device/homescreen.py b/core/src/apps/management/recovery_device/homescreen.py index 55de7d6927..ef7529f7c2 100644 --- a/core/src/apps/management/recovery_device/homescreen.py +++ b/core/src/apps/management/recovery_device/homescreen.py @@ -42,6 +42,7 @@ async def recovery_process() -> Success: async def _continue_recovery_process() -> Success: from trezor.errors import MnemonicError + from trezor import utils # gather the current recovery state from storage dry_run = storage_recovery.is_dry_run() @@ -63,9 +64,11 @@ async def _continue_recovery_process() -> Success: if is_first_step: # If we are starting recovery, ask for word count first... # _request_word_count - await layout.homescreen_dialog( - "Continue", "Select the number of words in your backup." - ) + # For TT, just continuing straight to word count keyboard + if utils.MODEL == "R": + await layout.homescreen_dialog( + "Continue", "Select the number of words in your backup." + ) # ask for the number of words word_count = await layout.request_word_count(dry_run) # ...and only then show the starting screen with word count. @@ -153,7 +156,7 @@ async def _finish_recovery(secret: bytes, backup_type: BackupType) -> Success: storage_recovery.end_progress() - await show_success("success_recovery", "Wallet recovered successfully.") + await show_success("success_recovery", "Wallet recovered successfully") return Success(message="Device recovered") diff --git a/core/src/trezor/ui/layouts/tr/__init__.py b/core/src/trezor/ui/layouts/tr/__init__.py index 067c20c235..cd4aa14a02 100644 --- a/core/src/trezor/ui/layouts/tr/__init__.py +++ b/core/src/trezor/ui/layouts/tr/__init__.py @@ -399,15 +399,6 @@ async def confirm_reset_device( ) ) - if recovery: - await confirm_action( - "recover_device", - title, - description="It is safe to eject your Trezor anytime and continue later.", - verb="CONTINUE", - br_code=ButtonRequestType.ProtectCall, - ) - async def prompt_backup() -> bool: br_type = "backup_device" diff --git a/core/src/trezor/ui/layouts/tr/recovery.py b/core/src/trezor/ui/layouts/tr/recovery.py index f28e90462e..a0b097d596 100644 --- a/core/src/trezor/ui/layouts/tr/recovery.py +++ b/core/src/trezor/ui/layouts/tr/recovery.py @@ -71,14 +71,17 @@ async def continue_recovery( # There is very limited space on the screen # (and having middle button would mean shortening the right button text) - description = text + # Never showing info for dry-run, user already saw it and it is disturbing + if dry_run: + show_info = False + if subtext: - description += f"\n\n{subtext}" + text += f"\n\n{subtext}" homepage = RustLayout( trezorui2.confirm_recovery( title="", - description=description, + description=text, button=button_label.upper(), info_button=False, dry_run=dry_run, diff --git a/core/src/trezor/ui/layouts/tt_v2/recovery.py b/core/src/trezor/ui/layouts/tt_v2/recovery.py index ae4b2ce766..ebc447c22c 100644 --- a/core/src/trezor/ui/layouts/tt_v2/recovery.py +++ b/core/src/trezor/ui/layouts/tt_v2/recovery.py @@ -106,40 +106,28 @@ async def continue_recovery( ) -> bool: from ..common import button_request - title = text - if subtext: - title += "\n" - title += subtext + if show_info: + # Show this just one-time + description = "You'll only have to select the first 2-3 letters of each word." + else: + description = subtext or "" - description = "It is safe to eject Trezor\nand continue later" + homepage = RustLayout( + trezorui2.confirm_recovery( + title=text, + description=description, + button=button_label.upper(), + info_button=info_func is not None, + dry_run=dry_run, + ) + ) + + await button_request("recovery", ButtonRequestType.RecoveryHomepage) if info_func is not None: - homepage = RustLayout( - trezorui2.confirm_recovery( - title=title, - description=description, - button=button_label.upper(), - info_button=True, - dry_run=dry_run, - ) - ) - await button_request("recovery", ButtonRequestType.RecoveryHomepage) return await _is_confirmed_info(homepage, info_func) else: - homepage = RustLayout( - trezorui2.confirm_recovery( - title=text, - description=description, - button=button_label.upper(), - info_button=False, - dry_run=dry_run, - ) - ) - result = await interact( - homepage, - "recovery", - ButtonRequestType.RecoveryHomepage, - ) + result = await ctx_wait(homepage) return result is CONFIRMED