1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-29 10:58:21 +00:00

refactor(core): move confirm_properties

This commit is contained in:
obrusvit 2024-11-22 13:12:13 +01:00
parent 5d009d8587
commit 48f1964ec0
13 changed files with 137 additions and 174 deletions

View File

@ -233,6 +233,18 @@ extern "C" fn new_confirm_modify_output(n_args: usize, args: *const Obj, kwargs:
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_properties(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let items: Obj = kwargs.get(Qstr::MP_QSTR_items)?;
let hold: bool = kwargs.get_or(Qstr::MP_QSTR_hold, false)?;
let layout = ModelUI::confirm_properties(title, items, hold)?;
Ok(LayoutObj::new_root(layout)?.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
extern "C" fn new_confirm_reset_device(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj { extern "C" fn new_confirm_reset_device(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 recovery: bool = kwargs.get(Qstr::MP_QSTR_recovery)?.try_into()?; let recovery: bool = kwargs.get(Qstr::MP_QSTR_recovery)?.try_into()?;
@ -937,6 +949,16 @@ pub static mp_module_trezorui_api: Module = obj_module! {
/// """Decrease or increase output amount.""" /// """Decrease or increase output amount."""
Qstr::MP_QSTR_confirm_modify_output => obj_fn_kw!(0, new_confirm_modify_output).as_obj(), Qstr::MP_QSTR_confirm_modify_output => obj_fn_kw!(0, new_confirm_modify_output).as_obj(),
/// def confirm_properties(
/// *,
/// title: str,
/// items: list[tuple[str | None, str | bytes | None, bool]],
/// hold: bool = False,
/// ) -> LayoutObj[UiResult]:
/// """Confirm list of key-value pairs. The third component in the tuple should be True if
/// the value is to be rendered as binary with monospace font, False otherwise."""
Qstr::MP_QSTR_confirm_properties => obj_fn_kw!(0, new_confirm_properties).as_obj(),
/// def confirm_reset_device(recovery: bool) -> LayoutObj[UiResult]: /// def confirm_reset_device(recovery: bool) -> LayoutObj[UiResult]:
/// """Confirm TOS before creating wallet creation or wallet recovery.""" /// """Confirm TOS before creating wallet creation or wallet recovery."""
Qstr::MP_QSTR_confirm_reset_device => obj_fn_kw!(0, new_confirm_reset_device).as_obj(), Qstr::MP_QSTR_confirm_reset_device => obj_fn_kw!(0, new_confirm_reset_device).as_obj(),

View File

@ -296,32 +296,6 @@ extern "C" fn new_confirm_address(n_args: usize, args: *const Obj, kwargs: *mut
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_properties(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let hold: bool = kwargs.get_or(Qstr::MP_QSTR_hold, false)?;
let items: Obj = kwargs.get(Qstr::MP_QSTR_items)?;
let paragraphs = PropsList::new(
items,
&theme::TEXT_NORMAL,
&theme::TEXT_MONO,
&theme::TEXT_MONO,
)?;
new_confirm_action_simple(
paragraphs.into_paragraphs(),
ConfirmActionMenu::new(None, false, None),
ConfirmActionStrings::new(title, None, None, hold.then_some(title)),
hold,
None,
)
.and_then(LayoutObj::new_root)
.map(Into::into)
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
extern "C" fn new_confirm_set_new_pin(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj { extern "C" fn new_confirm_set_new_pin(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()?;
@ -637,16 +611,6 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// and allows left swipe which does the same thing as the button.""" /// and allows left swipe which does the same thing as the button."""
Qstr::MP_QSTR_confirm_address => obj_fn_kw!(0, new_confirm_address).as_obj(), Qstr::MP_QSTR_confirm_address => obj_fn_kw!(0, new_confirm_address).as_obj(),
/// def confirm_properties(
/// *,
/// title: str,
/// items: list[tuple[str | None, str | bytes | None, bool]],
/// hold: bool = False,
/// ) -> LayoutObj[UiResult]:
/// """Confirm list of key-value pairs. The third component in the tuple should be True if
/// the value is to be rendered as binary with monospace font, False otherwise."""
Qstr::MP_QSTR_confirm_properties => obj_fn_kw!(0, new_confirm_properties).as_obj(),
// TODO: supply more arguments for Wipe code setting when figma done // TODO: supply more arguments for Wipe code setting when figma done
/// def flow_confirm_set_new_pin( /// def flow_confirm_set_new_pin(
/// *, /// *,

View File

@ -22,7 +22,7 @@ use crate::{
geometry::{self, Direction}, geometry::{self, Direction},
layout::{ layout::{
obj::{LayoutMaybeTrace, LayoutObj, RootComponent}, obj::{LayoutMaybeTrace, LayoutObj, RootComponent},
util::RecoveryType, util::{PropsList, RecoveryType},
}, },
ui_features_fw::UIFeaturesFirmware, ui_features_fw::UIFeaturesFirmware,
}, },
@ -274,6 +274,28 @@ impl UIFeaturesFirmware for ModelMercuryFeatures {
Ok(flow) Ok(flow)
} }
fn confirm_properties(
title: TString<'static>,
items: Obj,
hold: bool,
) -> Result<impl LayoutMaybeTrace, Error> {
let paragraphs = PropsList::new(
items,
&theme::TEXT_NORMAL,
&theme::TEXT_MONO,
&theme::TEXT_MONO,
)?;
let flow = flow::new_confirm_action_simple(
paragraphs.into_paragraphs(),
ConfirmActionMenu::new(None, false, None),
ConfirmActionStrings::new(title, None, None, hold.then_some(title)),
hold,
None,
)?;
Ok(flow)
}
fn confirm_value( fn confirm_value(
title: TString<'static>, title: TString<'static>,
value: Obj, value: Obj,

View File

@ -270,59 +270,6 @@ fn content_in_button_page<T: Component + Paginate + MaybeTrace + 'static>(
Ok(obj.into()) Ok(obj.into())
} }
extern "C" fn new_confirm_properties(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let hold: bool = kwargs.get_or(Qstr::MP_QSTR_hold, false)?;
let items: Obj = kwargs.get(Qstr::MP_QSTR_items)?;
let mut paragraphs = ParagraphVecLong::new();
for para in IterBuf::new().try_iterate(items)? {
let [key, value, is_data]: [Obj; 3] = util::iter_into_array(para)?;
let key = key.try_into_option::<TString>()?;
let value = value.try_into_option::<TString>()?;
let is_data: bool = is_data.try_into()?;
if let Some(key) = key {
if value.is_some() {
// Decreasing the margin between key and value (default is 5 px, we use 2 px)
// (this enables 4 lines - 2 key:value pairs - on the same screen)
paragraphs.add(
Paragraph::new(&theme::TEXT_BOLD, key)
.no_break()
.with_bottom_padding(2),
);
} else {
paragraphs.add(Paragraph::new(&theme::TEXT_BOLD, key));
}
}
if let Some(value) = value {
let style = if is_data {
&theme::TEXT_MONO_DATA
} else {
&theme::TEXT_MONO
};
paragraphs.add(Paragraph::new(style, value));
}
}
let button_text = if hold {
TR::buttons__hold_to_confirm.into()
} else {
TR::buttons__confirm.into()
};
content_in_button_page(
title,
paragraphs.into_paragraphs(),
button_text,
Some("".into()),
hold,
)
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
extern "C" fn new_confirm_backup(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj { extern "C" fn new_confirm_backup(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 get_page = move |page_index| match page_index { let get_page = move |page_index| match page_index {
@ -746,18 +693,6 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// """Confirm address.""" /// """Confirm address."""
Qstr::MP_QSTR_confirm_address => obj_fn_kw!(0, new_confirm_address).as_obj(), Qstr::MP_QSTR_confirm_address => obj_fn_kw!(0, new_confirm_address).as_obj(),
/// def confirm_properties(
/// *,
/// title: str,
/// items: list[tuple[str | None, str | bytes | None, bool]],
/// hold: bool = False,
/// ) -> LayoutObj[UiResult]:
/// """Confirm list of key-value pairs. The third component in the tuple should be True if
/// the value is to be rendered as binary with monospace font, False otherwise.
/// This only concerns the text style, you need to decode the value to UTF-8 in python."""
Qstr::MP_QSTR_confirm_properties => obj_fn_kw!(0, new_confirm_properties).as_obj(),
/// def confirm_backup() -> LayoutObj[UiResult]: /// def confirm_backup() -> LayoutObj[UiResult]:
/// """Strongly recommend user to do backup.""" /// """Strongly recommend user to do backup."""
Qstr::MP_QSTR_confirm_backup => obj_fn_kw!(0, new_confirm_backup).as_obj(), Qstr::MP_QSTR_confirm_backup => obj_fn_kw!(0, new_confirm_backup).as_obj(),

View File

@ -311,6 +311,56 @@ impl UIFeaturesFirmware for ModelTRFeatures {
) )
} }
fn confirm_properties(
title: TString<'static>,
items: Obj,
hold: bool,
) -> Result<impl LayoutMaybeTrace, Error> {
let mut paragraphs = ParagraphVecLong::new();
for para in IterBuf::new().try_iterate(items)? {
let [key, value, is_data]: [Obj; 3] = util::iter_into_array(para)?;
let key = key.try_into_option::<TString>()?;
let value = value.try_into_option::<TString>()?;
let is_data: bool = is_data.try_into()?;
if let Some(key) = key {
if value.is_some() {
// Decreasing the margin between key and value (default is 5 px, we use 2 px)
// (this enables 4 lines - 2 key:value pairs - on the same screen)
paragraphs.add(
Paragraph::new(&theme::TEXT_BOLD, key)
.no_break()
.with_bottom_padding(2),
);
} else {
paragraphs.add(Paragraph::new(&theme::TEXT_BOLD, key));
}
}
if let Some(value) = value {
let style = if is_data {
&theme::TEXT_MONO_DATA
} else {
&theme::TEXT_MONO
};
paragraphs.add(Paragraph::new(style, value));
}
}
let button_text = if hold {
TR::buttons__hold_to_confirm.into()
} else {
TR::buttons__confirm.into()
};
content_in_button_page(
title,
paragraphs.into_paragraphs(),
button_text,
Some("".into()),
hold,
)
}
fn confirm_reset_device(recovery: bool) -> Result<impl LayoutMaybeTrace, Error> { fn confirm_reset_device(recovery: bool) -> Result<impl LayoutMaybeTrace, Error> {
let (title, button) = if recovery { let (title, button) = if recovery {
( (

View File

@ -394,30 +394,6 @@ extern "C" fn new_confirm_address(n_args: usize, args: *const Obj, kwargs: *mut
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_properties(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let hold: bool = kwargs.get_or(Qstr::MP_QSTR_hold, false)?;
let items: Obj = kwargs.get(Qstr::MP_QSTR_items)?;
let paragraphs = PropsList::new(
items,
&theme::TEXT_NORMAL,
&theme::TEXT_MONO,
&theme::TEXT_MONO,
)?;
let page = if hold {
ButtonPage::new(paragraphs.into_paragraphs(), theme::BG).with_hold()?
} else {
ButtonPage::new(paragraphs.into_paragraphs(), theme::BG)
.with_cancel_confirm(None, Some(TR::buttons__confirm.into()))
};
let obj = LayoutObj::new(Frame::left_aligned(theme::label_title(), title, page))?;
Ok(obj.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
extern "C" fn new_show_address_details(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj { extern "C" fn new_show_address_details(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 qr_title: TString<'static> = kwargs.get(Qstr::MP_QSTR_qr_title)?.try_into()?; let qr_title: TString<'static> = kwargs.get(Qstr::MP_QSTR_qr_title)?.try_into()?;
@ -544,16 +520,6 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// and allows left swipe which does the same thing as the button.""" /// and allows left swipe which does the same thing as the button."""
Qstr::MP_QSTR_confirm_address => obj_fn_kw!(0, new_confirm_address).as_obj(), Qstr::MP_QSTR_confirm_address => obj_fn_kw!(0, new_confirm_address).as_obj(),
/// def confirm_properties(
/// *,
/// title: str,
/// items: list[tuple[str | None, str | bytes | None, bool]],
/// hold: bool = False,
/// ) -> LayoutObj[UiResult]:
/// """Confirm list of key-value pairs. The third component in the tuple should be True if
/// the value is to be rendered as binary with monospace font, False otherwise."""
Qstr::MP_QSTR_confirm_properties => obj_fn_kw!(0, new_confirm_properties).as_obj(),
/// def show_address_details( /// def show_address_details(
/// *, /// *,
/// qr_title: str, /// qr_title: str,

View File

@ -22,7 +22,7 @@ use crate::{
geometry, geometry,
layout::{ layout::{
obj::{LayoutMaybeTrace, LayoutObj, RootComponent}, obj::{LayoutMaybeTrace, LayoutObj, RootComponent},
util::{ConfirmBlob, RecoveryType}, util::{ConfirmBlob, PropsList, RecoveryType},
}, },
ui_features_fw::UIFeaturesFirmware, ui_features_fw::UIFeaturesFirmware,
}, },
@ -270,6 +270,27 @@ impl UIFeaturesFirmware for ModelTTFeatures {
Ok(layout) Ok(layout)
} }
fn confirm_properties(
title: TString<'static>,
items: Obj,
hold: bool,
) -> Result<impl LayoutMaybeTrace, Error> {
let paragraphs = PropsList::new(
items,
&theme::TEXT_NORMAL,
&theme::TEXT_MONO,
&theme::TEXT_MONO,
)?;
let page = if hold {
ButtonPage::new(paragraphs.into_paragraphs(), theme::BG).with_hold()?
} else {
ButtonPage::new(paragraphs.into_paragraphs(), theme::BG)
.with_cancel_confirm(None, Some(TR::buttons__confirm.into()))
};
let layout = RootComponent::new(Frame::left_aligned(theme::label_title(), title, page));
Ok(layout)
}
fn confirm_reset_device(recovery: bool) -> Result<impl LayoutMaybeTrace, Error> { fn confirm_reset_device(recovery: bool) -> Result<impl LayoutMaybeTrace, Error> {
let (title, button) = if recovery { let (title, button) = if recovery {
( (

View File

@ -79,6 +79,12 @@ pub trait UIFeaturesFirmware {
amount_new: TString<'static>, amount_new: TString<'static>,
) -> Result<impl LayoutMaybeTrace, Error>; ) -> Result<impl LayoutMaybeTrace, Error>;
fn confirm_properties(
title: TString<'static>,
items: Obj, // TODO: replace Obj`
hold: bool,
) -> Result<impl LayoutMaybeTrace, Error>;
fn confirm_reset_device(recovery: bool) -> Result<impl LayoutMaybeTrace, Error>; fn confirm_reset_device(recovery: bool) -> Result<impl LayoutMaybeTrace, Error>;
fn confirm_value( fn confirm_value(

View File

@ -28,17 +28,6 @@ def confirm_address(
and allows left swipe which does the same thing as the button.""" and allows left swipe which does the same thing as the button."""
# rust/src/ui/model_mercury/layout.rs
def confirm_properties(
*,
title: str,
items: list[tuple[str | None, str | bytes | None, bool]],
hold: bool = False,
) -> LayoutObj[UiResult]:
"""Confirm list of key-value pairs. The third component in the tuple should be True if
the value is to be rendered as binary with monospace font, False otherwise."""
# rust/src/ui/model_mercury/layout.rs # rust/src/ui/model_mercury/layout.rs
def flow_confirm_set_new_pin( def flow_confirm_set_new_pin(
*, *,
@ -161,18 +150,6 @@ def confirm_address(
"""Confirm address.""" """Confirm address."""
# rust/src/ui/model_tr/layout.rs
def confirm_properties(
*,
title: str,
items: list[tuple[str | None, str | bytes | None, bool]],
hold: bool = False,
) -> LayoutObj[UiResult]:
"""Confirm list of key-value pairs. The third component in the tuple should be True if
the value is to be rendered as binary with monospace font, False otherwise.
This only concerns the text style, you need to decode the value to UTF-8 in python."""
# rust/src/ui/model_tr/layout.rs # rust/src/ui/model_tr/layout.rs
def confirm_backup() -> LayoutObj[UiResult]: def confirm_backup() -> LayoutObj[UiResult]:
"""Strongly recommend user to do backup.""" """Strongly recommend user to do backup."""
@ -294,17 +271,6 @@ def confirm_address(
and allows left swipe which does the same thing as the button.""" and allows left swipe which does the same thing as the button."""
# rust/src/ui/model_tt/layout.rs
def confirm_properties(
*,
title: str,
items: list[tuple[str | None, str | bytes | None, bool]],
hold: bool = False,
) -> LayoutObj[UiResult]:
"""Confirm list of key-value pairs. The third component in the tuple should be True if
the value is to be rendered as binary with monospace font, False otherwise."""
# rust/src/ui/model_tt/layout.rs # rust/src/ui/model_tt/layout.rs
def show_address_details( def show_address_details(
*, *,

View File

@ -179,6 +179,17 @@ def confirm_modify_output(
"""Decrease or increase output amount.""" """Decrease or increase output amount."""
# rust/src/ui/api/firmware_upy.rs
def confirm_properties(
*,
title: str,
items: list[tuple[str | None, str | bytes | None, bool]],
hold: bool = False,
) -> LayoutObj[UiResult]:
"""Confirm list of key-value pairs. The third component in the tuple should be True if
the value is to be rendered as binary with monospace font, False otherwise."""
# rust/src/ui/api/firmware_upy.rs # rust/src/ui/api/firmware_upy.rs
def confirm_reset_device(recovery: bool) -> LayoutObj[UiResult]: def confirm_reset_device(recovery: bool) -> LayoutObj[UiResult]:
"""Confirm TOS before creating wallet creation or wallet recovery.""" """Confirm TOS before creating wallet creation or wallet recovery."""

View File

@ -636,7 +636,7 @@ def confirm_properties(
items = [(prop[0], prop[1], isinstance(prop[1], bytes)) for prop in props] items = [(prop[0], prop[1], isinstance(prop[1], bytes)) for prop in props]
return raise_if_not_confirmed( return raise_if_not_confirmed(
trezorui2.confirm_properties( trezorui_api.confirm_properties(
title=title, title=title,
items=items, items=items,
hold=hold, hold=hold,

View File

@ -684,7 +684,7 @@ def confirm_properties(
return (key, value, bool(is_data)) return (key, value, bool(is_data))
return raise_if_not_confirmed( return raise_if_not_confirmed(
trezorui2.confirm_properties( trezorui_api.confirm_properties(
title=title, title=title,
items=map(handle_bytes, props), # type: ignore [cannot be assigned to parameter "items"] items=map(handle_bytes, props), # type: ignore [cannot be assigned to parameter "items"]
hold=hold, hold=hold,

View File

@ -693,7 +693,7 @@ def confirm_properties(
items = [(prop[0], prop[1], isinstance(prop[1], bytes)) for prop in props] items = [(prop[0], prop[1], isinstance(prop[1], bytes)) for prop in props]
return raise_if_not_confirmed( return raise_if_not_confirmed(
trezorui2.confirm_properties( trezorui_api.confirm_properties(
title=title, title=title,
items=items, items=items,
hold=hold, hold=hold,