1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-01-03 12:00:59 +00:00

refactor(core): consistent use of confirm_address

- use `confirm_address` trait fn in both `confirm_output` and
`confirm_address` layout functions

[no changelog]
This commit is contained in:
obrusvit 2024-12-18 17:38:24 +01:00 committed by Vít Obrusník
parent 7e1f160dba
commit e9ecbbc5e8
9 changed files with 81 additions and 94 deletions

View File

@ -63,6 +63,7 @@ static void _librust_qstrs(void) {
MP_QSTR_address_details__derivation_path_colon; MP_QSTR_address_details__derivation_path_colon;
MP_QSTR_address_details__title_receive_address; MP_QSTR_address_details__title_receive_address;
MP_QSTR_address_details__title_receiving_to; MP_QSTR_address_details__title_receiving_to;
MP_QSTR_address_label;
MP_QSTR_address_qr; MP_QSTR_address_qr;
MP_QSTR_address_title; MP_QSTR_address_title;
MP_QSTR_allow_cancel; MP_QSTR_allow_cancel;

View File

@ -89,23 +89,21 @@ extern "C" fn new_confirm_action(n_args: usize, args: *const Obj, kwargs: *mut M
extern "C" fn new_confirm_address(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj { extern "C" fn new_confirm_address(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 title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let data: Obj = kwargs.get(Qstr::MP_QSTR_data)?; let address: Obj = kwargs.get(Qstr::MP_QSTR_address)?;
let description: Option<TString> = kwargs let address_label: Option<TString> = kwargs
.get(Qstr::MP_QSTR_description) .get(Qstr::MP_QSTR_address_label)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let extra: Option<TString> = kwargs
.get(Qstr::MP_QSTR_extra)
.unwrap_or_else(|_| Obj::const_none()) .unwrap_or_else(|_| Obj::const_none())
.try_into_option()?; .try_into_option()?;
let verb: Option<TString> = kwargs let verb: Option<TString> = kwargs
.get(Qstr::MP_QSTR_verb) .get(Qstr::MP_QSTR_verb)
.unwrap_or_else(|_| Obj::const_none()) .unwrap_or_else(|_| Obj::const_none())
.try_into_option()?; .try_into_option()?;
let info_button: bool = kwargs.get_or(Qstr::MP_QSTR_info_button, false)?;
let chunkify: bool = kwargs.get_or(Qstr::MP_QSTR_chunkify, false)?; let chunkify: bool = kwargs.get_or(Qstr::MP_QSTR_chunkify, false)?;
let layout = ModelUI::confirm_address(title, data, description, extra, verb, chunkify)?; let layout_obj =
Ok(LayoutObj::new_root(layout)?.into()) ModelUI::confirm_address(title, address, address_label, verb, info_button, chunkify)?;
Ok(layout_obj.into())
}; };
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
} }
@ -1163,10 +1161,10 @@ pub static mp_module_trezorui_api: Module = obj_module! {
/// def confirm_address( /// def confirm_address(
/// *, /// *,
/// title: str, /// title: str,
/// data: str | bytes, /// address: str | bytes,
/// description: str | None, /// address_label: str | None = None,
/// extra: str | None,
/// verb: str | None = None, /// verb: str | None = None,
/// info_button: bool = False,
/// chunkify: bool = False, /// chunkify: bool = False,
/// ) -> LayoutObj[UiResult]: /// ) -> LayoutObj[UiResult]:
/// """Confirm address.""" /// """Confirm address."""

View File

@ -75,16 +75,14 @@ impl FirmwareUI for UIMercury {
fn confirm_address( fn confirm_address(
_title: TString<'static>, _title: TString<'static>,
_data: Obj, _address: Obj,
_description: Option<TString<'static>>, _address_label: Option<TString<'static>>,
_extra: Option<TString<'static>>,
_verb: Option<TString<'static>>, _verb: Option<TString<'static>>,
_info_button: bool,
_chunkify: bool, _chunkify: bool,
) -> Result<impl LayoutMaybeTrace, Error> { ) -> Result<Gc<LayoutObj>, Error> {
// confirm_value is used instead // confirm_value is used instead
Err::<RootComponent<Empty, ModelUI>, Error>(Error::ValueError( Err::<Gc<LayoutObj>, Error>(Error::ValueError(c"confirm_address not implemented"))
c"confirm_address not implemented",
))
} }
fn confirm_blob( fn confirm_blob(

View File

@ -89,34 +89,50 @@ impl FirmwareUI for UIModelTR {
fn confirm_address( fn confirm_address(
title: TString<'static>, title: TString<'static>,
data: Obj, address: Obj,
_description: Option<TString<'static>>, address_label: Option<TString<'static>>,
_extra: Option<TString<'static>>,
verb: Option<TString<'static>>, verb: Option<TString<'static>>,
info_button: bool,
chunkify: bool, chunkify: bool,
) -> Result<impl LayoutMaybeTrace, Error> { ) -> Result<Gc<LayoutObj>, Error> {
let verb = verb.unwrap_or(TR::buttons__confirm.into()); let verb = verb.unwrap_or(TR::buttons__confirm.into());
let address: TString = data.try_into()?; let address: TString = address.try_into()?;
let get_page = move |page_index| { let get_page = move |page_index| {
assert!(page_index == 0); assert!(page_index == 0);
let (btn_layout, btn_actions) = if info_button {
let btn_layout = ButtonLayout::cancel_armed_info(verb); (
let btn_actions = ButtonActions::cancel_confirm_info(); ButtonLayout::cancel_armed_info(verb),
let style = if chunkify { ButtonActions::cancel_confirm_info(),
// Chunkifying the address into smaller pieces when requested )
theme::TEXT_MONO_ADDRESS_CHUNKS
} else { } else {
theme::TEXT_MONO_DATA (
ButtonLayout::cancel_none_text(verb),
ButtonActions::cancel_none_confirm(),
)
}; };
let ops = OpTextLayout::new(style).text_mono(address); let mut ops = OpTextLayout::new(theme::TEXT_MONO_DATA);
if let Some(label) = address_label {
// NOTE: need to explicitly turn off the chunkification before rendering the
// address label (for some reason it does not help to turn it off after
// rendering the chunks)
if chunkify {
ops = ops.chunkify_text(None);
}
ops = ops.text_normal(label).newline();
}
if chunkify {
// Chunkifying the address into smaller pieces when requested
ops = ops.chunkify_text(Some((theme::MONO_CHUNKS, 2)));
}
ops = ops.text_mono(address);
let formatted = FormattedText::new(ops).vertically_centered(); let formatted = FormattedText::new(ops).vertically_centered();
Page::new(btn_layout, btn_actions, formatted).with_title(title) Page::new(btn_layout, btn_actions, formatted).with_title(title)
}; };
let pages = FlowPages::new(get_page, 1); let pages = FlowPages::new(get_page, 1);
let layout = RootComponent::new(Flow::new(pages)); let obj = LayoutObj::new(Flow::new(pages))?;
Ok(layout) Ok(obj)
} }
fn confirm_blob( fn confirm_blob(

View File

@ -87,41 +87,18 @@ impl FirmwareUI for UIModelTT {
fn confirm_address( fn confirm_address(
title: TString<'static>, title: TString<'static>,
data: Obj, address: Obj,
description: Option<TString<'static>>, address_label: Option<TString<'static>>,
extra: Option<TString<'static>>,
verb: Option<TString<'static>>, verb: Option<TString<'static>>,
info_button: bool,
chunkify: bool, chunkify: bool,
) -> Result<impl LayoutMaybeTrace, Error> { ) -> Result<Gc<LayoutObj>, Error> {
let verb = verb.unwrap_or(TR::buttons__confirm.into()); let verb = verb.unwrap_or(TR::buttons__confirm.into());
let data_style = if chunkify { ConfirmBlobParams::new(title, address, None, Some(verb), None, false)
let address: TString = data.try_into()?; .with_subtitle(address_label)
theme::get_chunkified_text_style(address.len()) .with_info_button(info_button)
} else { .with_chunkify(chunkify)
&theme::TEXT_MONO .into_layout()
};
let paragraphs = ConfirmBlob {
description: description.unwrap_or("".into()),
extra: extra.unwrap_or("".into()),
data: data.try_into()?,
description_font: &theme::TEXT_NORMAL,
extra_font: &theme::TEXT_DEMIBOLD,
data_font: data_style,
}
.into_paragraphs();
let layout = RootComponent::new(
Frame::left_aligned(
theme::label_title(),
title,
ButtonPage::new(paragraphs, theme::BG)
.with_swipe_left()
.with_cancel_confirm(None, Some(verb)),
)
.with_info_button(),
);
Ok(layout)
} }
fn confirm_blob( fn confirm_blob(

View File

@ -33,12 +33,12 @@ pub trait FirmwareUI {
fn confirm_address( fn confirm_address(
title: TString<'static>, title: TString<'static>,
data: Obj, // TODO: replace Obj address: Obj, // TODO: replace Obj
description: Option<TString<'static>>, address_label: Option<TString<'static>>,
extra: Option<TString<'static>>,
verb: Option<TString<'static>>, verb: Option<TString<'static>>,
info_button: bool,
chunkify: bool, chunkify: bool,
) -> Result<impl LayoutMaybeTrace, Error>; ) -> Result<Gc<LayoutObj>, Error>; // TODO: return LayoutMaybeTrace
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
fn confirm_blob( fn confirm_blob(

View File

@ -102,10 +102,10 @@ def confirm_action(
def confirm_address( def confirm_address(
*, *,
title: str, title: str,
data: str | bytes, address: str | bytes,
description: str | None, address_label: str | None = None,
extra: str | None,
verb: str | None = None, verb: str | None = None,
info_button: bool = False,
chunkify: bool = False, chunkify: bool = False,
) -> LayoutObj[UiResult]: ) -> LayoutObj[UiResult]:
"""Confirm address.""" """Confirm address."""

View File

@ -257,9 +257,9 @@ async def show_address(
result = await interact( result = await interact(
trezorui_api.confirm_address( trezorui_api.confirm_address(
title=title, title=title,
data=address, address=address,
description="", # unused on TR address_label=None,
extra=None, # unused on TR info_button=True,
chunkify=chunkify, chunkify=chunkify,
), ),
br_name if send_button_request else None, br_name if send_button_request else None,
@ -485,13 +485,12 @@ async def confirm_output(
while True: while True:
await interact( await interact(
trezorui_api.confirm_blob( trezorui_api.confirm_address(
title=address_title, title=address_title,
data=address, address=address,
description=address_label or "", address_label=address_label or None,
subtitle=None,
verb=TR.buttons__continue, verb=TR.buttons__continue,
verb_cancel="", info_button=False,
chunkify=chunkify, chunkify=chunkify,
), ),
"confirm_output", "confirm_output",
@ -500,9 +499,9 @@ async def confirm_output(
try: try:
await interact( await interact(
trezorui_api.confirm_blob( trezorui_api.confirm_value(
title=amount_title, title=amount_title,
data=amount, value=amount,
description=None, description=None,
subtitle=None, subtitle=None,
verb_cancel="^", verb_cancel="^",

View File

@ -243,9 +243,9 @@ async def show_address(
result = await interact( result = await interact(
trezorui_api.confirm_address( trezorui_api.confirm_address(
title=title, title=title,
data=address, address=address,
description=network or "", address_label=network or None,
extra=None, info_button=True,
chunkify=chunkify, chunkify=chunkify,
), ),
br_name if send_button_request else None, br_name if send_button_request else None,
@ -427,13 +427,11 @@ async def confirm_output(
while True: while True:
# if the user cancels here, raise ActionCancelled (by default) # if the user cancels here, raise ActionCancelled (by default)
await interact( await interact(
trezorui_api.confirm_value( trezorui_api.confirm_address(
title=recipient_title, title=recipient_title,
subtitle=address_label, address=address,
description=None, address_label=address_label,
value=address,
verb=TR.buttons__continue, verb=TR.buttons__continue,
hold=False,
info_button=False, info_button=False,
chunkify=chunkify, chunkify=chunkify,
), ),
@ -1105,10 +1103,10 @@ async def confirm_signverify(
address_layout = trezorui_api.confirm_address( address_layout = trezorui_api.confirm_address(
title=address_title, title=address_title,
data=address, address=address,
description="", address_label=None,
verb=TR.buttons__continue, verb=TR.buttons__continue,
extra=None, info_button=True,
chunkify=chunkify, chunkify=chunkify,
) )