1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-01-08 06:20:56 +00:00

refactor(core): model_t confirm_summary

- model_t confirm_total refactored to confirm_summary
- parameter set changed to pave the way for unification across models

[no changelog]
This commit is contained in:
obrusvit 2024-11-28 15:06:08 +01:00 committed by Vít Obrusník
parent ef02c4de5d
commit 6e94748e92
5 changed files with 155 additions and 82 deletions

View File

@ -37,6 +37,7 @@ static void _librust_qstrs(void) {
MP_QSTR___dict__; MP_QSTR___dict__;
MP_QSTR___name__; MP_QSTR___name__;
MP_QSTR_account; MP_QSTR_account;
MP_QSTR_account_info;
MP_QSTR_account_items; MP_QSTR_account_items;
MP_QSTR_account_items_title; MP_QSTR_account_items_title;
MP_QSTR_account_label; MP_QSTR_account_label;
@ -72,6 +73,7 @@ static void _librust_qstrs(void) {
MP_QSTR_altcoin_tx_summary; MP_QSTR_altcoin_tx_summary;
MP_QSTR_amount; MP_QSTR_amount;
MP_QSTR_amount_change; MP_QSTR_amount_change;
MP_QSTR_amount_label;
MP_QSTR_amount_new; MP_QSTR_amount_new;
MP_QSTR_amount_title; MP_QSTR_amount_title;
MP_QSTR_amount_value; MP_QSTR_amount_value;
@ -209,6 +211,7 @@ static void _librust_qstrs(void) {
MP_QSTR_confirm_properties; MP_QSTR_confirm_properties;
MP_QSTR_confirm_recovery; MP_QSTR_confirm_recovery;
MP_QSTR_confirm_reset_device; MP_QSTR_confirm_reset_device;
MP_QSTR_confirm_summary;
MP_QSTR_confirm_total; MP_QSTR_confirm_total;
MP_QSTR_confirm_total__fee_rate; MP_QSTR_confirm_total__fee_rate;
MP_QSTR_confirm_total__fee_rate_colon; MP_QSTR_confirm_total__fee_rate_colon;
@ -242,7 +245,10 @@ static void _librust_qstrs(void) {
MP_QSTR_experimental_mode__only_for_dev; MP_QSTR_experimental_mode__only_for_dev;
MP_QSTR_experimental_mode__title; MP_QSTR_experimental_mode__title;
MP_QSTR_extra; MP_QSTR_extra;
MP_QSTR_extra_info;
MP_QSTR_fee;
MP_QSTR_fee_amount; MP_QSTR_fee_amount;
MP_QSTR_fee_info;
MP_QSTR_fee_items; MP_QSTR_fee_items;
MP_QSTR_fee_label; MP_QSTR_fee_label;
MP_QSTR_fee_rate_amount; MP_QSTR_fee_rate_amount;

View File

@ -93,20 +93,12 @@ where
left: Option<TString<'static>>, left: Option<TString<'static>>,
right: Option<TString<'static>>, right: Option<TString<'static>>,
) -> Self { ) -> Self {
let cancel = match left {
Some(verb) => verb.map(|s| match s {
"^" => Button::with_icon(theme::ICON_UP),
"<" => Button::with_icon(theme::ICON_BACK),
_ => Button::with_text(verb),
}),
_ => Button::with_icon(theme::ICON_CANCEL),
};
let confirm = match right { let confirm = match right {
Some(verb) => Button::with_text(verb).styled(theme::button_confirm()), Some(verb) => Button::with_text(verb).styled(theme::button_confirm()),
_ => Button::with_icon(theme::ICON_CONFIRM).styled(theme::button_confirm()), _ => Button::with_icon(theme::ICON_CONFIRM).styled(theme::button_confirm()),
}; };
self.button_cancel = Some(cancel);
self.button_confirm = confirm; self.button_confirm = confirm;
self = self.with_cancel_button(left);
self self
} }
@ -117,8 +109,16 @@ where
self self
} }
pub fn with_cancel_arrow(mut self) -> Self { pub fn with_cancel_button(mut self, left: Option<TString<'static>>) -> Self {
self.button_cancel = Some(Button::with_icon(theme::ICON_UP)); let cancel = match left {
Some(verb) => verb.map(|s| match s {
"^" => Button::with_icon(theme::ICON_UP),
"<" => Button::with_icon(theme::ICON_BACK),
_ => Button::with_text(verb),
}),
_ => Button::with_icon(theme::ICON_CANCEL),
};
self.button_cancel = Some(cancel);
self self
} }

View File

@ -763,28 +763,52 @@ extern "C" fn new_confirm_value(n_args: usize, args: *const Obj, kwargs: *mut Ma
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
} }
extern "C" fn new_confirm_total(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj { extern "C" fn new_confirm_summary(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| { let block = move |_args: &[Obj], kwargs: &Map| {
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?; let amount: TString = kwargs.get(Qstr::MP_QSTR_amount)?.try_into()?;
let items: Obj = kwargs.get(Qstr::MP_QSTR_items)?; let amount_label: TString = kwargs.get(Qstr::MP_QSTR_amount_label)?.try_into()?;
let info_button: bool = kwargs.get_or(Qstr::MP_QSTR_info_button, false)?; let fee: TString = kwargs.get(Qstr::MP_QSTR_fee)?.try_into()?;
let cancel_arrow: bool = kwargs.get_or(Qstr::MP_QSTR_cancel_arrow, false)?; let fee_label: TString = kwargs.get(Qstr::MP_QSTR_fee_label)?.try_into()?;
let title: Option<TString> = kwargs
.get(Qstr::MP_QSTR_title)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let account_items: Option<Obj> = kwargs
.get(Qstr::MP_QSTR_account_items)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let extra_items: Option<Obj> = kwargs
.get(Qstr::MP_QSTR_extra_items)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let _extra_title: Option<TString> = kwargs
.get(Qstr::MP_QSTR_extra_title)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let verb_cancel: Option<TString<'static>> = kwargs
.get(Qstr::MP_QSTR_verb_cancel)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let mut paragraphs = ParagraphVecShort::new(); let info_button: bool = account_items.is_some() || extra_items.is_some();
let paragraphs = ParagraphVecShort::from_iter([
Paragraph::new(&theme::TEXT_NORMAL, amount_label).no_break(),
Paragraph::new(&theme::TEXT_MONO, amount),
Paragraph::new(&theme::TEXT_NORMAL, fee_label).no_break(),
Paragraph::new(&theme::TEXT_MONO, fee),
]);
for pair in IterBuf::new().try_iterate(items)? { let mut page = ButtonPage::new(paragraphs.into_paragraphs(), theme::BG)
let [label, value]: [TString; 2] = util::iter_into_array(pair)?; .with_hold()?
paragraphs.add(Paragraph::new(&theme::TEXT_NORMAL, label).no_break()); .with_cancel_button(verb_cancel);
paragraphs.add(Paragraph::new(&theme::TEXT_MONO, value));
}
let mut page = ButtonPage::new(paragraphs.into_paragraphs(), theme::BG).with_hold()?;
if cancel_arrow {
page = page.with_cancel_arrow()
}
if info_button { if info_button {
page = page.with_swipe_left(); page = page.with_swipe_left();
} }
let mut frame = Frame::left_aligned(theme::label_title(), title, page); let mut frame = Frame::left_aligned(
theme::label_title(),
title.unwrap_or(TString::empty()),
page,
);
if info_button { if info_button {
frame = frame.with_info_button(); frame = frame.with_info_button();
} }
@ -1868,15 +1892,20 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// """Confirm value. Merge of confirm_total and confirm_output.""" /// """Confirm value. Merge of confirm_total and confirm_output."""
Qstr::MP_QSTR_confirm_value => obj_fn_kw!(0, new_confirm_value).as_obj(), Qstr::MP_QSTR_confirm_value => obj_fn_kw!(0, new_confirm_value).as_obj(),
/// def confirm_total( /// def confirm_summary(
/// *, /// *,
/// title: str, /// amount: str,
/// items: Iterable[tuple[str, str]], /// amount_label: str,
/// info_button: bool = False, /// fee: str,
/// cancel_arrow: bool = False, /// fee_label: str,
/// title: str | None = None,
/// account_items: Iterable[tuple[str, str]] | None = None,
/// extra_items: Iterable[tuple[str, str]] | None = None,
/// extra_title: str | None = None,
/// verb_cancel: str | None = None,
/// ) -> LayoutObj[UiResult]: /// ) -> LayoutObj[UiResult]:
/// """Transaction summary. Always hold to confirm.""" /// """Confirm summary of a transaction."""
Qstr::MP_QSTR_confirm_total => obj_fn_kw!(0, new_confirm_total).as_obj(), Qstr::MP_QSTR_confirm_summary => obj_fn_kw!(0, new_confirm_summary).as_obj(),
/// def confirm_modify_output( /// def confirm_modify_output(
/// *, /// *,

View File

@ -1290,14 +1290,19 @@ def confirm_value(
# rust/src/ui/model_tt/layout.rs # rust/src/ui/model_tt/layout.rs
def confirm_total( def confirm_summary(
*, *,
title: str, amount: str,
items: Iterable[tuple[str, str]], amount_label: str,
info_button: bool = False, fee: str,
cancel_arrow: bool = False, fee_label: str,
title: str | None = None,
account_items: Iterable[tuple[str, str]] | None = None,
extra_items: Iterable[tuple[str, str]] | None = None,
extra_title: str | None = None,
verb_cancel: str | None = None,
) -> LayoutObj[UiResult]: ) -> LayoutObj[UiResult]:
"""Transaction summary. Always hold to confirm.""" """Confirm summary of a transaction."""
# rust/src/ui/model_tt/layout.rs # rust/src/ui/model_tt/layout.rs

View File

@ -750,43 +750,61 @@ def confirm_total(
total_label = total_label or f"{TR.send__total_amount}:" # def_arg total_label = total_label or f"{TR.send__total_amount}:" # def_arg
fee_label = fee_label or TR.send__including_fee # def_arg fee_label = fee_label or TR.send__including_fee # def_arg
items = [ account_info_items = []
(total_label, total_amount), extra_info_items = []
(fee_label, fee_amount),
]
info_items = []
if source_account: if source_account:
info_items.append((TR.confirm_total__sending_from_account, source_account)) account_info_items.append(
(TR.confirm_total__sending_from_account, source_account)
)
if fee_rate_amount: if fee_rate_amount:
info_items.append((f"{TR.confirm_total__fee_rate}:", fee_rate_amount)) extra_info_items.append((f"{TR.confirm_total__fee_rate}:", fee_rate_amount))
return _confirm_summary( return _confirm_summary(
items, total_amount,
TR.words__title_summary, total_label,
info_items=info_items, fee_amount,
fee_label,
title=title,
account_items=account_info_items,
extra_items=extra_info_items,
extra_title=TR.words__title_information,
br_name=br_name, br_name=br_name,
br_code=br_code, br_code=br_code,
) )
def _confirm_summary( def _confirm_summary(
items: Iterable[tuple[str, str]], amount: str,
amount_label: str,
fee: str,
fee_label: str,
title: str | None = None, title: str | None = None,
info_items: Iterable[tuple[str, str]] | None = None, account_items: Iterable[tuple[str, str]] | None = None,
info_title: str | None = None, extra_items: Iterable[tuple[str, str]] | None = None,
extra_title: str | None = None,
br_name: str = "confirm_total", br_name: str = "confirm_total",
br_code: ButtonRequestType = ButtonRequestType.SignTx, br_code: ButtonRequestType = ButtonRequestType.SignTx,
) -> Awaitable[None]: ) -> Awaitable[None]:
title = title or TR.words__title_summary # def_arg title = title or TR.words__title_summary # def_arg
total_layout = trezorui2.confirm_total( total_layout = trezorui2.confirm_summary(
amount=amount,
amount_label=amount_label,
fee=fee,
fee_label=fee_label,
title=title, title=title,
items=items, account_items=account_items or None,
info_button=bool(info_items), extra_items=extra_items or None,
) )
info_items = info_items or []
# TODO: use `_info` params directly in this^ layout instead of using `with_info`
info_items = []
if account_items:
info_items.extend(account_items)
if extra_items:
info_items.extend(extra_items)
info_layout = trezorui2.show_info_with_cancel( info_layout = trezorui2.show_info_with_cancel(
title=info_title if info_title else TR.words__title_information, title=extra_title if extra_title else TR.words__title_information,
items=info_items, items=info_items,
) )
return with_info(total_layout, info_layout, br_name, br_code) return with_info(total_layout, info_layout, br_name, br_code)
@ -811,14 +829,16 @@ if not utils.BITCOIN_ONLY:
br_code: ButtonRequestType = ButtonRequestType.SignTx, br_code: ButtonRequestType = ButtonRequestType.SignTx,
chunkify: bool = False, chunkify: bool = False,
) -> None: ) -> None:
total_layout = trezorui2.confirm_total( # NOTE: fee_info used so that info button is shown
total_layout = trezorui2.confirm_summary(
amount=total_amount,
amount_label=f"{TR.words__amount}:",
fee=maximum_fee,
fee_label=f"{TR.send__maximum_fee}:",
title=TR.words__title_summary, title=TR.words__title_summary,
items=[ extra_items=fee_info_items,
(f"{TR.words__amount}:", total_amount), extra_title=TR.confirm_total__title_fee,
(f"{TR.send__maximum_fee}:", maximum_fee), verb_cancel="^",
],
info_button=True,
cancel_arrow=True,
) )
info_layout = trezorui2.show_info_with_cancel( info_layout = trezorui2.show_info_with_cancel(
title=TR.confirm_total__title_fee, title=TR.confirm_total__title_fee,
@ -879,17 +899,23 @@ if not utils.BITCOIN_ONLY:
# confirmation # confirmation
if verb == TR.ethereum__staking_claim: if verb == TR.ethereum__staking_claim:
items = ((f"{TR.send__maximum_fee}:", maximum_fee),) amount = ""
amount_label = ""
fee_label = f"{TR.send__maximum_fee}:"
fee = maximum_fee
else: else:
items = ( amount_label = f"{TR.words__amount}:"
(f"{TR.words__amount}:", total_amount), amount = total_amount
(f"{TR.send__maximum_fee}:", maximum_fee), fee_label = f"{TR.send__maximum_fee}:"
) fee = maximum_fee
await _confirm_summary( await _confirm_summary(
items, # items amount,
amount_label,
fee,
fee_label,
title=title, title=title,
info_title=TR.confirm_total__title_fee, extra_items=[(f"{k}:", v) for (k, v) in info_items],
info_items=[(f"{k}:", v) for (k, v) in info_items], extra_title=TR.confirm_total__title_fee,
br_name=br_name, br_name=br_name,
br_code=br_code, br_code=br_code,
) )
@ -908,8 +934,11 @@ if not utils.BITCOIN_ONLY:
) # def_arg ) # def_arg
fee_title = fee_title or TR.words__fee # def_arg fee_title = fee_title or TR.words__fee # def_arg
return _confirm_summary( return _confirm_summary(
((amount_title, amount), (fee_title, fee)), amount,
info_items=items, amount_title,
fee,
fee_title,
extra_items=items,
br_name=br_name, br_name=br_name,
br_code=br_code, br_code=br_code,
) )
@ -922,8 +951,11 @@ if not utils.BITCOIN_ONLY:
amount_title = f"{TR.send__total_amount}:" amount_title = f"{TR.send__total_amount}:"
fee_title = TR.send__including_fee fee_title = TR.send__including_fee
return _confirm_summary( return _confirm_summary(
((amount_title, amount), (fee_title, fee)), amount,
info_items=items, amount_title,
fee,
fee_title,
extra_items=items,
br_name="confirm_cardano_tx", br_name="confirm_cardano_tx",
br_code=ButtonRequestType.SignTx, br_code=ButtonRequestType.SignTx,
) )
@ -931,12 +963,13 @@ if not utils.BITCOIN_ONLY:
def confirm_joint_total(spending_amount: str, total_amount: str) -> Awaitable[None]: def confirm_joint_total(spending_amount: str, total_amount: str) -> Awaitable[None]:
return raise_if_not_confirmed( return raise_if_not_confirmed(
trezorui2.confirm_total( # FIXME: arguments for amount/fee are misused here
trezorui2.confirm_summary(
amount=spending_amount,
amount_label=TR.send__you_are_contributing,
fee=total_amount,
fee_label=TR.send__to_the_total_amount,
title=TR.send__title_joint_transaction, title=TR.send__title_joint_transaction,
items=[
(TR.send__you_are_contributing, spending_amount),
(TR.send__to_the_total_amount, total_amount),
],
), ),
"confirm_joint_total", "confirm_joint_total",
ButtonRequestType.SignTx, ButtonRequestType.SignTx,