1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-22 23:48:12 +00:00

refactor(core): move confirm_blob

- model_t `ConfirmBlobParams` copied for now and the return type of
`into_layout` changed to `Result<Gc<LayoutObj>>`
This commit is contained in:
obrusvit 2024-11-21 12:52:04 +01:00
parent 04f6d779e2
commit 8d08341adc
14 changed files with 354 additions and 292 deletions

View File

@ -280,6 +280,7 @@ static void _librust_qstrs(void) {
MP_QSTR_icon_name; MP_QSTR_icon_name;
MP_QSTR_image; MP_QSTR_image;
MP_QSTR_indeterminate; MP_QSTR_indeterminate;
MP_QSTR_info;
MP_QSTR_info_button; MP_QSTR_info_button;
MP_QSTR_init; MP_QSTR_init;
MP_QSTR_inputs__back; MP_QSTR_inputs__back;

View File

@ -85,6 +85,65 @@ extern "C" fn new_confirm_action(n_args: usize, args: *const Obj, kwargs: *mut M
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_blob(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 data: Obj = kwargs.get(Qstr::MP_QSTR_data)?;
let description: Option<TString> = kwargs
.get(Qstr::MP_QSTR_description)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let text_mono: bool = kwargs.get_or(Qstr::MP_QSTR_text_mono, true)?;
let extra: Option<TString> = kwargs
.get(Qstr::MP_QSTR_extra)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let subtitle: Option<TString> = kwargs
.get(Qstr::MP_QSTR_subtitle)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let verb: Option<TString> = kwargs
.get(Qstr::MP_QSTR_verb)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let verb_cancel: Option<TString> = kwargs
.get(Qstr::MP_QSTR_verb_cancel)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let verb_info: Option<TString> = kwargs
.get(Qstr::MP_QSTR_verb_info)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let info: bool = kwargs.get_or(Qstr::MP_QSTR_info, false)?; // FIXME: mercury has true
let hold: bool = kwargs.get_or(Qstr::MP_QSTR_hold, false)?;
let chunkify: bool = kwargs.get_or(Qstr::MP_QSTR_chunkify, false)?;
let prompt_screen: bool = kwargs.get_or(Qstr::MP_QSTR_prompt_screen, true)?;
let page_limit: Option<usize> = kwargs
.get(Qstr::MP_QSTR_page_limit)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let layout_obj = ModelUI::confirm_blob(
title,
data,
description,
text_mono,
extra,
subtitle,
verb,
verb_cancel,
verb_info,
info,
hold,
chunkify,
prompt_screen,
page_limit,
)?;
Ok(layout_obj.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
extern "C" fn new_confirm_coinjoin(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj { extern "C" fn new_confirm_coinjoin(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 max_rounds: TString = kwargs.get(Qstr::MP_QSTR_max_rounds)?.try_into()?; let max_rounds: TString = kwargs.get(Qstr::MP_QSTR_max_rounds)?.try_into()?;
@ -763,6 +822,26 @@ pub static mp_module_trezorui_api: Module = obj_module! {
/// """Confirm action.""" /// """Confirm action."""
Qstr::MP_QSTR_confirm_action => obj_fn_kw!(0, new_confirm_action).as_obj(), Qstr::MP_QSTR_confirm_action => obj_fn_kw!(0, new_confirm_action).as_obj(),
/// def confirm_blob(
/// *,
/// title: str,
/// data: str | bytes,
/// description: str | None,
/// text_mono: bool = True,
/// extra: str | None = None,
/// subtitle: str | None = None,
/// verb: str | None = None,
/// verb_cancel: str | None = None,
/// verb_info: str | None = None,
/// info: bool = True,
/// hold: bool = False,
/// chunkify: bool = False,
/// prompt_screen: bool = False,
/// page_limit: int | None = None,
/// ) -> LayoutObj[UiResult]:
/// """Confirm byte sequence data."""
Qstr::MP_QSTR_confirm_blob => obj_fn_kw!(0, new_confirm_blob).as_obj(),
/// def confirm_coinjoin( /// def confirm_coinjoin(
/// *, /// *,
/// max_rounds: str, /// max_rounds: str,

View File

@ -257,73 +257,6 @@ extern "C" fn new_confirm_emphasized(n_args: usize, args: *const Obj, kwargs: *m
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_blob(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 data: Obj = kwargs.get(Qstr::MP_QSTR_data)?;
let description: Option<TString> = kwargs
.get(Qstr::MP_QSTR_description)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let text_mono: bool = kwargs.get_or(Qstr::MP_QSTR_text_mono, true)?;
let extra: Option<TString> = kwargs
.get(Qstr::MP_QSTR_extra)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let subtitle: Option<TString> = kwargs
.get(Qstr::MP_QSTR_subtitle)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let verb: Option<TString> = kwargs
.get(Qstr::MP_QSTR_verb)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let verb_cancel: Option<TString> = kwargs
.get(Qstr::MP_QSTR_verb_cancel)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let verb_info: Option<TString> = kwargs
.get(Qstr::MP_QSTR_verb_info)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let info: bool = kwargs.get_or(Qstr::MP_QSTR_info, true)?;
let hold: bool = kwargs.get_or(Qstr::MP_QSTR_hold, false)?;
let chunkify: bool = kwargs.get_or(Qstr::MP_QSTR_chunkify, false)?;
let prompt_screen: bool = kwargs.get_or(Qstr::MP_QSTR_prompt_screen, true)?;
let page_limit: Option<usize> = kwargs
.get(Qstr::MP_QSTR_page_limit)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let (description, description_font) = if page_limit == Some(1) {
(
Some(TR::instructions__view_all_data.into()),
&theme::TEXT_SUB_GREEN_LIME,
)
} else {
(description, &theme::TEXT_NORMAL)
};
ConfirmBlobParams::new(title, data, description)
.with_description_font(description_font)
.with_text_mono(text_mono)
.with_subtitle(subtitle)
.with_verb(verb)
.with_verb_cancel(verb_cancel)
.with_verb_info(verb_info)
.with_extra(extra)
.with_info_button(info)
.with_chunkify(chunkify)
.with_page_limit(page_limit)
.with_prompt(prompt_screen)
.with_hold(hold)
.into_flow()
.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_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()?;
@ -728,26 +661,6 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// the first component is a bool indicating whether this part is emphasized.""" /// the first component is a bool indicating whether this part is emphasized."""
Qstr::MP_QSTR_confirm_emphasized => obj_fn_kw!(0, new_confirm_emphasized).as_obj(), Qstr::MP_QSTR_confirm_emphasized => obj_fn_kw!(0, new_confirm_emphasized).as_obj(),
/// def confirm_blob(
/// *,
/// title: str,
/// data: str | bytes,
/// description: str | None,
/// text_mono: bool = True,
/// extra: str | None = None,
/// subtitle: str | None = None,
/// verb: str | None = None,
/// verb_cancel: str | None = None,
/// verb_info: str | None = None,
/// info: bool = True,
/// hold: bool = False,
/// chunkify: bool = False,
/// prompt_screen: bool = False,
/// page_limit: int | None = None,
/// ) -> LayoutObj[UiResult]:
/// """Confirm byte sequence data."""
Qstr::MP_QSTR_confirm_blob => obj_fn_kw!(0, new_confirm_blob).as_obj(),
/// def confirm_address( /// def confirm_address(
/// *, /// *,
/// title: str, /// title: str,

View File

@ -35,7 +35,8 @@ use super::{
SwipeContent, SwipeUpScreen, VerticalMenu, SwipeContent, SwipeUpScreen, VerticalMenu,
}, },
flow::{ flow::{
self, confirm_with_info, new_confirm_action_simple, ConfirmActionMenu, ConfirmActionStrings, self, confirm_with_info, new_confirm_action_simple, ConfirmActionMenu,
ConfirmActionStrings, ConfirmBlobParams,
}, },
theme, ModelMercuryFeatures, theme, ModelMercuryFeatures,
}; };
@ -68,6 +69,49 @@ impl UIFeaturesFirmware for ModelMercuryFeatures {
Ok(flow) Ok(flow)
} }
fn confirm_blob(
title: TString<'static>,
data: Obj,
description: Option<TString<'static>>,
text_mono: bool,
extra: Option<TString<'static>>,
subtitle: Option<TString<'static>>,
verb: Option<TString<'static>>,
verb_cancel: Option<TString<'static>>,
verb_info: Option<TString<'static>>,
info: bool,
hold: bool,
chunkify: bool,
prompt_screen: bool,
page_limit: Option<usize>,
) -> Result<Gc<LayoutObj>, Error> {
let (description, description_font) = if page_limit == Some(1) {
(
Some(TR::instructions__view_all_data.into()),
&theme::TEXT_SUB_GREEN_LIME,
)
} else {
(description, &theme::TEXT_NORMAL)
};
ConfirmBlobParams::new(title, data, description)
.with_description_font(description_font)
.with_text_mono(text_mono)
.with_subtitle(subtitle)
.with_verb(verb)
.with_verb_cancel(verb_cancel)
.with_verb_info(verb_info)
.with_extra(extra)
.with_info_button(info)
.with_chunkify(chunkify)
.with_page_limit(page_limit)
.with_prompt(prompt_screen)
.with_hold(hold)
.into_flow()
.and_then(LayoutObj::new_root)
.map(Into::into)
}
fn confirm_homescreen( fn confirm_homescreen(
title: TString<'static>, title: TString<'static>,
image: BinaryData<'static>, image: BinaryData<'static>,

View File

@ -270,55 +270,6 @@ fn content_in_button_page<T: Component + Paginate + MaybeTrace + 'static>(
Ok(obj.into()) Ok(obj.into())
} }
extern "C" fn new_confirm_blob(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 data: Obj = kwargs.get(Qstr::MP_QSTR_data)?;
let description: Option<TString> =
kwargs.get(Qstr::MP_QSTR_description)?.try_into_option()?;
let extra: Option<TString> = kwargs
.get(Qstr::MP_QSTR_extra)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let verb: Option<TString> = kwargs
.get(Qstr::MP_QSTR_verb)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let verb_cancel: Option<TString> = kwargs
.get(Qstr::MP_QSTR_verb_cancel)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let hold: bool = kwargs.get_or(Qstr::MP_QSTR_hold, false)?;
let chunkify: bool = kwargs.get_or(Qstr::MP_QSTR_chunkify, false)?;
let style = if chunkify {
// Chunkifying the address into smaller pieces when requested
&theme::TEXT_MONO_ADDRESS_CHUNKS
} else {
&theme::TEXT_MONO_DATA
};
let paragraphs = ConfirmBlob {
description: description.unwrap_or("".into()),
extra: extra.unwrap_or("".into()),
data: data.try_into()?,
description_font: &theme::TEXT_BOLD,
extra_font: &theme::TEXT_NORMAL,
data_font: style,
}
.into_paragraphs();
content_in_button_page(
title,
paragraphs,
verb.unwrap_or(TR::buttons__confirm.into()),
verb_cancel,
hold,
)
};
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 { extern "C" fn new_confirm_properties(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()?;
@ -811,26 +762,6 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// ///
Qstr::MP_QSTR___name__ => Qstr::MP_QSTR_trezorui2.to_obj(), Qstr::MP_QSTR___name__ => Qstr::MP_QSTR_trezorui2.to_obj(),
/// def confirm_blob(
/// *,
/// title: str,
/// data: str | bytes,
/// description: str | None,
/// text_mono: bool = True,
/// extra: str | None = None,
/// subtitle: str | None = None,
/// verb: str = "CONFIRM",
/// verb_cancel: str | None = None,
/// verb_info: str | None = None,
/// info: bool = True,
/// hold: bool = False,
/// chunkify: bool = False,
/// prompt_screen: bool = False,
/// page_limit: int | None = None,
/// ) -> LayoutObj[UiResult]:
/// """Confirm byte sequence data."""
Qstr::MP_QSTR_confirm_blob => obj_fn_kw!(0, new_confirm_blob).as_obj(),
/// def confirm_address( /// def confirm_address(
/// *, /// *,
/// title: str, /// title: str,

View File

@ -23,7 +23,7 @@ use crate::{
geometry, geometry,
layout::{ layout::{
obj::{LayoutMaybeTrace, LayoutObj, RootComponent}, obj::{LayoutMaybeTrace, LayoutObj, RootComponent},
util::RecoveryType, util::{ConfirmBlob, RecoveryType},
}, },
model_tr::{ model_tr::{
component::{ButtonActions, ButtonLayout, Page}, component::{ButtonActions, ButtonLayout, Page},
@ -83,6 +83,49 @@ impl UIFeaturesFirmware for ModelTRFeatures {
) )
} }
fn confirm_blob(
title: TString<'static>,
data: Obj,
description: Option<TString<'static>>,
_text_mono: bool,
extra: Option<TString<'static>>,
_subtitle: Option<TString<'static>>,
verb: Option<TString<'static>>,
verb_cancel: Option<TString<'static>>,
_verb_info: Option<TString<'static>>,
_info: bool,
hold: bool,
chunkify: bool,
_prompt_screen: bool,
_page_limit: Option<usize>,
) -> Result<Gc<LayoutObj>, Error> {
let style = if chunkify {
// Chunkifying the address into smaller pieces when requested
&theme::TEXT_MONO_ADDRESS_CHUNKS
} else {
&theme::TEXT_MONO_DATA
};
let paragraphs = ConfirmBlob {
description: description.unwrap_or("".into()),
extra: extra.unwrap_or("".into()),
data: data.try_into()?,
description_font: &theme::TEXT_BOLD,
extra_font: &theme::TEXT_NORMAL,
data_font: style,
}
.into_paragraphs();
let layout = content_in_button_page(
title,
paragraphs,
verb.unwrap_or(TR::buttons__confirm.into()),
verb_cancel,
hold,
)?;
LayoutObj::new_root(layout)
}
fn confirm_homescreen( fn confirm_homescreen(
title: TString<'static>, title: TString<'static>,
image: BinaryData<'static>, image: BinaryData<'static>,

View File

@ -461,44 +461,6 @@ impl ConfirmBlobParams {
} }
} }
extern "C" fn new_confirm_blob(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 data: Obj = kwargs.get(Qstr::MP_QSTR_data)?;
let description: Option<TString> =
kwargs.get(Qstr::MP_QSTR_description)?.try_into_option()?;
let text_mono: bool = kwargs.get_or(Qstr::MP_QSTR_text_mono, true)?;
let extra: Option<TString> = kwargs
.get(Qstr::MP_QSTR_extra)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let verb: Option<TString> = kwargs
.get(Qstr::MP_QSTR_verb)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let verb_cancel: Option<TString> = kwargs
.get(Qstr::MP_QSTR_verb_cancel)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let info: bool = kwargs.get_or(Qstr::MP_QSTR_info, false)?;
let hold: bool = kwargs.get_or(Qstr::MP_QSTR_hold, false)?;
let chunkify: bool = kwargs.get_or(Qstr::MP_QSTR_chunkify, false)?;
let page_limit: Option<usize> = kwargs
.get(Qstr::MP_QSTR_page_limit)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
ConfirmBlobParams::new(title, data, description, verb, verb_cancel, hold)
.with_text_mono(text_mono)
.with_extra(extra)
.with_chunkify(chunkify)
.with_info_button(info)
.with_page_limit(page_limit)
.into_layout()
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
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()?;
@ -709,26 +671,6 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// the first component is a bool indicating whether this part is emphasized.""" /// the first component is a bool indicating whether this part is emphasized."""
Qstr::MP_QSTR_confirm_emphasized => obj_fn_kw!(0, new_confirm_emphasized).as_obj(), Qstr::MP_QSTR_confirm_emphasized => obj_fn_kw!(0, new_confirm_emphasized).as_obj(),
/// def confirm_blob(
/// *,
/// title: str,
/// data: str | bytes,
/// description: str | None,
/// text_mono: bool = True,
/// extra: str | None = None,
/// subtitle: str | None = None,
/// verb: str | None = None,
/// verb_cancel: str | None = None,
/// verb_info: str | None = None,
/// info: bool = True,
/// hold: bool = False,
/// chunkify: bool = False,
/// prompt_screen: bool = False,
/// page_limit: int | None = None,
/// ) -> LayoutObj[UiResult]:
/// """Confirm byte sequence data."""
Qstr::MP_QSTR_confirm_blob => obj_fn_kw!(0, new_confirm_blob).as_obj(),
/// def confirm_address( /// def confirm_address(
/// *, /// *,
/// title: str, /// title: str,

View File

@ -22,7 +22,7 @@ use crate::{
geometry, geometry,
layout::{ layout::{
obj::{LayoutMaybeTrace, LayoutObj, RootComponent}, obj::{LayoutMaybeTrace, LayoutObj, RootComponent},
util::RecoveryType, util::{ConfirmBlob, RecoveryType},
}, },
ui_features_fw::UIFeaturesFirmware, ui_features_fw::UIFeaturesFirmware,
}, },
@ -80,6 +80,31 @@ impl UIFeaturesFirmware for ModelTTFeatures {
Ok(layout) Ok(layout)
} }
fn confirm_blob(
title: TString<'static>,
data: Obj,
description: Option<TString<'static>>,
text_mono: bool,
extra: Option<TString<'static>>,
_subtitle: Option<TString<'static>>,
verb: Option<TString<'static>>,
verb_cancel: Option<TString<'static>>,
_verb_info: Option<TString<'static>>,
info: bool,
hold: bool,
chunkify: bool,
_prompt_screen: bool,
page_limit: Option<usize>,
) -> Result<Gc<LayoutObj>, Error> {
ConfirmBlobParams::new(title, data, description, verb, verb_cancel, hold)
.with_text_mono(text_mono)
.with_extra(extra)
.with_chunkify(chunkify)
.with_info_button(info)
.with_page_limit(page_limit)
.into_layout()
}
fn confirm_homescreen( fn confirm_homescreen(
title: TString<'static>, title: TString<'static>,
mut image: BinaryData<'static>, mut image: BinaryData<'static>,
@ -923,3 +948,112 @@ fn new_show_modal(
Ok(obj) Ok(obj)
} }
// TODO: move to some util.rs?
struct ConfirmBlobParams {
title: TString<'static>,
subtitle: Option<TString<'static>>,
data: Obj,
description: Option<TString<'static>>,
extra: Option<TString<'static>>,
verb: Option<TString<'static>>,
verb_cancel: Option<TString<'static>>,
info_button: bool,
hold: bool,
chunkify: bool,
text_mono: bool,
page_limit: Option<usize>,
}
impl ConfirmBlobParams {
fn new(
title: TString<'static>,
data: Obj,
description: Option<TString<'static>>,
verb: Option<TString<'static>>,
verb_cancel: Option<TString<'static>>,
hold: bool,
) -> Self {
Self {
title,
subtitle: None,
data,
description,
extra: None,
verb,
verb_cancel,
info_button: false,
hold,
chunkify: false,
text_mono: true,
page_limit: None,
}
}
fn with_extra(mut self, extra: Option<TString<'static>>) -> Self {
self.extra = extra;
self
}
fn with_subtitle(mut self, subtitle: Option<TString<'static>>) -> Self {
self.subtitle = subtitle;
self
}
fn with_info_button(mut self, info_button: bool) -> Self {
self.info_button = info_button;
self
}
fn with_chunkify(mut self, chunkify: bool) -> Self {
self.chunkify = chunkify;
self
}
fn with_text_mono(mut self, text_mono: bool) -> Self {
self.text_mono = text_mono;
self
}
fn with_page_limit(mut self, page_limit: Option<usize>) -> Self {
self.page_limit = page_limit;
self
}
fn into_layout(self) -> Result<Gc<LayoutObj>, Error> {
let paragraphs = ConfirmBlob {
description: self.description.unwrap_or("".into()),
extra: self.extra.unwrap_or("".into()),
data: self.data.try_into()?,
description_font: &theme::TEXT_NORMAL,
extra_font: &theme::TEXT_DEMIBOLD,
data_font: if self.chunkify {
let data: TString = self.data.try_into()?;
theme::get_chunkified_text_style(data.len())
} else if self.text_mono {
&theme::TEXT_MONO
} else {
&theme::TEXT_NORMAL
},
}
.into_paragraphs();
let mut page = ButtonPage::new(paragraphs, theme::BG);
if let Some(verb) = self.verb {
page = page.with_cancel_confirm(self.verb_cancel, Some(verb))
}
if self.hold {
page = page.with_hold()?
}
page = page.with_page_limit(self.page_limit);
let mut frame = Frame::left_aligned(theme::label_title(), self.title, page);
if let Some(subtitle) = self.subtitle {
frame = frame.with_subtitle(theme::label_subtitle(), subtitle);
}
if self.info_button {
frame = frame.with_info_button();
}
LayoutObj::new(frame)
}
}

View File

@ -26,6 +26,23 @@ pub trait UIFeaturesFirmware {
prompt_title: Option<TString<'static>>, prompt_title: Option<TString<'static>>,
) -> Result<impl LayoutMaybeTrace, Error>; ) -> Result<impl LayoutMaybeTrace, Error>;
fn confirm_blob(
title: TString<'static>,
data: Obj, // TODO: replace Obj
description: Option<TString<'static>>,
text_mono: bool,
extra: Option<TString<'static>>,
subtitle: Option<TString<'static>>,
verb: Option<TString<'static>>,
verb_cancel: Option<TString<'static>>,
verb_info: Option<TString<'static>>,
info: bool,
hold: bool,
chunkify: bool,
prompt_screen: bool,
page_limit: Option<usize>,
) -> Result<Gc<LayoutObj>, Error>; // TODO: return LayoutMaybeTrace
fn confirm_homescreen( fn confirm_homescreen(
title: TString<'static>, title: TString<'static>,
image: BinaryData<'static>, image: BinaryData<'static>,

View File

@ -14,27 +14,6 @@ def confirm_emphasized(
the first component is a bool indicating whether this part is emphasized.""" the first component is a bool indicating whether this part is emphasized."""
# rust/src/ui/model_mercury/layout.rs
def confirm_blob(
*,
title: str,
data: str | bytes,
description: str | None,
text_mono: bool = True,
extra: str | None = None,
subtitle: str | None = None,
verb: str | None = None,
verb_cancel: str | None = None,
verb_info: str | None = None,
info: bool = True,
hold: bool = False,
chunkify: bool = False,
prompt_screen: bool = False,
page_limit: int | None = None,
) -> LayoutObj[UiResult]:
"""Confirm byte sequence data."""
# rust/src/ui/model_mercury/layout.rs # rust/src/ui/model_mercury/layout.rs
def confirm_address( def confirm_address(
*, *,
@ -186,27 +165,6 @@ from trezor import utils
from trezorui_api import * from trezorui_api import *
# rust/src/ui/model_tr/layout.rs
def confirm_blob(
*,
title: str,
data: str | bytes,
description: str | None,
text_mono: bool = True,
extra: str | None = None,
subtitle: str | None = None,
verb: str = "CONFIRM",
verb_cancel: str | None = None,
verb_info: str | None = None,
info: bool = True,
hold: bool = False,
chunkify: bool = False,
prompt_screen: bool = False,
page_limit: int | None = None,
) -> LayoutObj[UiResult]:
"""Confirm byte sequence data."""
# rust/src/ui/model_tr/layout.rs # rust/src/ui/model_tr/layout.rs
def confirm_address( def confirm_address(
*, *,
@ -351,27 +309,6 @@ def confirm_emphasized(
the first component is a bool indicating whether this part is emphasized.""" the first component is a bool indicating whether this part is emphasized."""
# rust/src/ui/model_tt/layout.rs
def confirm_blob(
*,
title: str,
data: str | bytes,
description: str | None,
text_mono: bool = True,
extra: str | None = None,
subtitle: str | None = None,
verb: str | None = None,
verb_cancel: str | None = None,
verb_info: str | None = None,
info: bool = True,
hold: bool = False,
chunkify: bool = False,
prompt_screen: bool = False,
page_limit: int | None = None,
) -> LayoutObj[UiResult]:
"""Confirm byte sequence data."""
# rust/src/ui/model_tt/layout.rs # rust/src/ui/model_tt/layout.rs
def confirm_address( def confirm_address(
*, *,

View File

@ -96,6 +96,27 @@ def confirm_action(
"""Confirm action.""" """Confirm action."""
# rust/src/ui/api/firmware_upy.rs
def confirm_blob(
*,
title: str,
data: str | bytes,
description: str | None,
text_mono: bool = True,
extra: str | None = None,
subtitle: str | None = None,
verb: str | None = None,
verb_cancel: str | None = None,
verb_info: str | None = None,
info: bool = True,
hold: bool = False,
chunkify: bool = False,
prompt_screen: bool = False,
page_limit: int | None = None,
) -> LayoutObj[UiResult]:
"""Confirm byte sequence data."""
# rust/src/ui/api/firmware_upy.rs # rust/src/ui/api/firmware_upy.rs
def confirm_coinjoin( def confirm_coinjoin(
*, *,

View File

@ -467,7 +467,7 @@ def confirm_blob(
prompt_screen: bool = True, prompt_screen: bool = True,
) -> Awaitable[None]: ) -> Awaitable[None]:
if ask_pagination: if ask_pagination:
main_layout = trezorui2.confirm_blob( main_layout = trezorui_api.confirm_blob(
title=title, title=title,
data=data, data=data,
description=None, description=None,
@ -481,7 +481,7 @@ def confirm_blob(
prompt_screen=False, prompt_screen=False,
page_limit=1, page_limit=1,
) )
info_layout = trezorui2.confirm_blob( info_layout = trezorui_api.confirm_blob(
title=title, title=title,
data=data, data=data,
description=None, description=None,
@ -502,7 +502,7 @@ def confirm_blob(
info_layout_can_confirm=True, info_layout_can_confirm=True,
) )
else: else:
layout = trezorui2.confirm_blob( layout = trezorui_api.confirm_blob(
title=title, title=title,
data=data, data=data,
description=description, description=description,
@ -909,7 +909,7 @@ async def confirm_modify_output(
amount_change: str, amount_change: str,
amount_new: str, amount_new: str,
) -> None: ) -> None:
address_layout = trezorui2.confirm_blob( address_layout = trezorui_api.confirm_blob(
title=TR.modify_amount__title, title=TR.modify_amount__title,
data=address, data=address,
verb=TR.buttons__continue, verb=TR.buttons__continue,
@ -1031,7 +1031,7 @@ async def confirm_signverify(
horizontal=True, horizontal=True,
) )
message_layout = trezorui2.confirm_blob( message_layout = trezorui_api.confirm_blob(
title=TR.sign_message__confirm_message, title=TR.sign_message__confirm_message,
description=None, description=None,
data=message, data=message,

View File

@ -561,7 +561,7 @@ def confirm_blob(
prompt_screen: bool = True, prompt_screen: bool = True,
) -> Awaitable[None]: ) -> Awaitable[None]:
verb = verb or TR.buttons__confirm # def_arg verb = verb or TR.buttons__confirm # def_arg
layout = trezorui2.confirm_blob( layout = trezorui_api.confirm_blob(
title=title, title=title,
description=description, description=description,
data=data, data=data,
@ -748,7 +748,7 @@ async def confirm_value(
elif result is INFO: elif result is INFO:
info_title, info_value = info_items_list[0] info_title, info_value = info_items_list[0]
await interact( await interact(
trezorui2.confirm_blob( trezorui_api.confirm_blob(
title=info_title, title=info_title,
data=info_value, data=info_value,
description=description, description=description,
@ -993,7 +993,7 @@ async def confirm_modify_output(
amount_change: str, amount_change: str,
amount_new: str, amount_new: str,
) -> None: ) -> None:
address_layout = trezorui2.confirm_blob( address_layout = trezorui_api.confirm_blob(
title=TR.modify_amount__title, title=TR.modify_amount__title,
data=address, data=address,
verb=TR.buttons__continue, verb=TR.buttons__continue,
@ -1095,7 +1095,7 @@ async def confirm_signverify(
) )
try: try:
await raise_if_not_confirmed( await raise_if_not_confirmed(
trezorui2.confirm_blob( trezorui_api.confirm_blob(
title=TR.sign_message__confirm_message, title=TR.sign_message__confirm_message,
description=None, description=None,
data=message, data=message,

View File

@ -560,7 +560,7 @@ def confirm_blob(
prompt_screen: bool = True, prompt_screen: bool = True,
) -> Awaitable[None]: ) -> Awaitable[None]:
verb = verb or TR.buttons__confirm # def_arg verb = verb or TR.buttons__confirm # def_arg
layout = trezorui2.confirm_blob( layout = trezorui_api.confirm_blob(
title=title, title=title,
description=description, description=description,
text_mono=text_mono, text_mono=text_mono,
@ -957,7 +957,7 @@ async def confirm_modify_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(
trezorui2.confirm_blob( trezorui_api.confirm_blob(
title="MODIFY AMOUNT", title="MODIFY AMOUNT",
data=address, data=address,
verb="CONTINUE", verb="CONTINUE",
@ -1076,7 +1076,7 @@ async def confirm_signverify(
horizontal=True, horizontal=True,
) )
message_layout = trezorui2.confirm_blob( message_layout = trezorui_api.confirm_blob(
title=TR.sign_message__confirm_message, title=TR.sign_message__confirm_message,
description=None, description=None,
data=message, data=message,