From 20e408d7df76eaf878eed260793ddda22a92deca Mon Sep 17 00:00:00 2001 From: obrusvit Date: Thu, 3 Oct 2024 22:46:54 +0200 Subject: [PATCH] fix(ui/mercury): fix should_show_more prompt This prompt was unintuitive as the menu button served as the "show more" button. This commit implements a small SwipeFlow which hides the option to the context menu. --- .../model_mercury/flow/confirm_with_info.rs | 81 +++++++++++++++++++ .../rust/src/ui/model_mercury/flow/mod.rs | 2 + .../embed/rust/src/ui/model_mercury/layout.rs | 18 ++--- core/mocks/generated/trezorui2.pyi | 4 +- 4 files changed, 93 insertions(+), 12 deletions(-) create mode 100644 core/embed/rust/src/ui/model_mercury/flow/confirm_with_info.rs diff --git a/core/embed/rust/src/ui/model_mercury/flow/confirm_with_info.rs b/core/embed/rust/src/ui/model_mercury/flow/confirm_with_info.rs new file mode 100644 index 0000000000..b34b5a30b5 --- /dev/null +++ b/core/embed/rust/src/ui/model_mercury/flow/confirm_with_info.rs @@ -0,0 +1,81 @@ +use crate::{ + error, + strutil::TString, + translations::TR, + ui::{ + component::{ + swipe_detect::SwipeSettings, + text::paragraphs::{ParagraphSource, ParagraphVecShort}, + ComponentExt, + }, + flow::{ + base::{Decision, DecisionBuilder}, + FlowController, FlowMsg, SwipeFlow, + }, + geometry::Direction, + model_mercury::{ + component::{Frame, FrameMsg, SwipeContent, VerticalMenu, VerticalMenuChoiceMsg}, + theme, + }, + }, +}; + +#[derive(Copy, Clone, PartialEq, Eq)] +pub enum ConfirmWithInfo { + Main, + Menu, +} + +impl FlowController for ConfirmWithInfo { + #[inline] + fn index(&'static self) -> usize { + *self as usize + } + fn handle_swipe(&'static self, direction: Direction) -> Decision { + match (self, direction) { + (Self::Main, Direction::Left) => Self::Menu.swipe(direction), + (Self::Main, Direction::Up) => self.return_msg(FlowMsg::Confirmed), + (Self::Menu, Direction::Right) => Self::Main.swipe(direction), + _ => self.do_nothing(), + } + } + fn handle_event(&'static self, msg: FlowMsg) -> Decision { + match (self, msg) { + (Self::Main, FlowMsg::Info) => Self::Menu.goto(), + (Self::Menu, FlowMsg::Cancelled) => Self::Main.swipe_right(), + (Self::Menu, FlowMsg::Choice(0)) => self.return_msg(FlowMsg::Info), + (Self::Menu, FlowMsg::Choice(1)) => self.return_msg(FlowMsg::Cancelled), + _ => self.do_nothing(), + } + } +} + +pub fn new_confirm_with_info( + title: TString<'static>, + button: TString<'static>, + info_button: TString<'static>, + paragraphs: ParagraphVecShort<'static>, +) -> Result { + let content_main = Frame::left_aligned(title, SwipeContent::new(paragraphs.into_paragraphs())) + .with_menu_button() + .with_footer(TR::instructions__swipe_up.into(), Some(button)) + .with_swipe(Direction::Up, SwipeSettings::default()) + .map(|msg| matches!(msg, FrameMsg::Button(FlowMsg::Info)).then_some(FlowMsg::Info)); + + let content_menu = Frame::left_aligned( + TString::empty(), + VerticalMenu::empty() + .item(theme::ICON_CHEVRON_RIGHT, info_button) + .danger(theme::ICON_CANCEL, TR::buttons__cancel.into()), + ) + .with_cancel_button() + .with_swipe(Direction::Right, SwipeSettings::immediate()) + .map(|msg| match msg { + FrameMsg::Content(VerticalMenuChoiceMsg::Selected(i)) => Some(FlowMsg::Choice(i)), + FrameMsg::Button(_) => Some(FlowMsg::Cancelled), + }); + + SwipeFlow::new(&ConfirmWithInfo::Main)? + .with_page(&ConfirmWithInfo::Main, content_main)? + .with_page(&ConfirmWithInfo::Menu, content_menu) +} diff --git a/core/embed/rust/src/ui/model_mercury/flow/mod.rs b/core/embed/rust/src/ui/model_mercury/flow/mod.rs index 9cf4ff6c91..feb3f17ca9 100644 --- a/core/embed/rust/src/ui/model_mercury/flow/mod.rs +++ b/core/embed/rust/src/ui/model_mercury/flow/mod.rs @@ -6,6 +6,7 @@ pub mod confirm_output; pub mod confirm_reset; pub mod confirm_set_new_pin; pub mod confirm_summary; +pub mod confirm_with_info; pub mod continue_recovery; pub mod get_address; pub mod prompt_backup; @@ -26,6 +27,7 @@ pub use confirm_output::new_confirm_output; pub use confirm_reset::new_confirm_reset; pub use confirm_set_new_pin::SetNewPin; pub use confirm_summary::new_confirm_summary; +pub use confirm_with_info::new_confirm_with_info; pub use continue_recovery::new_continue_recovery; pub use get_address::GetAddress; pub use prompt_backup::PromptBackup; diff --git a/core/embed/rust/src/ui/model_mercury/layout.rs b/core/embed/rust/src/ui/model_mercury/layout.rs index 9908af9736..891f91a32a 100644 --- a/core/embed/rust/src/ui/model_mercury/layout.rs +++ b/core/embed/rust/src/ui/model_mercury/layout.rs @@ -7,7 +7,8 @@ use super::{ PinKeyboardMsg, Progress, PromptScreen, SelectWordCount, SelectWordCountMsg, Slip39Input, StatusScreen, SwipeUpScreen, SwipeUpScreenMsg, VerticalMenu, VerticalMenuChoiceMsg, }, - flow, theme, + flow::{self, confirm_with_info}, + theme, }; use crate::{ error::{value_error, Error}, @@ -788,6 +789,7 @@ extern "C" fn new_confirm_with_info(n_args: usize, args: *const Obj, kwargs: *mu let block = move |_args: &[Obj], kwargs: &Map| { let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?; let button: TString = kwargs.get(Qstr::MP_QSTR_button)?.try_into()?; + let info_button: TString = kwargs.get(Qstr::MP_QSTR_info_button)?.try_into()?; let items: Obj = kwargs.get(Qstr::MP_QSTR_items)?; let mut paragraphs = ParagraphVecShort::new(); @@ -802,13 +804,9 @@ extern "C" fn new_confirm_with_info(n_args: usize, args: *const Obj, kwargs: *mu } } - let obj = LayoutObj::new(SwipeUpScreen::new( - Frame::left_aligned(title, SwipeContent::new(paragraphs.into_paragraphs())) - .with_menu_button() - .with_footer(TR::instructions__swipe_up.into(), Some(button)) - .with_swipe(Direction::Up, SwipeSettings::default()), - ))?; - Ok(obj.into()) + let flow = + confirm_with_info::new_confirm_with_info(title, button, info_button, paragraphs)?; + Ok(LayoutObj::new(flow)?.into()) }; unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } } @@ -1444,8 +1442,8 @@ pub static mp_module_trezorui2: Module = obj_module! { /// info_button: str, /// items: Iterable[tuple[int, str]], /// ) -> LayoutObj[UiResult]: - /// """Confirm given items but with third button. Always single page - /// without scrolling.""" + /// """Confirm given items but with third button. In mercury, the button is placed in + /// context menu.""" Qstr::MP_QSTR_confirm_with_info => obj_fn_kw!(0, new_confirm_with_info).as_obj(), /// def confirm_more( diff --git a/core/mocks/generated/trezorui2.pyi b/core/mocks/generated/trezorui2.pyi index 1e5c90e639..2e7fb95d72 100644 --- a/core/mocks/generated/trezorui2.pyi +++ b/core/mocks/generated/trezorui2.pyi @@ -314,8 +314,8 @@ def confirm_with_info( info_button: str, items: Iterable[tuple[int, str]], ) -> LayoutObj[UiResult]: - """Confirm given items but with third button. Always single page - without scrolling.""" + """Confirm given items but with third button. In mercury, the button is placed in + context menu.""" # rust/src/ui/model_mercury/layout.rs