1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-02-05 04:10:58 +00:00

refactor(core): merge confirm_blob and confirm_value

[no changelog]
This commit is contained in:
Ioan Bizău 2025-01-08 12:57:41 +01:00 committed by Ioan Bizău
parent 96bc9db9e0
commit e99beaf486
16 changed files with 208 additions and 387 deletions

View File

@ -187,8 +187,6 @@ static void _librust_qstrs(void) {
MP_QSTR_coinjoin_authorized; MP_QSTR_coinjoin_authorized;
MP_QSTR_confirm_action; MP_QSTR_confirm_action;
MP_QSTR_confirm_address; MP_QSTR_confirm_address;
MP_QSTR_confirm_blob;
MP_QSTR_confirm_blob_intro;
MP_QSTR_confirm_coinjoin; MP_QSTR_confirm_coinjoin;
MP_QSTR_confirm_emphasized; MP_QSTR_confirm_emphasized;
MP_QSTR_confirm_fido; MP_QSTR_confirm_fido;
@ -206,12 +204,12 @@ static void _librust_qstrs(void) {
MP_QSTR_confirm_total__title_fee; MP_QSTR_confirm_total__title_fee;
MP_QSTR_confirm_total__title_sending_from; MP_QSTR_confirm_total__title_sending_from;
MP_QSTR_confirm_value; MP_QSTR_confirm_value;
MP_QSTR_confirm_value_intro;
MP_QSTR_confirm_with_info; MP_QSTR_confirm_with_info;
MP_QSTR_continue_recovery_homepage; MP_QSTR_continue_recovery_homepage;
MP_QSTR_count; MP_QSTR_count;
MP_QSTR_current; MP_QSTR_current;
MP_QSTR_danger; MP_QSTR_danger;
MP_QSTR_data;
MP_QSTR_data_hash; MP_QSTR_data_hash;
MP_QSTR_data_len; MP_QSTR_data_len;
MP_QSTR_debug__loading_seed; MP_QSTR_debug__loading_seed;
@ -299,6 +297,7 @@ static void _librust_qstrs(void) {
MP_QSTR_instructions__tap_to_confirm; MP_QSTR_instructions__tap_to_confirm;
MP_QSTR_instructions__tap_to_start; MP_QSTR_instructions__tap_to_start;
MP_QSTR_instructions__view_all_data; MP_QSTR_instructions__view_all_data;
MP_QSTR_is_data;
MP_QSTR_is_type_of; MP_QSTR_is_type_of;
MP_QSTR_items; MP_QSTR_items;
MP_QSTR_joint__title; MP_QSTR_joint__title;
@ -725,7 +724,6 @@ static void _librust_qstrs(void) {
MP_QSTR_value; MP_QSTR_value;
MP_QSTR_verb; MP_QSTR_verb;
MP_QSTR_verb_cancel; MP_QSTR_verb_cancel;
MP_QSTR_verb_info;
MP_QSTR_verify; MP_QSTR_verify;
MP_QSTR_version; MP_QSTR_version;
MP_QSTR_wipe__info; MP_QSTR_wipe__info;

View File

@ -108,15 +108,15 @@ 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_blob(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj { extern "C" fn new_confirm_value(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 value: Obj = kwargs.get(Qstr::MP_QSTR_value)?;
let description: Option<TString> = kwargs let description: Option<TString> = kwargs
.get(Qstr::MP_QSTR_description) .get(Qstr::MP_QSTR_description)
.unwrap_or_else(|_| Obj::const_none()) .unwrap_or_else(|_| Obj::const_none())
.try_into_option()?; .try_into_option()?;
let text_mono: bool = kwargs.get_or(Qstr::MP_QSTR_text_mono, true)?; let is_data: bool = kwargs.get_or(Qstr::MP_QSTR_is_data, true)?;
let extra: Option<TString> = kwargs let extra: Option<TString> = kwargs
.get(Qstr::MP_QSTR_extra) .get(Qstr::MP_QSTR_extra)
.unwrap_or_else(|_| Obj::const_none()) .unwrap_or_else(|_| Obj::const_none())
@ -133,10 +133,6 @@ extern "C" fn new_confirm_blob(n_args: usize, args: *const Obj, kwargs: *mut Map
.get(Qstr::MP_QSTR_verb_cancel) .get(Qstr::MP_QSTR_verb_cancel)
.unwrap_or_else(|_| Obj::const_none()) .unwrap_or_else(|_| Obj::const_none())
.try_into_option()?; .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)?; let info: bool = kwargs.get_or(Qstr::MP_QSTR_info, false)?;
let hold: bool = kwargs.get_or(Qstr::MP_QSTR_hold, false)?; let hold: bool = kwargs.get_or(Qstr::MP_QSTR_hold, false)?;
let chunkify: bool = kwargs.get_or(Qstr::MP_QSTR_chunkify, false)?; let chunkify: bool = kwargs.get_or(Qstr::MP_QSTR_chunkify, false)?;
@ -144,16 +140,15 @@ extern "C" fn new_confirm_blob(n_args: usize, args: *const Obj, kwargs: *mut Map
let prompt_screen: bool = kwargs.get_or(Qstr::MP_QSTR_prompt_screen, false)?; let prompt_screen: bool = kwargs.get_or(Qstr::MP_QSTR_prompt_screen, false)?;
let cancel: bool = kwargs.get_or(Qstr::MP_QSTR_cancel, false)?; let cancel: bool = kwargs.get_or(Qstr::MP_QSTR_cancel, false)?;
let layout_obj = ModelUI::confirm_blob( let layout_obj = ModelUI::confirm_value(
title, title,
data, value,
description, description,
text_mono, is_data,
extra, extra,
subtitle, subtitle,
verb, verb,
verb_cancel, verb_cancel,
verb_info,
info, info,
hold, hold,
chunkify, chunkify,
@ -166,10 +161,10 @@ extern "C" fn new_confirm_blob(n_args: usize, args: *const Obj, kwargs: *mut Map
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_intro(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj { extern "C" fn new_confirm_value_intro(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 value: Obj = kwargs.get(Qstr::MP_QSTR_value)?;
let subtitle: Option<TString> = kwargs let subtitle: Option<TString> = kwargs
.get(Qstr::MP_QSTR_subtitle) .get(Qstr::MP_QSTR_subtitle)
.unwrap_or_else(|_| Obj::const_none()) .unwrap_or_else(|_| Obj::const_none())
@ -185,7 +180,7 @@ extern "C" fn new_confirm_blob_intro(n_args: usize, args: *const Obj, kwargs: *m
let chunkify: bool = kwargs.get_or(Qstr::MP_QSTR_chunkify, false)?; let chunkify: bool = kwargs.get_or(Qstr::MP_QSTR_chunkify, false)?;
let layout_obj = let layout_obj =
ModelUI::confirm_blob_intro(title, data, subtitle, verb, verb_cancel, chunkify)?; ModelUI::confirm_value_intro(title, value, subtitle, verb, verb_cancel, chunkify)?;
Ok(layout_obj.into()) 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) }
@ -373,53 +368,6 @@ extern "C" fn new_confirm_summary(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_value(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 subtitle: Option<TString> = kwargs
.get(Qstr::MP_QSTR_subtitle)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let description: Option<TString> = kwargs
.get(Qstr::MP_QSTR_description)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let value: Obj = kwargs.get(Qstr::MP_QSTR_value)?;
let info_button: bool = kwargs.get_or(Qstr::MP_QSTR_info_button, false)?;
let verb: Option<TString> = kwargs
.get(Qstr::MP_QSTR_verb)
.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 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 text_mono: bool = kwargs.get_or(Qstr::MP_QSTR_text_mono, true)?;
let layout_obj = ModelUI::confirm_value(
title,
value,
description,
subtitle,
verb,
verb_info,
verb_cancel,
info_button,
hold,
chunkify,
text_mono,
)?;
Ok(layout_obj.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
extern "C" fn new_confirm_with_info(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj { extern "C" fn new_confirm_with_info(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()?;
@ -1170,17 +1118,16 @@ pub static mp_module_trezorui_api: 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_blob( /// def confirm_value(
/// *, /// *,
/// title: str, /// title: str,
/// data: str | bytes, /// value: str | bytes,
/// description: str | None, /// description: str | None,
/// text_mono: bool = True, /// is_data: bool = True,
/// extra: str | None = None, /// extra: str | None = None,
/// subtitle: str | None = None, /// subtitle: str | None = None,
/// verb: str | None = None, /// verb: str | None = None,
/// verb_cancel: str | None = None, /// verb_cancel: str | None = None,
/// verb_info: str | None = None,
/// info: bool = True, /// info: bool = True,
/// hold: bool = False, /// hold: bool = False,
/// chunkify: bool = False, /// chunkify: bool = False,
@ -1188,22 +1135,27 @@ pub static mp_module_trezorui_api: Module = obj_module! {
/// prompt_screen: bool = False, /// prompt_screen: bool = False,
/// cancel: bool = False, /// cancel: bool = False,
/// ) -> LayoutObj[UiResult]: /// ) -> LayoutObj[UiResult]:
/// """Confirm byte sequence data.""" /// """Confirm a generic piece of information on the screen.
Qstr::MP_QSTR_confirm_blob => obj_fn_kw!(0, new_confirm_blob).as_obj(), /// The value can either be human readable text (`is_data=False`)
/// or something else - like an address or a blob of data.
/// The difference between the two kinds of values
/// is both in the font and in the linebreak strategy."""
Qstr::MP_QSTR_confirm_value => obj_fn_kw!(0, new_confirm_value).as_obj(),
/// def confirm_blob_intro( /// def confirm_value_intro(
/// *, /// *,
/// title: str, /// title: str,
/// data: str | bytes, /// value: str | bytes,
/// subtitle: str | None = None, /// subtitle: str | None = None,
/// verb: str | None = None, /// verb: str | None = None,
/// verb_cancel: str | None = None, /// verb_cancel: str | None = None,
/// chunkify: bool = False, /// chunkify: bool = False,
/// ) -> LayoutObj[UiResult]: /// ) -> LayoutObj[UiResult]:
/// """Confirm byte sequence data by showing only the first page of the data /// """Similar to `confirm_value`, but only the first page is shown.
/// and instructing the user to access the menu in order to view all the data, /// This function is intended as a building block for a higher level `confirm_blob`
/// which can then be confirmed using confirm_blob.""" /// abstraction which can paginate the blob, show just the first page
Qstr::MP_QSTR_confirm_blob_intro => obj_fn_kw!(0, new_confirm_blob_intro).as_obj(), /// and instruct the user to view the complete blob if they wish."""
Qstr::MP_QSTR_confirm_value_intro => obj_fn_kw!(0, new_confirm_value_intro).as_obj(),
/// def confirm_coinjoin( /// def confirm_coinjoin(
/// *, /// *,
@ -1312,23 +1264,6 @@ pub static mp_module_trezorui_api: Module = obj_module! {
/// """Confirm summary of a transaction.""" /// """Confirm summary of a transaction."""
Qstr::MP_QSTR_confirm_summary => obj_fn_kw!(0, new_confirm_summary).as_obj(), Qstr::MP_QSTR_confirm_summary => obj_fn_kw!(0, new_confirm_summary).as_obj(),
/// def confirm_value(
/// *,
/// title: str,
/// value: str,
/// description: str | None,
/// subtitle: str | None,
/// verb: str | None = None,
/// verb_info: str | None = None,
/// verb_cancel: str | None = None,
/// info_button: bool = False,
/// hold: bool = False,
/// chunkify: bool = False,
/// text_mono: bool = True,
/// ) -> LayoutObj[UiResult]:
/// """Confirm value. Merge of confirm_total and confirm_output."""
Qstr::MP_QSTR_confirm_value => obj_fn_kw!(0, new_confirm_value).as_obj(),
/// def confirm_with_info( /// def confirm_with_info(
/// *, /// *,
/// title: str, /// title: str,

View File

@ -57,21 +57,21 @@ impl TryFrom<Obj> for StrOrBytes {
} }
#[derive(Clone)] #[derive(Clone)]
pub struct ConfirmBlob { pub struct ConfirmValueParams {
pub description: TString<'static>, pub description: TString<'static>,
pub extra: TString<'static>, pub extra: TString<'static>,
pub data: StrOrBytes, pub value: StrOrBytes,
pub font: &'static TextStyle,
pub description_font: &'static TextStyle, pub description_font: &'static TextStyle,
pub extra_font: &'static TextStyle, pub extra_font: &'static TextStyle,
pub data_font: &'static TextStyle,
} }
impl ParagraphSource<'static> for ConfirmBlob { impl ParagraphSource<'static> for ConfirmValueParams {
fn at(&self, index: usize, offset: usize) -> Paragraph<'static> { fn at(&self, index: usize, offset: usize) -> Paragraph<'static> {
match index { match index {
0 => Paragraph::new(self.description_font, self.description.skip_prefix(offset)), 0 => Paragraph::new(self.description_font, self.description.skip_prefix(offset)),
1 => Paragraph::new(self.extra_font, self.extra.skip_prefix(offset)), 1 => Paragraph::new(self.extra_font, self.extra.skip_prefix(offset)),
2 => Paragraph::new(self.data_font, self.data.as_str_offset(offset)), 2 => Paragraph::new(self.font, self.value.as_str_offset(offset)),
_ => unreachable!(), _ => unreachable!(),
} }
} }

View File

@ -23,7 +23,7 @@ use crate::{
geometry, geometry,
layout::{ layout::{
obj::{LayoutMaybeTrace, LayoutObj, RootComponent}, obj::{LayoutMaybeTrace, LayoutObj, RootComponent},
util::{ConfirmBlob, PropsList, RecoveryType}, util::{ConfirmValueParams, PropsList, RecoveryType},
}, },
ui_firmware::{ ui_firmware::{
FirmwareUI, MAX_CHECKLIST_ITEMS, MAX_GROUP_SHARE_LINES, MAX_WORD_QUIZ_ITEMS, FirmwareUI, MAX_CHECKLIST_ITEMS, MAX_GROUP_SHARE_LINES, MAX_WORD_QUIZ_ITEMS,
@ -94,23 +94,22 @@ impl FirmwareUI for UIBolt {
chunkify: bool, chunkify: bool,
) -> Result<Gc<LayoutObj>, Error> { ) -> Result<Gc<LayoutObj>, Error> {
let verb = verb.unwrap_or(TR::buttons__confirm.into()); let verb = verb.unwrap_or(TR::buttons__confirm.into());
ConfirmBlobParams::new(title, address, None, Some(verb), None, false) ConfirmValue::new(title, address, None, Some(verb), None, false)
.with_subtitle(address_label) .with_subtitle(address_label)
.with_info_button(info_button) .with_info_button(info_button)
.with_chunkify(chunkify) .with_chunkify(chunkify)
.into_layout() .into_layout()
} }
fn confirm_blob( fn confirm_value(
title: TString<'static>, title: TString<'static>,
data: Obj, value: Obj,
description: Option<TString<'static>>, description: Option<TString<'static>>,
text_mono: bool, is_data: bool,
extra: Option<TString<'static>>, extra: Option<TString<'static>>,
_subtitle: Option<TString<'static>>, subtitle: Option<TString<'static>>,
verb: Option<TString<'static>>, verb: Option<TString<'static>>,
verb_cancel: Option<TString<'static>>, verb_cancel: Option<TString<'static>>,
_verb_info: Option<TString<'static>>,
info: bool, info: bool,
hold: bool, hold: bool,
chunkify: bool, chunkify: bool,
@ -118,23 +117,24 @@ impl FirmwareUI for UIBolt {
_prompt_screen: bool, _prompt_screen: bool,
_cancel: bool, _cancel: bool,
) -> Result<Gc<LayoutObj>, Error> { ) -> Result<Gc<LayoutObj>, Error> {
ConfirmBlobParams::new(title, data, description, verb, verb_cancel, hold) ConfirmValue::new(title, value, description, verb, verb_cancel, hold)
.with_text_mono(text_mono) .with_text_mono(is_data)
.with_subtitle(subtitle)
.with_extra(extra) .with_extra(extra)
.with_chunkify(chunkify) .with_chunkify(chunkify)
.with_info_button(info) .with_info_button(info)
.into_layout() .into_layout()
} }
fn confirm_blob_intro( fn confirm_value_intro(
_title: TString<'static>, _title: TString<'static>,
_data: Obj, _value: Obj,
_subtitle: Option<TString<'static>>, _subtitle: Option<TString<'static>>,
_verb: Option<TString<'static>>, _verb: Option<TString<'static>>,
_verb_cancel: Option<TString<'static>>, _verb_cancel: Option<TString<'static>>,
_chunkify: bool, _chunkify: bool,
) -> Result<Gc<LayoutObj>, Error> { ) -> Result<Gc<LayoutObj>, Error> {
Err::<Gc<LayoutObj>, Error>(Error::ValueError(c"confirm_blob_intro not implemented")) Err::<Gc<LayoutObj>, Error>(Error::ValueError(c"confirm_value_intro not implemented"))
} }
fn confirm_homescreen( fn confirm_homescreen(
@ -450,27 +450,6 @@ impl FirmwareUI for UIBolt {
Ok(layout) Ok(layout)
} }
fn confirm_value(
title: TString<'static>,
value: Obj,
description: Option<TString<'static>>,
subtitle: Option<TString<'static>>,
verb: Option<TString<'static>>,
_verb_info: Option<TString<'static>>,
verb_cancel: Option<TString<'static>>,
info_button: bool,
hold: bool,
chunkify: bool,
text_mono: bool,
) -> Result<Gc<LayoutObj>, Error> {
ConfirmBlobParams::new(title, value, description, verb, verb_cancel, hold)
.with_subtitle(subtitle)
.with_info_button(info_button)
.with_chunkify(chunkify)
.with_text_mono(text_mono)
.into_layout()
}
fn confirm_with_info( fn confirm_with_info(
title: TString<'static>, title: TString<'static>,
button: TString<'static>, button: TString<'static>,
@ -1221,10 +1200,10 @@ fn new_show_modal(
} }
// TODO: move to some util.rs? // TODO: move to some util.rs?
struct ConfirmBlobParams { struct ConfirmValue {
title: TString<'static>, title: TString<'static>,
subtitle: Option<TString<'static>>, subtitle: Option<TString<'static>>,
data: Obj, value: Obj,
description: Option<TString<'static>>, description: Option<TString<'static>>,
extra: Option<TString<'static>>, extra: Option<TString<'static>>,
verb: Option<TString<'static>>, verb: Option<TString<'static>>,
@ -1235,10 +1214,10 @@ struct ConfirmBlobParams {
text_mono: bool, text_mono: bool,
} }
impl ConfirmBlobParams { impl ConfirmValue {
fn new( fn new(
title: TString<'static>, title: TString<'static>,
data: Obj, value: Obj,
description: Option<TString<'static>>, description: Option<TString<'static>>,
verb: Option<TString<'static>>, verb: Option<TString<'static>>,
verb_cancel: Option<TString<'static>>, verb_cancel: Option<TString<'static>>,
@ -1247,7 +1226,7 @@ impl ConfirmBlobParams {
Self { Self {
title, title,
subtitle: None, subtitle: None,
data, value,
description, description,
extra: None, extra: None,
verb, verb,
@ -1285,20 +1264,20 @@ impl ConfirmBlobParams {
} }
fn into_layout(self) -> Result<Gc<LayoutObj>, Error> { fn into_layout(self) -> Result<Gc<LayoutObj>, Error> {
let paragraphs = ConfirmBlob { let paragraphs = ConfirmValueParams {
description: self.description.unwrap_or("".into()), description: self.description.unwrap_or("".into()),
extra: self.extra.unwrap_or("".into()), extra: self.extra.unwrap_or("".into()),
data: self.data.try_into()?, value: self.value.try_into()?,
description_font: &theme::TEXT_NORMAL, font: if self.chunkify {
extra_font: &theme::TEXT_DEMIBOLD, let value: TString = self.value.try_into()?;
data_font: if self.chunkify { theme::get_chunkified_text_style(value.len())
let data: TString = self.data.try_into()?;
theme::get_chunkified_text_style(data.len())
} else if self.text_mono { } else if self.text_mono {
&theme::TEXT_MONO &theme::TEXT_MONO
} else { } else {
&theme::TEXT_NORMAL &theme::TEXT_NORMAL
}, },
description_font: &theme::TEXT_NORMAL,
extra_font: &theme::TEXT_DEMIBOLD,
} }
.into_paragraphs(); .into_paragraphs();

View File

@ -24,7 +24,7 @@ use crate::{
geometry, geometry,
layout::{ layout::{
obj::{LayoutMaybeTrace, LayoutObj, RootComponent}, obj::{LayoutMaybeTrace, LayoutObj, RootComponent},
util::{ConfirmBlob, RecoveryType}, util::{ConfirmValueParams, RecoveryType},
}, },
ui_firmware::{ ui_firmware::{
FirmwareUI, MAX_CHECKLIST_ITEMS, MAX_GROUP_SHARE_LINES, MAX_WORD_QUIZ_ITEMS, FirmwareUI, MAX_CHECKLIST_ITEMS, MAX_GROUP_SHARE_LINES, MAX_WORD_QUIZ_ITEMS,
@ -132,16 +132,15 @@ impl FirmwareUI for UICaesar {
Ok(obj) Ok(obj)
} }
fn confirm_blob( fn confirm_value(
title: TString<'static>, title: TString<'static>,
data: Obj, value: Obj,
description: Option<TString<'static>>, description: Option<TString<'static>>,
_text_mono: bool, is_data: bool,
extra: Option<TString<'static>>, extra: Option<TString<'static>>,
_subtitle: Option<TString<'static>>, _subtitle: Option<TString<'static>>,
verb: Option<TString<'static>>, verb: Option<TString<'static>>,
verb_cancel: Option<TString<'static>>, verb_cancel: Option<TString<'static>>,
_verb_info: Option<TString<'static>>,
_info: bool, _info: bool,
hold: bool, hold: bool,
chunkify: bool, chunkify: bool,
@ -149,20 +148,20 @@ impl FirmwareUI for UICaesar {
_prompt_screen: bool, _prompt_screen: bool,
_cancel: bool, _cancel: bool,
) -> Result<Gc<LayoutObj>, Error> { ) -> Result<Gc<LayoutObj>, Error> {
let style = if chunkify { let paragraphs = ConfirmValueParams {
// 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()), description: description.unwrap_or("".into()),
extra: extra.unwrap_or("".into()), extra: extra.unwrap_or("".into()),
data: data.try_into()?, value: value.try_into()?,
font: if chunkify {
// Chunkifying the address into smaller pieces when requested
&theme::TEXT_MONO_ADDRESS_CHUNKS
} else if is_data {
&theme::TEXT_MONO_DATA
} else {
&theme::TEXT_NORMAL
},
description_font: &theme::TEXT_BOLD, description_font: &theme::TEXT_BOLD,
extra_font: &theme::TEXT_NORMAL, extra_font: &theme::TEXT_NORMAL,
data_font: style,
} }
.into_paragraphs(); .into_paragraphs();
@ -176,15 +175,15 @@ impl FirmwareUI for UICaesar {
LayoutObj::new_root(layout) LayoutObj::new_root(layout)
} }
fn confirm_blob_intro( fn confirm_value_intro(
_title: TString<'static>, _title: TString<'static>,
_data: Obj, _value: Obj,
_subtitle: Option<TString<'static>>, _subtitle: Option<TString<'static>>,
_verb: Option<TString<'static>>, _verb: Option<TString<'static>>,
_verb_cancel: Option<TString<'static>>, _verb_cancel: Option<TString<'static>>,
_chunkify: bool, _chunkify: bool,
) -> Result<Gc<LayoutObj>, Error> { ) -> Result<Gc<LayoutObj>, Error> {
Err::<Gc<LayoutObj>, Error>(Error::ValueError(c"confirm_blob_intro not implemented")) Err::<Gc<LayoutObj>, Error>(Error::ValueError(c"confirm_value_intro not implemented"))
} }
fn confirm_homescreen( fn confirm_homescreen(
@ -590,36 +589,6 @@ impl FirmwareUI for UICaesar {
Ok(layout) Ok(layout)
} }
fn confirm_value(
title: TString<'static>,
value: Obj,
description: Option<TString<'static>>,
_subtitle: Option<TString<'static>>,
verb: Option<TString<'static>>,
_verb_info: Option<TString<'static>>,
verb_cancel: Option<TString<'static>>,
_info_button: bool,
hold: bool,
_chunkify: bool,
_text_mono: bool,
) -> Result<Gc<LayoutObj>, Error> {
let value: TString = value.try_into()?;
let description = description.unwrap_or("".into());
let paragraphs = Paragraphs::new([
Paragraph::new(&theme::TEXT_BOLD, description),
Paragraph::new(&theme::TEXT_MONO, value),
]);
let layout = content_in_button_page(
title,
paragraphs,
verb.unwrap_or(TR::buttons__confirm.into()),
verb_cancel,
hold,
)?;
LayoutObj::new_root(layout)
}
fn confirm_with_info( fn confirm_with_info(
title: TString<'static>, title: TString<'static>,
button: TString<'static>, button: TString<'static>,

View File

@ -23,7 +23,7 @@ use super::{
}, },
theme, theme,
}, },
util::{ConfirmBlobParams, ShowInfoParams}, util::{ConfirmValue, ShowInfoParams},
}; };
const MENU_ITEM_CANCEL: usize = 0; const MENU_ITEM_CANCEL: usize = 0;
@ -214,13 +214,13 @@ fn get_cancel_page(
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn new_confirm_output( pub fn new_confirm_output(
main_params: ConfirmBlobParams, confirm_main: ConfirmValue,
account: Option<TString<'static>>, account: Option<TString<'static>>,
account_path: Option<TString<'static>>, account_path: Option<TString<'static>>,
br_name: TString<'static>, br_name: TString<'static>,
br_code: u16, br_code: u16,
content_amount_params: Option<ConfirmBlobParams>, confirm_amount: Option<ConfirmValue>,
address_params: Option<ConfirmBlobParams>, confirm_address: Option<ConfirmValue>,
address_title: TString<'static>, address_title: TString<'static>,
summary_items_params: Option<ShowInfoParams>, summary_items_params: Option<ShowInfoParams>,
fee_items_params: ShowInfoParams, fee_items_params: ShowInfoParams,
@ -229,14 +229,14 @@ pub fn new_confirm_output(
cancel_text: Option<TString<'static>>, cancel_text: Option<TString<'static>>,
) -> Result<SwipeFlow, error::Error> { ) -> Result<SwipeFlow, error::Error> {
// Main // Main
let main_content = main_params let main_content = confirm_main
.into_layout()? .into_layout()?
.one_button_request(ButtonRequest::from_num(br_code, br_name)); .one_button_request(ButtonRequest::from_num(br_code, br_name));
// MainMenu // MainMenu
let mut main_menu = VerticalMenu::empty(); let mut main_menu = VerticalMenu::empty();
let mut main_menu_items = Vec::<usize, 3>::new(); let mut main_menu_items = Vec::<usize, 3>::new();
if address_params.is_some() { if confirm_address.is_some() {
main_menu = main_menu.item(theme::ICON_CHEVRON_RIGHT, address_title); main_menu = main_menu.item(theme::ICON_CHEVRON_RIGHT, address_title);
unwrap!(main_menu_items.push(MENU_ITEM_ADDRESS_INFO)); unwrap!(main_menu_items.push(MENU_ITEM_ADDRESS_INFO));
} }
@ -267,14 +267,14 @@ pub fn new_confirm_output(
let ac = AddressDetails::new(TR::send__send_from.into(), account, account_path)?; let ac = AddressDetails::new(TR::send__send_from.into(), account, account_path)?;
let account_content = ac.map(|_| Some(FlowMsg::Cancelled)); let account_content = ac.map(|_| Some(FlowMsg::Cancelled));
let res = if let Some(content_amount_params) = content_amount_params { let res = if let Some(confirm_amount) = confirm_amount {
let content_amount = content_amount_params let confirm_amount = confirm_amount
.into_layout()? .into_layout()?
.one_button_request(ButtonRequest::from_num(br_code, br_name)); .one_button_request(ButtonRequest::from_num(br_code, br_name));
SwipeFlow::new(&ConfirmOutputWithAmount::Address)? SwipeFlow::new(&ConfirmOutputWithAmount::Address)?
.with_page(&ConfirmOutputWithAmount::Address, main_content)? .with_page(&ConfirmOutputWithAmount::Address, main_content)?
.with_page(&ConfirmOutputWithAmount::Amount, content_amount)? .with_page(&ConfirmOutputWithAmount::Amount, confirm_amount)?
.with_page(&ConfirmOutputWithAmount::Menu, content_main_menu)? .with_page(&ConfirmOutputWithAmount::Menu, content_main_menu)?
.with_page(&ConfirmOutputWithAmount::AccountInfo, account_content)? .with_page(&ConfirmOutputWithAmount::AccountInfo, account_content)?
.with_page(&ConfirmOutputWithAmount::CancelTap, get_cancel_page())? .with_page(&ConfirmOutputWithAmount::CancelTap, get_cancel_page())?
@ -352,8 +352,8 @@ pub fn new_confirm_output(
.with_page(&ConfirmOutputWithSummary::Main, main_content)? .with_page(&ConfirmOutputWithSummary::Main, main_content)?
.with_page(&ConfirmOutputWithSummary::MainMenu, content_main_menu)? .with_page(&ConfirmOutputWithSummary::MainMenu, content_main_menu)?
.with_page(&ConfirmOutputWithSummary::MainMenuCancel, get_cancel_page())?; .with_page(&ConfirmOutputWithSummary::MainMenuCancel, get_cancel_page())?;
if let Some(address_params) = address_params { if let Some(confirm_address) = confirm_address {
let address_content = address_params.into_layout()?; let address_content = confirm_address.into_layout()?;
flow = flow.with_page(&ConfirmOutputWithSummary::AddressInfo, address_content)?; flow = flow.with_page(&ConfirmOutputWithSummary::AddressInfo, address_content)?;
} else { } else {
// dummy page - this will never be shown since there is no menu item pointing to // dummy page - this will never be shown since there is no menu item pointing to

View File

@ -15,7 +15,7 @@ use crate::{
FlowController, FlowMsg, SwipeFlow, SwipePage, FlowController, FlowMsg, SwipeFlow, SwipePage,
}, },
geometry::Direction, geometry::Direction,
layout::util::ConfirmBlob, layout::util::ConfirmValueParams,
}, },
}; };
@ -101,19 +101,18 @@ pub fn new_get_address(
br_name: TString<'static>, br_name: TString<'static>,
) -> Result<SwipeFlow, error::Error> { ) -> Result<SwipeFlow, error::Error> {
// Address // Address
let data_style = if chunkify { let paragraphs = ConfirmValueParams {
let address: TString = address.try_into()?;
theme::get_chunkified_text_style(address.len())
} else {
&theme::TEXT_MONO
};
let paragraphs = ConfirmBlob {
description: description.unwrap_or_else(|| "".into()), description: description.unwrap_or_else(|| "".into()),
extra: extra.unwrap_or_else(|| "".into()), extra: extra.unwrap_or_else(|| "".into()),
data: address.try_into()?, value: address.try_into()?,
font: if chunkify {
let address: TString = address.try_into()?;
theme::get_chunkified_text_style(address.len())
} else {
&theme::TEXT_MONO
},
description_font: &theme::TEXT_NORMAL, description_font: &theme::TEXT_NORMAL,
extra_font: &theme::TEXT_DEMIBOLD, extra_font: &theme::TEXT_DEMIBOLD,
data_font: data_style,
} }
.into_paragraphs(); .into_paragraphs();
let content_address = let content_address =

View File

@ -39,4 +39,4 @@ pub use set_brightness::SetBrightness;
pub use show_danger::ShowDanger; pub use show_danger::ShowDanger;
pub use show_share_words::ShowShareWords; pub use show_share_words::ShowShareWords;
pub use show_tutorial::ShowTutorial; pub use show_tutorial::ShowTutorial;
pub use util::{ConfirmBlobParams, ShowInfoParams}; pub use util::{ConfirmValue, ShowInfoParams};

View File

@ -16,7 +16,7 @@ use crate::{
}, },
flow::{FlowMsg, Swipable, SwipeFlow, SwipePage}, flow::{FlowMsg, Swipable, SwipeFlow, SwipePage},
geometry::Direction, geometry::Direction,
layout::util::{ConfirmBlob, StrOrBytes}, layout::util::{ConfirmValueParams, StrOrBytes},
}, },
}; };
use heapless::Vec; use heapless::Vec;
@ -29,12 +29,12 @@ use super::{
ConfirmActionExtra, ConfirmActionMenuStrings, ConfirmActionStrings, ConfirmActionExtra, ConfirmActionMenuStrings, ConfirmActionStrings,
}; };
pub struct ConfirmBlobParams { pub struct ConfirmValue {
title: TString<'static>, title: TString<'static>,
subtitle: Option<TString<'static>>, subtitle: Option<TString<'static>>,
footer_instruction: Option<TString<'static>>, footer_instruction: Option<TString<'static>>,
footer_description: Option<TString<'static>>, footer_description: Option<TString<'static>>,
data: Obj, value: Obj,
description: Option<TString<'static>>, description: Option<TString<'static>>,
description_font: &'static TextStyle, description_font: &'static TextStyle,
extra: Option<TString<'static>>, extra: Option<TString<'static>>,
@ -56,14 +56,14 @@ pub struct ConfirmBlobParams {
cancel: bool, cancel: bool,
} }
impl ConfirmBlobParams { impl ConfirmValue {
pub fn new(title: TString<'static>, data: Obj, description: Option<TString<'static>>) -> Self { pub fn new(title: TString<'static>, value: Obj, description: Option<TString<'static>>) -> Self {
Self { Self {
title, title,
subtitle: None, subtitle: None,
footer_instruction: None, footer_instruction: None,
footer_description: None, footer_description: None,
data, value,
description, description,
description_font: &theme::TEXT_NORMAL, description_font: &theme::TEXT_NORMAL,
extra: None, extra: None,
@ -202,24 +202,24 @@ impl ConfirmBlobParams {
pub fn into_layout( pub fn into_layout(
self, self,
) -> Result<impl Component<Msg = FlowMsg> + Swipable + MaybeTrace, Error> { ) -> Result<impl Component<Msg = FlowMsg> + Swipable + MaybeTrace, Error> {
let paragraphs = ConfirmBlob { let paragraphs = ConfirmValueParams {
description: self.description.unwrap_or("".into()), description: self.description.unwrap_or("".into()),
extra: self.extra.unwrap_or("".into()), extra: self.extra.unwrap_or("".into()),
data: if self.data != Obj::const_none() { value: if self.value != Obj::const_none() {
self.data.try_into()? self.value.try_into()?
} else { } else {
StrOrBytes::Str("".into()) StrOrBytes::Str("".into())
}, },
description_font: &theme::TEXT_NORMAL, font: if self.chunkify {
extra_font: &theme::TEXT_DEMIBOLD, let value: TString = self.value.try_into()?;
data_font: if self.chunkify { theme::get_chunkified_text_style(value.len())
let data: TString = self.data.try_into()?;
theme::get_chunkified_text_style(data.len())
} else if self.text_mono { } else if self.text_mono {
&theme::TEXT_MONO &theme::TEXT_MONO
} else { } else {
&theme::TEXT_NORMAL &theme::TEXT_NORMAL
}, },
description_font: &theme::TEXT_NORMAL,
extra_font: &theme::TEXT_DEMIBOLD,
} }
.into_paragraphs(); .into_paragraphs();
@ -257,20 +257,20 @@ impl ConfirmBlobParams {
} }
pub fn into_flow(self) -> Result<SwipeFlow, Error> { pub fn into_flow(self) -> Result<SwipeFlow, Error> {
let paragraphs = ConfirmBlob { let paragraphs = ConfirmValueParams {
description: self.description.unwrap_or("".into()), description: self.description.unwrap_or("".into()),
extra: self.extra.unwrap_or("".into()), extra: self.extra.unwrap_or("".into()),
data: self.data.try_into()?, value: self.value.try_into()?,
description_font: self.description_font, font: if self.chunkify {
extra_font: &theme::TEXT_DEMIBOLD, let value: TString = self.value.try_into()?;
data_font: if self.chunkify { theme::get_chunkified_text_style(value.len())
let data: TString = self.data.try_into()?;
theme::get_chunkified_text_style(data.len())
} else if self.text_mono { } else if self.text_mono {
&theme::TEXT_MONO &theme::TEXT_MONO
} else { } else {
&theme::TEXT_NORMAL &theme::TEXT_NORMAL
}, },
description_font: self.description_font,
extra_font: &theme::TEXT_DEMIBOLD,
} }
.into_paragraphs(); .into_paragraphs();

View File

@ -40,7 +40,7 @@ use super::{
}, },
flow::{ flow::{
self, new_confirm_action_simple, ConfirmActionExtra, ConfirmActionMenuStrings, self, new_confirm_action_simple, ConfirmActionExtra, ConfirmActionMenuStrings,
ConfirmActionStrings, ConfirmBlobParams, ShowInfoParams, ConfirmActionStrings, ConfirmValue, ShowInfoParams,
}, },
theme, UIDelizia, theme, UIDelizia,
}; };
@ -85,16 +85,15 @@ impl FirmwareUI for UIDelizia {
Err::<Gc<LayoutObj>, Error>(Error::ValueError(c"confirm_address not implemented")) Err::<Gc<LayoutObj>, Error>(Error::ValueError(c"confirm_address not implemented"))
} }
fn confirm_blob( fn confirm_value(
title: TString<'static>, title: TString<'static>,
data: Obj, value: Obj,
description: Option<TString<'static>>, description: Option<TString<'static>>,
text_mono: bool, is_data: bool,
extra: Option<TString<'static>>, extra: Option<TString<'static>>,
subtitle: Option<TString<'static>>, subtitle: Option<TString<'static>>,
verb: Option<TString<'static>>, verb: Option<TString<'static>>,
verb_cancel: Option<TString<'static>>, verb_cancel: Option<TString<'static>>,
verb_info: Option<TString<'static>>,
info: bool, info: bool,
hold: bool, hold: bool,
chunkify: bool, chunkify: bool,
@ -102,14 +101,14 @@ impl FirmwareUI for UIDelizia {
prompt_screen: bool, prompt_screen: bool,
cancel: bool, cancel: bool,
) -> Result<Gc<LayoutObj>, Error> { ) -> Result<Gc<LayoutObj>, Error> {
ConfirmBlobParams::new(title, data, description) ConfirmValue::new(title, value, description)
.with_description_font(&theme::TEXT_SUB_GREY) .with_description_font(&theme::TEXT_SUB_GREY)
.with_text_mono(text_mono) .with_text_mono(is_data)
.with_subtitle(subtitle) .with_subtitle(subtitle)
.with_verb(verb) .with_verb(verb)
.with_verb_cancel(verb_cancel) .with_verb_cancel(verb_cancel)
.with_verb_info(if info { .with_verb_info(if info {
Some(verb_info.unwrap_or(TR::words__title_information.into())) Some(TR::buttons__more_info.into())
} else { } else {
None None
}) })
@ -124,16 +123,16 @@ impl FirmwareUI for UIDelizia {
.map(Into::into) .map(Into::into)
} }
fn confirm_blob_intro( fn confirm_value_intro(
title: TString<'static>, title: TString<'static>,
data: Obj, value: Obj,
subtitle: Option<TString<'static>>, subtitle: Option<TString<'static>>,
verb: Option<TString<'static>>, verb: Option<TString<'static>>,
verb_cancel: Option<TString<'static>>, verb_cancel: Option<TString<'static>>,
chunkify: bool, chunkify: bool,
) -> Result<Gc<LayoutObj>, Error> { ) -> Result<Gc<LayoutObj>, Error> {
const CONFIRM_BLOB_INTRO_MARGIN: usize = 24; const CONFIRM_VALUE_INTRO_MARGIN: usize = 24;
ConfirmBlobParams::new(title, data, Some(TR::instructions__view_all_data.into())) ConfirmValue::new(title, value, Some(TR::instructions__view_all_data.into()))
.with_verb(verb) .with_verb(verb)
.with_verb_info(Some(TR::buttons__view_all_data.into())) .with_verb_info(Some(TR::buttons__view_all_data.into()))
.with_description_font(&theme::TEXT_SUB_GREEN_LIME) .with_description_font(&theme::TEXT_SUB_GREEN_LIME)
@ -144,7 +143,7 @@ impl FirmwareUI for UIDelizia {
)) ))
.with_chunkify(chunkify) .with_chunkify(chunkify)
.with_page_limit(Some(1)) .with_page_limit(Some(1))
.with_frame_margin(CONFIRM_BLOB_INTRO_MARGIN) .with_frame_margin(CONFIRM_VALUE_INTRO_MARGIN)
.into_flow() .into_flow()
.and_then(LayoutObj::new_root) .and_then(LayoutObj::new_root)
.map(Into::into) .map(Into::into)
@ -438,37 +437,6 @@ impl FirmwareUI for UIDelizia {
Ok(flow) Ok(flow)
} }
fn confirm_value(
title: TString<'static>,
value: Obj,
description: Option<TString<'static>>,
subtitle: Option<TString<'static>>,
verb: Option<TString<'static>>,
verb_info: Option<TString<'static>>,
verb_cancel: Option<TString<'static>>,
info_button: bool,
hold: bool,
chunkify: bool,
text_mono: bool,
) -> Result<Gc<LayoutObj>, Error> {
ConfirmBlobParams::new(title, value, description)
.with_subtitle(subtitle)
.with_verb(verb)
.with_verb_cancel(verb_cancel)
.with_verb_info(if info_button {
Some(verb_info.unwrap_or(TR::words__title_information.into()))
} else {
None
})
.with_chunkify(chunkify)
.with_text_mono(text_mono)
.with_prompt(hold)
.with_hold(hold)
.into_flow()
.and_then(LayoutObj::new_root)
.map(Into::into)
}
fn confirm_with_info( fn confirm_with_info(
title: TString<'static>, title: TString<'static>,
button: TString<'static>, button: TString<'static>,
@ -559,7 +527,7 @@ impl FirmwareUI for UIDelizia {
) -> Result<impl LayoutMaybeTrace, Error> { ) -> Result<impl LayoutMaybeTrace, Error> {
let address_title = address_title.unwrap_or(TR::words__address.into()); let address_title = address_title.unwrap_or(TR::words__address.into());
let main_params = ConfirmBlobParams::new(title.unwrap_or(TString::empty()), message, None) let confirm_main = ConfirmValue::new(title.unwrap_or(TString::empty()), message, None)
.with_subtitle(subtitle) .with_subtitle(subtitle)
.with_menu_button() .with_menu_button()
.with_footer(TR::instructions__swipe_up.into(), None) .with_footer(TR::instructions__swipe_up.into(), None)
@ -567,8 +535,8 @@ impl FirmwareUI for UIDelizia {
.with_text_mono(text_mono) .with_text_mono(text_mono)
.with_swipe_up(); .with_swipe_up();
let content_amount_params = amount.map(|amount| { let confirm_amount = amount.map(|amount| {
ConfirmBlobParams::new(TR::words__amount.into(), amount, None) ConfirmValue::new(TR::words__amount.into(), amount, None)
.with_subtitle(subtitle) .with_subtitle(subtitle)
.with_menu_button() .with_menu_button()
.with_footer(TR::instructions__swipe_up.into(), None) .with_footer(TR::instructions__swipe_up.into(), None)
@ -577,8 +545,8 @@ impl FirmwareUI for UIDelizia {
.with_swipe_down() .with_swipe_down()
}); });
let address_params = address.map(|address| { let confirm_value = address.map(|address| {
ConfirmBlobParams::new(address_title, address, None) ConfirmValue::new(address_title, address, None)
.with_cancel_button() .with_cancel_button()
.with_chunkify(true) .with_chunkify(true)
.with_text_mono(true) .with_text_mono(true)
@ -611,13 +579,13 @@ impl FirmwareUI for UIDelizia {
}; };
let flow = flow::confirm_output::new_confirm_output( let flow = flow::confirm_output::new_confirm_output(
main_params, confirm_main,
account, account,
account_path, account_path,
br_name, br_name,
br_code, br_code,
content_amount_params, confirm_amount,
address_params, confirm_value,
address_title, address_title,
summary_items_params, summary_items_params,
fee_items_params, fee_items_params,

View File

@ -41,16 +41,15 @@ pub trait FirmwareUI {
) -> Result<Gc<LayoutObj>, Error>; // TODO: return LayoutMaybeTrace ) -> Result<Gc<LayoutObj>, Error>; // TODO: return LayoutMaybeTrace
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
fn confirm_blob( fn confirm_value(
title: TString<'static>, title: TString<'static>,
data: Obj, // TODO: replace Obj value: Obj, // TODO: replace Obj
description: Option<TString<'static>>, description: Option<TString<'static>>,
text_mono: bool, is_data: bool,
extra: Option<TString<'static>>, extra: Option<TString<'static>>,
subtitle: Option<TString<'static>>, subtitle: Option<TString<'static>>,
verb: Option<TString<'static>>, verb: Option<TString<'static>>,
verb_cancel: Option<TString<'static>>, verb_cancel: Option<TString<'static>>,
verb_info: Option<TString<'static>>,
info: bool, info: bool,
hold: bool, hold: bool,
chunkify: bool, chunkify: bool,
@ -59,9 +58,9 @@ pub trait FirmwareUI {
cancel: bool, cancel: bool,
) -> Result<Gc<LayoutObj>, Error>; // TODO: return LayoutMaybeTrace ) -> Result<Gc<LayoutObj>, Error>; // TODO: return LayoutMaybeTrace
fn confirm_blob_intro( fn confirm_value_intro(
title: TString<'static>, title: TString<'static>,
data: Obj, // TODO: replace Obj value: Obj, // TODO: replace Obj
subtitle: Option<TString<'static>>, subtitle: Option<TString<'static>>,
verb: Option<TString<'static>>, verb: Option<TString<'static>>,
verb_cancel: Option<TString<'static>>, verb_cancel: Option<TString<'static>>,
@ -138,21 +137,6 @@ pub trait FirmwareUI {
verb_cancel: Option<TString<'static>>, verb_cancel: Option<TString<'static>>,
) -> Result<impl LayoutMaybeTrace, Error>; ) -> Result<impl LayoutMaybeTrace, Error>;
#[allow(clippy::too_many_arguments)]
fn confirm_value(
title: TString<'static>,
value: Obj, // TODO: replace Obj
description: Option<TString<'static>>,
subtitle: Option<TString<'static>>,
verb: Option<TString<'static>>,
verb_info: Option<TString<'static>>,
verb_cancel: Option<TString<'static>>,
info_button: bool,
hold: bool,
chunkify: bool,
text_mono: bool,
) -> Result<Gc<LayoutObj>, Error>; // TODO: return LayoutMaybeTrace
fn confirm_with_info( fn confirm_with_info(
title: TString<'static>, title: TString<'static>,
button: TString<'static>, button: TString<'static>,

View File

@ -112,17 +112,16 @@ def confirm_address(
# rust/src/ui/api/firmware_micropython.rs # rust/src/ui/api/firmware_micropython.rs
def confirm_blob( def confirm_value(
*, *,
title: str, title: str,
data: str | bytes, value: str | bytes,
description: str | None, description: str | None,
text_mono: bool = True, is_data: bool = True,
extra: str | None = None, extra: str | None = None,
subtitle: str | None = None, subtitle: str | None = None,
verb: str | None = None, verb: str | None = None,
verb_cancel: str | None = None, verb_cancel: str | None = None,
verb_info: str | None = None,
info: bool = True, info: bool = True,
hold: bool = False, hold: bool = False,
chunkify: bool = False, chunkify: bool = False,
@ -130,22 +129,27 @@ def confirm_blob(
prompt_screen: bool = False, prompt_screen: bool = False,
cancel: bool = False, cancel: bool = False,
) -> LayoutObj[UiResult]: ) -> LayoutObj[UiResult]:
"""Confirm byte sequence data.""" """Confirm a generic piece of information on the screen.
The value can either be human readable text (`is_data=False`)
or something else - like an address or a blob of data.
The difference between the two kinds of values
is both in the font and in the linebreak strategy."""
# rust/src/ui/api/firmware_micropython.rs # rust/src/ui/api/firmware_micropython.rs
def confirm_blob_intro( def confirm_value_intro(
*, *,
title: str, title: str,
data: str | bytes, value: str | bytes,
subtitle: str | None = None, subtitle: str | None = None,
verb: str | None = None, verb: str | None = None,
verb_cancel: str | None = None, verb_cancel: str | None = None,
chunkify: bool = False, chunkify: bool = False,
) -> LayoutObj[UiResult]: ) -> LayoutObj[UiResult]:
"""Confirm byte sequence data by showing only the first page of the data """Similar to `confirm_value`, but only the first page is shown.
and instructing the user to access the menu in order to view all the data, This function is intended as a building block for a higher level `confirm_blob`
which can then be confirmed using confirm_blob.""" abstraction which can paginate the blob, show just the first page
and instruct the user to view the complete blob if they wish."""
# rust/src/ui/api/firmware_micropython.rs # rust/src/ui/api/firmware_micropython.rs
@ -265,24 +269,6 @@ def confirm_summary(
"""Confirm summary of a transaction.""" """Confirm summary of a transaction."""
# rust/src/ui/api/firmware_micropython.rs
def confirm_value(
*,
title: str,
value: str,
description: str | None,
subtitle: str | None,
verb: str | None = None,
verb_info: str | None = None,
verb_cancel: str | None = None,
info_button: bool = False,
hold: bool = False,
chunkify: bool = False,
text_mono: bool = True,
) -> LayoutObj[UiResult]:
"""Confirm value. Merge of confirm_total and confirm_output."""
# rust/src/ui/api/firmware_micropython.rs # rust/src/ui/api/firmware_micropython.rs
def confirm_with_info( def confirm_with_info(
*, *,

View File

@ -310,14 +310,17 @@ async def confirm_nondefault_locktime(lock_time: int, lock_time_disabled: bool)
if lock_time < _LOCKTIME_TIMESTAMP_MIN_VALUE: if lock_time < _LOCKTIME_TIMESTAMP_MIN_VALUE:
text = TR.bitcoin__locktime_set_to_blockheight text = TR.bitcoin__locktime_set_to_blockheight
value = str(lock_time) value = str(lock_time)
is_data = True
else: else:
text = TR.bitcoin__locktime_set_to text = TR.bitcoin__locktime_set_to
value = format_timestamp(lock_time) value = format_timestamp(lock_time)
is_data = False
await layouts.confirm_value( await layouts.confirm_value(
TR.bitcoin__confirm_locktime, TR.bitcoin__confirm_locktime,
value, value,
text, text,
"nondefault_locktime", "nondefault_locktime",
is_data=is_data,
br_code=ButtonRequestType.SignTx, br_code=ButtonRequestType.SignTx,
verb=TR.buttons__confirm, verb=TR.buttons__confirm,
) )

View File

@ -443,13 +443,13 @@ async def confirm_output(
await interact( await interact(
trezorui_api.confirm_value( trezorui_api.confirm_value(
title=amount_title, title=amount_title,
subtitle=None,
description=None,
value=amount, value=amount,
description=None,
subtitle=None,
verb=None if hold else TR.buttons__confirm, verb=None if hold else TR.buttons__confirm,
verb_cancel="^", verb_cancel="^",
info=False,
hold=hold, hold=hold,
info_button=False,
), ),
"confirm_output", "confirm_output",
br_code, br_code,
@ -569,7 +569,6 @@ def confirm_blob(
title: str, title: str,
data: bytes | str, data: bytes | str,
description: str | None = None, description: str | None = None,
text_mono: bool = True,
subtitle: str | None = None, subtitle: str | None = None,
verb: str | None = None, verb: str | None = None,
verb_cancel: str | None = None, verb_cancel: str | None = None,
@ -581,11 +580,10 @@ 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 = trezorui_api.confirm_blob( layout = trezorui_api.confirm_value(
title=title, title=title,
description=description, description=description,
text_mono=text_mono, value=data,
data=data,
hold=hold, hold=hold,
verb=verb, verb=verb,
verb_cancel=None, verb_cancel=None,
@ -669,7 +667,7 @@ def confirm_value(
verb: str | None = None, verb: str | None = None,
subtitle: str | None = None, subtitle: str | None = None,
hold: bool = False, hold: bool = False,
value_text_mono: bool = True, is_data: bool = True,
info_items: Iterable[tuple[str, str]] | None = None, info_items: Iterable[tuple[str, str]] | None = None,
info_title: str | None = None, info_title: str | None = None,
chunkify_info: bool = False, chunkify_info: bool = False,
@ -689,13 +687,13 @@ def confirm_value(
return with_info( return with_info(
trezorui_api.confirm_value( trezorui_api.confirm_value(
title=title, title=title,
subtitle=subtitle,
description=description,
value=value, value=value,
description=description,
is_data=is_data,
subtitle=subtitle,
verb=verb, verb=verb,
info=bool(info_items),
hold=hold, hold=hold,
info_button=bool(info_items),
text_mono=value_text_mono,
), ),
info_layout, info_layout,
br_name, br_name,
@ -874,6 +872,7 @@ if not utils.BITCOIN_ONLY:
br_code: ButtonRequestType = ButtonRequestType.SignTx, br_code: ButtonRequestType = ButtonRequestType.SignTx,
) -> None: ) -> None:
# intro # intro
await confirm_value( await confirm_value(
title, title,
intro_question, intro_question,
@ -881,7 +880,7 @@ if not utils.BITCOIN_ONLY:
br_name, br_name,
br_code, br_code,
verb=verb, verb=verb,
value_text_mono=False, is_data=False,
info_items=(("", address),), info_items=(("", address),),
info_title=address_title, info_title=address_title,
chunkify_info=chunkify, chunkify_info=chunkify,
@ -1009,9 +1008,9 @@ 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(
trezorui_api.confirm_blob( trezorui_api.confirm_value(
title="MODIFY AMOUNT", title="MODIFY AMOUNT",
data=address, value=address,
verb="CONTINUE", verb="CONTINUE",
verb_cancel=None, verb_cancel=None,
description="Address:", description="Address:",
@ -1128,10 +1127,10 @@ async def confirm_signverify(
horizontal=True, horizontal=True,
) )
message_layout = trezorui_api.confirm_blob( message_layout = trezorui_api.confirm_value(
title=TR.sign_message__confirm_message, title=TR.sign_message__confirm_message,
description=None, description=None,
data=message, value=message,
hold=not verify, hold=not verify,
verb=TR.buttons__confirm if verify else None, verb=TR.buttons__confirm if verify else None,
) )

View File

@ -503,7 +503,6 @@ async def confirm_output(
title=amount_title, title=amount_title,
value=amount, value=amount,
description=None, description=None,
subtitle=None,
verb_cancel="^", verb_cancel="^",
verb=TR.buttons__confirm, verb=TR.buttons__confirm,
), ),
@ -590,12 +589,14 @@ def confirm_blob(
chunkify: bool = False, chunkify: bool = False,
prompt_screen: bool = True, prompt_screen: bool = True,
) -> Awaitable[None]: ) -> Awaitable[None]:
verb = verb or TR.buttons__confirm # def_arg if description and ":" not in description:
layout = trezorui_api.confirm_blob( description += ":"
layout = trezorui_api.confirm_value(
title=title, title=title,
description=description, description=description,
data=data, value=data,
verb=verb, verb=verb or TR.buttons__confirm,
verb_cancel="", verb_cancel="",
hold=hold, hold=hold,
chunkify=chunkify, chunkify=chunkify,
@ -736,6 +737,7 @@ async def confirm_value(
*, *,
verb: str | None = None, verb: str | None = None,
hold: bool = False, hold: bool = False,
is_data: bool = True,
info_items: Iterable[tuple[str, str]] | None = None, info_items: Iterable[tuple[str, str]] | None = None,
chunkify_info: bool = False, chunkify_info: bool = False,
) -> None: ) -> None:
@ -746,13 +748,15 @@ async def confirm_value(
if info_items is None: if info_items is None:
return await raise_if_not_confirmed( return await raise_if_not_confirmed(
trezorui_api.confirm_value( # type: ignore [Argument missing for parameter "subtitle"] trezorui_api.confirm_value(
title=title, title=title,
description=description,
value=value, value=value,
description=description,
verb=verb or TR.buttons__hold_to_confirm, verb=verb or TR.buttons__hold_to_confirm,
verb_cancel="", verb_cancel="",
info=False,
hold=hold, hold=hold,
is_data=is_data,
), ),
br_name, br_name,
br_code, br_code,
@ -782,13 +786,14 @@ 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(
trezorui_api.confirm_blob( trezorui_api.confirm_value(
title=info_title, title=info_title,
data=info_value, value=info_value,
description=description, description=description,
verb="", verb="",
verb_cancel="<", verb_cancel="<",
hold=False, hold=False,
is_data=is_data,
chunkify=chunkify_info, chunkify=chunkify_info,
), ),
None, None,
@ -1031,9 +1036,9 @@ async def confirm_modify_output(
amount_change: str, amount_change: str,
amount_new: str, amount_new: str,
) -> None: ) -> None:
address_layout = trezorui_api.confirm_blob( address_layout = trezorui_api.confirm_value(
title=TR.modify_amount__title, title=TR.modify_amount__title,
data=address, value=address,
verb=TR.buttons__continue, verb=TR.buttons__continue,
description=f"{TR.words__address}:", description=f"{TR.words__address}:",
) )
@ -1133,10 +1138,10 @@ async def confirm_signverify(
) )
try: try:
await raise_if_not_confirmed( await raise_if_not_confirmed(
trezorui_api.confirm_blob( trezorui_api.confirm_value(
title=TR.sign_message__confirm_message, title=TR.sign_message__confirm_message,
description=None, description=None,
data=message, value=message,
verb=None, verb=None,
verb_cancel="^", verb_cancel="^",
hold=False, hold=False,

View File

@ -484,7 +484,6 @@ def confirm_blob(
title: str, title: str,
data: bytes | str, data: bytes | str,
description: str | None = None, description: str | None = None,
text_mono: bool = True,
subtitle: str | None = None, subtitle: str | None = None,
verb: str | None = None, verb: str | None = None,
verb_cancel: str | None = None, verb_cancel: str | None = None,
@ -496,17 +495,17 @@ def confirm_blob(
prompt_screen: bool = True, prompt_screen: bool = True,
) -> Awaitable[None]: ) -> Awaitable[None]:
if ask_pagination: if ask_pagination:
main_layout = trezorui_api.confirm_blob_intro( main_layout = trezorui_api.confirm_value_intro(
title=title, title=title,
data=data, value=data,
subtitle=description, subtitle=description,
verb=verb, verb=verb,
verb_cancel=verb_cancel, verb_cancel=verb_cancel,
chunkify=chunkify, chunkify=chunkify,
) )
info_layout = trezorui_api.confirm_blob( info_layout = trezorui_api.confirm_value(
title=title, title=title,
data=data, value=data,
subtitle=description, subtitle=description,
description=None, description=None,
verb=None, verb=None,
@ -528,11 +527,10 @@ def confirm_blob(
info_layout_can_confirm=True, info_layout_can_confirm=True,
) )
else: else:
layout = trezorui_api.confirm_blob( layout = trezorui_api.confirm_value(
title=title, title=title,
data=data, value=data,
description=description, description=description,
text_mono=text_mono,
subtitle=subtitle, subtitle=subtitle,
verb=verb, verb=verb,
verb_cancel=verb_cancel, verb_cancel=verb_cancel,
@ -615,7 +613,7 @@ def confirm_value(
verb: str | None = None, verb: str | None = None,
subtitle: str | None = None, subtitle: str | None = None,
hold: bool = False, hold: bool = False,
value_text_mono: bool = True, is_data: bool = True,
chunkify: bool = False, chunkify: bool = False,
info_items: Iterable[tuple[str, str]] | None = None, info_items: Iterable[tuple[str, str]] | None = None,
info_title: str | None = None, info_title: str | None = None,
@ -636,14 +634,14 @@ def confirm_value(
return with_info( return with_info(
trezorui_api.confirm_value( trezorui_api.confirm_value(
title=title, title=title,
subtitle=subtitle,
description=description,
value=value, value=value,
is_data=is_data,
description=description,
subtitle=subtitle,
verb=verb, verb=verb,
info=bool(info_items),
hold=hold, hold=hold,
info_button=bool(info_items),
chunkify=chunkify, chunkify=chunkify,
text_mono=value_text_mono,
), ),
info_layout, info_layout,
br_name, br_name,
@ -936,9 +934,9 @@ async def confirm_modify_output(
amount_change: str, amount_change: str,
amount_new: str, amount_new: str,
) -> None: ) -> None:
address_layout = trezorui_api.confirm_blob( address_layout = trezorui_api.confirm_value(
title=TR.modify_amount__title, title=TR.modify_amount__title,
data=address, value=address,
verb=TR.buttons__continue, verb=TR.buttons__continue,
verb_cancel=None, verb_cancel=None,
description=f"{TR.words__address}:", description=f"{TR.words__address}:",
@ -1033,12 +1031,10 @@ async def confirm_signverify(
address_layout = trezorui_api.confirm_value( address_layout = trezorui_api.confirm_value(
title=address_title, title=address_title,
subtitle=None,
description="",
value=address, value=address,
description="",
verb=TR.buttons__continue, verb=TR.buttons__continue,
verb_info=TR.buttons__more_info, info=True,
info_button=True,
chunkify=chunkify, chunkify=chunkify,
) )
@ -1060,10 +1056,10 @@ async def confirm_signverify(
horizontal=True, horizontal=True,
) )
message_layout = trezorui_api.confirm_blob( message_layout = trezorui_api.confirm_value(
title=TR.sign_message__confirm_message, title=TR.sign_message__confirm_message,
description=None, description=None,
data=message, value=message,
extra=None, extra=None,
prompt_screen=True, prompt_screen=True,
hold=not verify, hold=not verify,