From b616b27c5bd1bb9e09b208ec4770aadc0c2ca206 Mon Sep 17 00:00:00 2001 From: obrusvit Date: Wed, 25 Sep 2024 17:09:16 +0200 Subject: [PATCH] refactor(core/mercury): use params structs Supply the rust layout with dedicated paremeter type instead of plain micropython::Obj. The types used are ConfirmBlobParams and ShowInfoParams. [no changelog] --- .../ui/model_mercury/flow/confirm_output.rs | 80 +++-------- .../ui/model_mercury/flow/confirm_summary.rs | 41 ++---- .../rust/src/ui/model_mercury/flow/util.rs | 4 + .../embed/rust/src/ui/model_mercury/layout.rs | 134 +++++++++++++----- 4 files changed, 133 insertions(+), 126 deletions(-) diff --git a/core/embed/rust/src/ui/model_mercury/flow/confirm_output.rs b/core/embed/rust/src/ui/model_mercury/flow/confirm_output.rs index 3ea64885d1..4168fb1b81 100644 --- a/core/embed/rust/src/ui/model_mercury/flow/confirm_output.rs +++ b/core/embed/rust/src/ui/model_mercury/flow/confirm_output.rs @@ -2,7 +2,6 @@ use heapless::Vec; use crate::{ error, - micropython::{iter::IterBuf, obj::Obj, util}, strutil::TString, translations::TR, ui::{ @@ -212,40 +211,29 @@ fn get_cancel_page( } pub fn new_confirm_output( - title: Option>, - subtitle: Option>, + main_params: ConfirmBlobParams, account: Option>, account_path: Option>, br_name: TString<'static>, br_code: u16, - message: Obj, - amount: Option, - chunkify: bool, - text_mono: bool, - address: Option, + content_amount_params: Option, + address_params: Option, address_title: Option>, - summary_items: Obj, - fee_items: Obj, - summary_title: Option>, + summary_items_params: Option, + fee_items_params: ShowInfoParams, summary_br_name: Option>, summary_br_code: Option, cancel_text: Option>, ) -> Result { // Main - let main_content = ConfirmBlobParams::new(title.unwrap_or(TString::empty()), message, None) - .with_subtitle(subtitle) - .with_menu_button() - .with_footer(TR::instructions__swipe_up.into(), None) - .with_chunkify(chunkify) - .with_text_mono(text_mono) - .with_swipe_up() + let main_content = main_params .into_layout()? .one_button_request(ButtonRequest::from_num(br_code, br_name)); // MainMenu let mut main_menu = VerticalMenu::empty(); let mut main_menu_items = Vec::::new(); - if address.is_some() { + if address_params.is_some() { main_menu = main_menu.item( theme::ICON_CHEVRON_RIGHT, address_title.unwrap_or(TR::words__address.into()), @@ -279,17 +267,10 @@ pub fn new_confirm_output( let ac = AddressDetails::new(TR::send__send_from.into(), account, account_path)?; let account_content = ac.map(|_| Some(FlowMsg::Cancelled)); - let res = if amount.is_some() { - let content_amount = - ConfirmBlobParams::new(TR::words__amount.into(), amount.unwrap(), None) - .with_subtitle(subtitle) - .with_menu_button() - .with_footer(TR::instructions__swipe_up.into(), None) - .with_text_mono(text_mono) - .with_swipe_up() - .with_swipe_down() - .into_layout()? - .one_button_request(ButtonRequest::from_num(br_code, br_name)); + let res = if let Some(content_amount_params) = content_amount_params { + let content_amount = content_amount_params + .into_layout()? + .one_button_request(ButtonRequest::from_num(br_code, br_name)); SwipeFlow::new(&ConfirmOutputWithAmount::Address)? .with_page(&ConfirmOutputWithAmount::Address, main_content)? @@ -297,19 +278,9 @@ pub fn new_confirm_output( .with_page(&ConfirmOutputWithAmount::Menu, content_main_menu)? .with_page(&ConfirmOutputWithAmount::AccountInfo, account_content)? .with_page(&ConfirmOutputWithAmount::CancelTap, get_cancel_page())? - } else if summary_items != Obj::const_none() { + } else if let Some(summary_items_params) = summary_items_params { // Summary - let mut summary = - ShowInfoParams::new(summary_title.unwrap_or(TR::words__title_summary.into())) - .with_menu_button() - .with_footer(TR::instructions__swipe_up.into(), None) - .with_swipe_up() - .with_swipe_down(); - for pair in IterBuf::new().try_iterate(summary_items)? { - let [label, value]: [TString; 2] = util::iter_into_array(pair)?; - summary = unwrap!(summary.add(label, value)); - } - let content_summary = summary + let content_summary = summary_items_params .into_layout()? .one_button_request(ButtonRequest::from_num( summary_br_code.unwrap(), @@ -333,16 +304,8 @@ pub fn new_confirm_output( }); // FeeInfo - let mut has_fee_info = false; - let mut fee = ShowInfoParams::new(TR::confirm_total__title_fee.into()).with_cancel_button(); - if fee_items != Obj::const_none() { - for pair in IterBuf::new().try_iterate(fee_items)? { - let [label, value]: [TString; 2] = util::iter_into_array(pair)?; - fee = unwrap!(fee.add(label, value)); - has_fee_info = true; - } - } - let content_fee = fee.into_layout()?; + let has_fee_info = !fee_items_params.is_empty(); + let content_fee = fee_items_params.into_layout()?; // SummaryMenu let mut summary_menu = VerticalMenu::empty(); @@ -389,17 +352,8 @@ pub fn new_confirm_output( .with_page(&ConfirmOutputWithSummary::Main, main_content)? .with_page(&ConfirmOutputWithSummary::MainMenu, content_main_menu)? .with_page(&ConfirmOutputWithSummary::MainMenuCancel, get_cancel_page())?; - if address.is_some() { - let address_content = ConfirmBlobParams::new( - address_title.unwrap_or(TR::words__address.into()), - address.unwrap(), - None, - ) - .with_cancel_button() - .with_chunkify(true) - .with_text_mono(true) - .with_swipe_right() - .into_layout()?; + if let Some(address_params) = address_params { + let address_content = address_params.into_layout()?; flow = flow.with_page(&ConfirmOutputWithSummary::AddressInfo, address_content)?; } else { // dummy page - this will never be shown since there is no menu item pointing to diff --git a/core/embed/rust/src/ui/model_mercury/flow/confirm_summary.rs b/core/embed/rust/src/ui/model_mercury/flow/confirm_summary.rs index 2b2c4b9533..f7adb903cd 100644 --- a/core/embed/rust/src/ui/model_mercury/flow/confirm_summary.rs +++ b/core/embed/rust/src/ui/model_mercury/flow/confirm_summary.rs @@ -2,7 +2,6 @@ use heapless::Vec; use crate::{ error, - micropython::{iter::IterBuf, obj::Obj, util}, strutil::TString, translations::TR, ui::{ @@ -19,7 +18,8 @@ use crate::{ use super::{ super::{ component::{ - Frame, FrameMsg, PromptMsg, PromptScreen, VerticalMenu, VerticalMenuChoiceMsg, + Frame, FrameMsg, PromptMsg, PromptScreen, SwipeContent, VerticalMenu, + VerticalMenuChoiceMsg, }, theme, }, @@ -75,24 +75,15 @@ impl FlowController for ConfirmSummary { } pub fn new_confirm_summary( - title: TString<'static>, - items: Obj, - account_items: Obj, - fee_items: Obj, + summary_params: ShowInfoParams, + account_params: ShowInfoParams, + fee_params: ShowInfoParams, br_name: TString<'static>, br_code: u16, cancel_text: Option>, ) -> Result { // Summary - let mut summary = ShowInfoParams::new(title) - .with_menu_button() - .with_footer(TR::instructions__swipe_up.into(), None) - .with_swipe_up(); - for pair in IterBuf::new().try_iterate(items)? { - let [label, value]: [TString; 2] = util::iter_into_array(pair)?; - summary = unwrap!(summary.add(label, value)); - } - let content_summary = summary + let content_summary = summary_params .into_layout()? .one_button_request(ButtonRequest::from_num(br_code, br_name)) // Summary(1) + Hold(1) @@ -114,24 +105,12 @@ pub fn new_confirm_summary( }); // FeeInfo - let mut has_fee_info = false; - let mut fee = ShowInfoParams::new(TR::confirm_total__title_fee.into()).with_cancel_button(); - for pair in IterBuf::new().try_iterate(fee_items)? { - let [label, value]: [TString; 2] = util::iter_into_array(pair)?; - fee = unwrap!(fee.add(label, value)); - has_fee_info = true; - } - let content_fee = fee.into_layout()?; + let has_fee_info = !fee_params.is_empty(); + let content_fee = fee_params.into_layout()?; // AccountInfo - let mut has_account_info = false; - let mut account = ShowInfoParams::new(TR::send__send_from.into()).with_cancel_button(); - for pair in IterBuf::new().try_iterate(account_items)? { - let [label, value]: [TString; 2] = util::iter_into_array(pair)?; - account = unwrap!(account.add(label, value)); - has_account_info = true; - } - let content_account = account.into_layout()?; + let has_account_info = !account_params.is_empty(); + let content_account = account_params.into_layout()?; // Menu let mut menu = VerticalMenu::empty(); diff --git a/core/embed/rust/src/ui/model_mercury/flow/util.rs b/core/embed/rust/src/ui/model_mercury/flow/util.rs index ca38692ac3..df46538c8b 100644 --- a/core/embed/rust/src/ui/model_mercury/flow/util.rs +++ b/core/embed/rust/src/ui/model_mercury/flow/util.rs @@ -271,6 +271,10 @@ impl ShowInfoParams { } } + pub fn is_empty(&self) -> bool { + self.items.is_empty() + } + #[inline(never)] pub const fn with_subtitle(mut self, subtitle: Option>) -> Self { self.subtitle = subtitle; diff --git a/core/embed/rust/src/ui/model_mercury/layout.rs b/core/embed/rust/src/ui/model_mercury/layout.rs index a8c96960ee..20d7ed7085 100644 --- a/core/embed/rust/src/ui/model_mercury/layout.rs +++ b/core/embed/rust/src/ui/model_mercury/layout.rs @@ -52,6 +52,7 @@ use crate::{ component::{check_homescreen_format, SwipeContent}, flow::new_confirm_action_simple, flow::util::ConfirmBlobParams, + flow::util::ShowInfoParams, theme::ICON_BULLET_CHECKMARK, }, }, @@ -273,19 +274,15 @@ extern "C" fn new_confirm_blob(n_args: usize, args: *const Obj, kwargs: *mut Map let chunkify: bool = kwargs.get_or(Qstr::MP_QSTR_chunkify, false)?; let prompt_screen: bool = kwargs.get_or(Qstr::MP_QSTR_prompt_screen, true)?; - ConfirmBlobParams::new( - title, - data, - description, - ) - .with_extra(extra) - .with_chunkify(chunkify) - .with_verb_cancel(verb_cancel) - .with_hold(hold) - .with_prompt(prompt_screen) - .into_flow() - .and_then(LayoutObj::new) - .map(Into::into) + ConfirmBlobParams::new(title, data, description) + .with_extra(extra) + .with_chunkify(chunkify) + .with_verb_cancel(verb_cancel) + .with_hold(hold) + .with_prompt(prompt_screen) + .into_flow() + .and_then(LayoutObj::new) + .map(Into::into) }; unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } } @@ -488,8 +485,9 @@ extern "C" fn new_confirm_output(n_args: usize, args: *const Obj, kwargs: *mut M let address_title: Option = kwargs.get(Qstr::MP_QSTR_address_title)?.try_into_option()?; - let summary_items: Obj = kwargs.get(Qstr::MP_QSTR_summary_items)?; - let fee_items: Obj = kwargs.get(Qstr::MP_QSTR_fee_items)?; + let summary_items: Option = + kwargs.get(Qstr::MP_QSTR_summary_items)?.try_into_option()?; + let fee_items: Option = kwargs.get(Qstr::MP_QSTR_fee_items)?.try_into_option()?; let summary_title: Option = kwargs.get(Qstr::MP_QSTR_summary_title)?.try_into_option()?; @@ -503,22 +501,72 @@ extern "C" fn new_confirm_output(n_args: usize, args: *const Obj, kwargs: *mut M let cancel_text: Option = kwargs.get(Qstr::MP_QSTR_cancel_text)?.try_into_option()?; + let main_params = ConfirmBlobParams::new(title.unwrap_or(TString::empty()), message, None) + .with_subtitle(subtitle) + .with_menu_button() + .with_footer(TR::instructions__swipe_up.into(), None) + .with_chunkify(chunkify) + .with_text_mono(text_mono) + .with_swipe_up(); + + let content_amount_params = amount.map(|amount| { + ConfirmBlobParams::new(TR::words__amount.into(), amount, None) + .with_subtitle(subtitle) + .with_menu_button() + .with_footer(TR::instructions__swipe_up.into(), None) + .with_text_mono(text_mono) + .with_swipe_up() + .with_swipe_down() + }); + + let address_params = address.map(|address| { + ConfirmBlobParams::new( + address_title.unwrap_or(TR::words__address.into()), + address, + None, + ) + .with_cancel_button() + .with_chunkify(true) + .with_text_mono(true) + .with_swipe_right() + }); + + let mut fee_items_params = + ShowInfoParams::new(TR::confirm_total__title_fee.into()).with_cancel_button(); + if fee_items.is_some() { + for pair in IterBuf::new().try_iterate(fee_items.unwrap())? { + let [label, value]: [TString; 2] = util::iter_into_array(pair)?; + fee_items_params = unwrap!(fee_items_params.add(label, value)); + } + } + + let summary_items_params: Option = if summary_items.is_some() { + let mut summary = + ShowInfoParams::new(summary_title.unwrap_or(TR::words__title_summary.into())) + .with_menu_button() + .with_footer(TR::instructions__swipe_up.into(), None) + .with_swipe_up() + .with_swipe_down(); + for pair in IterBuf::new().try_iterate(summary_items.unwrap())? { + let [label, value]: [TString; 2] = util::iter_into_array(pair)?; + summary = unwrap!(summary.add(label, value)); + } + Some(summary) + } else { + None + }; + let flow = flow::confirm_output::new_confirm_output( - title, - subtitle, + main_params, account, account_path, br_name, br_code, - message, - amount, - chunkify, - text_mono, - address, + content_amount_params, + address_params, address_title, - summary_items, - fee_items, - summary_title, + summary_items_params, + fee_items_params, summary_br_name, summary_br_code, cancel_text, @@ -539,11 +587,33 @@ extern "C" fn new_confirm_summary(n_args: usize, args: *const Obj, kwargs: *mut let cancel_text: Option = kwargs.get(Qstr::MP_QSTR_cancel_text)?.try_into_option()?; - let flow = flow::confirm_summary::new_confirm_summary( - title, - items, - account_items, - fee_items, + let mut summary_params = ShowInfoParams::new(title.clone()) + .with_menu_button() + .with_footer(TR::instructions__swipe_up.into(), None) + .with_swipe_up(); + for pair in IterBuf::new().try_iterate(items)? { + let [label, value]: [TString; 2] = util::iter_into_array(pair)?; + summary_params = unwrap!(summary_params.add(label, value)); + } + + let mut account_params = + ShowInfoParams::new(TR::send__send_from.into()).with_cancel_button(); + for pair in IterBuf::new().try_iterate(account_items)? { + let [label, value]: [TString; 2] = util::iter_into_array(pair)?; + account_params = unwrap!(account_params.add(label, value)); + } + + let mut fee_params = + ShowInfoParams::new(TR::confirm_total__title_fee.into()).with_cancel_button(); + for pair in IterBuf::new().try_iterate(fee_items)? { + let [label, value]: [TString; 2] = util::iter_into_array(pair)?; + fee_params = unwrap!(fee_params.add(label, value)); + } + + let flow = flow::new_confirm_summary( + summary_params, + account_params, + fee_params, br_name, br_code, cancel_text, @@ -625,8 +695,8 @@ extern "C" fn new_confirm_value(n_args: usize, args: *const Obj, kwargs: *mut Ma .with_prompt(hold) .with_hold(hold) .into_flow() - .and_then(LayoutObj::new) - .map(Into::into) + .and_then(LayoutObj::new) + .map(Into::into) }; unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } }