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

refactor(core): move confirm_with_info

- decided to import stuff from micropython so that I don't have to write
`crate::micropython::yadayada` everywhere. I'll remove that from other
functions later during squash.
This commit is contained in:
obrusvit 2024-11-21 10:52:47 +01:00
parent 9bff86142d
commit 926b91cb66
13 changed files with 162 additions and 181 deletions

View File

@ -184,6 +184,23 @@ extern "C" fn new_confirm_reset_device(n_args: usize, args: *const Obj, kwargs:
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 {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let button: TString = kwargs.get(Qstr::MP_QSTR_button)?.try_into()?;
let info_button: TString = kwargs.get(Qstr::MP_QSTR_info_button)?.try_into()?;
let verb_cancel: Option<TString<'static>> = kwargs
.get(Qstr::MP_QSTR_verb_cancel)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let items: Obj = kwargs.get(Qstr::MP_QSTR_items)?;
let layout = ModelUI::confirm_with_info(title, button, info_button, verb_cancel, items)?;
Ok(LayoutObj::new_root(layout)?.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
extern "C" fn new_continue_recovery_homepage(
n_args: usize,
args: *const Obj,
@ -794,6 +811,19 @@ pub static mp_module_trezorui_api: Module = obj_module! {
/// """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(),
/// def confirm_with_info(
/// *,
/// title: str,
/// button: str,
/// info_button: str,
/// verb_cancel: str | None = None,
/// items: Iterable[tuple[int, str | bytes]],
/// ) -> LayoutObj[UiResult]:
/// """Confirm given items but with third button. Always single page
/// without scrolling. In mercury, the button is placed in
/// context menu."""
Qstr::MP_QSTR_confirm_with_info => obj_fn_kw!(0, new_confirm_with_info).as_obj(),
/// def continue_recovery_homepage(
/// *,
/// text: str,

View File

@ -658,32 +658,6 @@ extern "C" fn new_confirm_total(n_args: usize, args: *const Obj, kwargs: *mut Ma
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 {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let button: TString = kwargs.get(Qstr::MP_QSTR_button)?.try_into()?;
let info_button: TString = kwargs.get(Qstr::MP_QSTR_info_button)?.try_into()?;
let items: Obj = kwargs.get(Qstr::MP_QSTR_items)?;
let mut paragraphs = ParagraphVecShort::new();
for para in IterBuf::new().try_iterate(items)? {
let [font, text]: [Obj; 2] = util::iter_into_array(para)?;
let style: &TextStyle = theme::textstyle_number(font.try_into()?);
let text: TString = text.try_into()?;
paragraphs.add(Paragraph::new(style, text));
if paragraphs.is_full() {
break;
}
}
let flow =
confirm_with_info::new_confirm_with_info(title, button, info_button, paragraphs)?;
Ok(LayoutObj::new_root(flow)?.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
extern "C" fn new_confirm_more(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()?;
@ -875,17 +849,6 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// """Transaction summary. Always hold to confirm."""
Qstr::MP_QSTR_confirm_total => obj_fn_kw!(0, new_confirm_total).as_obj(),
/// def confirm_with_info(
/// *,
/// title: str,
/// button: str,
/// info_button: str,
/// items: Iterable[tuple[int, str]],
/// ) -> LayoutObj[UiResult]:
/// """Confirm given items but with third button. In mercury, the button is placed in
/// context menu."""
Qstr::MP_QSTR_confirm_with_info => obj_fn_kw!(0, new_confirm_with_info).as_obj(),
/// def confirm_more(
/// *,
/// title: str,

View File

@ -3,17 +3,20 @@ use core::cmp::Ordering;
use crate::{
error::{value_error, Error},
io::BinaryData,
micropython::{gc::Gc, list::List, util},
micropython::{gc::Gc, iter::IterBuf, list::List, obj::Obj, util},
strutil::TString,
translations::TR,
ui::{
component::{
connect::Connect,
swipe_detect::SwipeSettings,
text::paragraphs::{
text::{
paragraphs::{
Checklist, Paragraph, ParagraphSource, ParagraphVecLong, ParagraphVecShort,
Paragraphs, VecExt,
},
TextStyle,
},
Border, CachedJpeg, ComponentExt, Empty, Never, Timeout,
},
geometry::{self, Direction},
@ -31,7 +34,9 @@ use super::{
MnemonicKeyboard, PinKeyboard, Progress, SelectWordCount, Slip39Input, StatusScreen,
SwipeContent, SwipeUpScreen, VerticalMenu,
},
flow::{self, new_confirm_action_simple, ConfirmActionMenu, ConfirmActionStrings},
flow::{
self, confirm_with_info, new_confirm_action_simple, ConfirmActionMenu, ConfirmActionStrings,
},
theme, ModelMercuryFeatures,
};
@ -225,6 +230,30 @@ impl UIFeaturesFirmware for ModelMercuryFeatures {
Ok(flow)
}
fn confirm_with_info(
title: TString<'static>,
button: TString<'static>,
info_button: TString<'static>,
verb_cancel: Option<TString<'static>>,
items: Obj,
) -> Result<impl LayoutMaybeTrace, Error> {
let mut paragraphs = ParagraphVecShort::new();
for para in IterBuf::new().try_iterate(items)? {
let [font, text]: [Obj; 2] = util::iter_into_array(para)?;
let style: &TextStyle = theme::textstyle_number(font.try_into()?);
let text: TString = text.try_into()?;
paragraphs.add(Paragraph::new(style, text));
if paragraphs.is_full() {
break;
}
}
let flow =
confirm_with_info::new_confirm_with_info(title, button, info_button, paragraphs)?;
Ok(flow)
}
fn check_homescreen_format(image: BinaryData, __accept_toif: bool) -> bool {
super::component::check_homescreen_format(image)
}

View File

@ -778,41 +778,6 @@ extern "C" fn new_multiple_pages_texts(n_args: usize, args: *const Obj, kwargs:
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 {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let button: TString<'static> = kwargs.get(Qstr::MP_QSTR_button)?.try_into()?;
let verb_cancel: Option<TString<'static>> = kwargs
.get(Qstr::MP_QSTR_verb_cancel)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let items: Obj = kwargs.get(Qstr::MP_QSTR_items)?;
let mut paragraphs = ParagraphVecShort::new();
for para in IterBuf::new().try_iterate(items)? {
let [font, text]: [Obj; 2] = util::iter_into_array(para)?;
let style: &TextStyle = theme::textstyle_number(font.try_into()?);
let text: TString = text.try_into()?;
paragraphs.add(Paragraph::new(style, text));
if paragraphs.is_full() {
break;
}
}
let obj = LayoutObj::new(Frame::new(
title,
ShowMore::<Paragraphs<ParagraphVecShort>>::new(
paragraphs.into_paragraphs(),
verb_cancel,
button,
),
))?;
Ok(obj.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
extern "C" fn new_confirm_more(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()?;
@ -976,18 +941,6 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// """Show multiple texts, each on its own page."""
Qstr::MP_QSTR_multiple_pages_texts => obj_fn_kw!(0, new_multiple_pages_texts).as_obj(),
/// def confirm_with_info(
/// *,
/// title: str,
/// button: str,
/// info_button: str, # unused on TR
/// items: Iterable[Tuple[int, str | bytes]],
/// verb_cancel: str | None = None,
/// ) -> LayoutObj[UiResult]:
/// """Confirm given items but with third button. Always single page
/// without scrolling."""
Qstr::MP_QSTR_confirm_with_info => obj_fn_kw!(0, new_confirm_with_info).as_obj(),
/// def confirm_more(
/// *,
/// title: str,

View File

@ -4,7 +4,7 @@ use crate::{
error::Error,
io::BinaryData,
maybe_trace::MaybeTrace,
micropython::{gc::Gc, list::List},
micropython::{gc::Gc, iter::IterBuf, list::List, obj::Obj, util},
strutil::TString,
translations::TR,
ui::{
@ -16,6 +16,7 @@ use crate::{
Checklist, Paragraph, ParagraphSource, ParagraphVecLong, ParagraphVecShort,
Paragraphs, VecExt,
},
TextStyle,
},
Component, ComponentExt, Empty, FormattedText, Label, LineBreaking, Paginate, Timeout,
},
@ -36,7 +37,7 @@ use super::{
component::{
ButtonDetails, ButtonPage, CoinJoinProgress, ConfirmHomescreen, Flow, FlowPages, Frame,
Homescreen, Lockscreen, NumberInput, PassphraseEntry, PinEntry, Progress, ScrollableFrame,
ShareWords, SimpleChoice, WordlistEntry, WordlistType,
ShareWords, ShowMore, SimpleChoice, WordlistEntry, WordlistType,
},
theme, ModelTRFeatures,
};
@ -290,6 +291,36 @@ impl UIFeaturesFirmware for ModelTRFeatures {
content_in_button_page(title, formatted, button, Some("".into()), false)
}
fn confirm_with_info(
title: TString<'static>,
button: TString<'static>,
_info_button: TString<'static>,
verb_cancel: Option<TString<'static>>,
items: Obj,
) -> Result<impl LayoutMaybeTrace, Error> {
let mut paragraphs = ParagraphVecShort::new();
for para in IterBuf::new().try_iterate(items)? {
let [font, text]: [Obj; 2] = util::iter_into_array(para)?;
let style: &TextStyle = theme::textstyle_number(font.try_into()?);
let text: TString = text.try_into()?;
paragraphs.add(Paragraph::new(style, text));
if paragraphs.is_full() {
break;
}
}
let layout = RootComponent::new(Frame::new(
title,
ShowMore::<Paragraphs<ParagraphVecShort>>::new(
paragraphs.into_paragraphs(),
verb_cancel,
button,
),
));
Ok(layout)
}
fn check_homescreen_format(image: BinaryData, _accept_toif: bool) -> bool {
super::component::check_homescreen_format(image)
}

View File

@ -702,37 +702,6 @@ extern "C" fn new_confirm_total(n_args: usize, args: *const Obj, kwargs: *mut Ma
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 {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let button: TString = kwargs.get(Qstr::MP_QSTR_button)?.try_into()?;
let info_button: TString = kwargs.get(Qstr::MP_QSTR_info_button)?.try_into()?;
let items: Obj = kwargs.get(Qstr::MP_QSTR_items)?;
let mut paragraphs = ParagraphVecShort::new();
for para in IterBuf::new().try_iterate(items)? {
let [font, text]: [Obj; 2] = util::iter_into_array(para)?;
let style: &TextStyle = theme::textstyle_number(font.try_into()?);
let text: TString = text.try_into()?;
paragraphs.add(Paragraph::new(style, text));
if paragraphs.is_full() {
break;
}
}
let buttons = Button::cancel_info_confirm(button, info_button);
let obj = LayoutObj::new(Frame::left_aligned(
theme::label_title(),
title,
Dialog::new(paragraphs.into_paragraphs(), buttons),
))?;
Ok(obj.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
extern "C" fn new_confirm_more(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()?;
@ -875,17 +844,6 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// """Transaction summary. Always hold to confirm."""
Qstr::MP_QSTR_confirm_total => obj_fn_kw!(0, new_confirm_total).as_obj(),
/// def confirm_with_info(
/// *,
/// title: str,
/// button: str,
/// info_button: str,
/// items: Iterable[tuple[int, str | bytes]],
/// ) -> LayoutObj[UiResult]:
/// """Confirm given items but with third button. Always single page
/// without scrolling."""
Qstr::MP_QSTR_confirm_with_info => obj_fn_kw!(0, new_confirm_with_info).as_obj(),
/// def confirm_more(
/// *,
/// title: str,

View File

@ -3,17 +3,20 @@ use core::cmp::Ordering;
use crate::{
error::{value_error, Error},
io::BinaryData,
micropython::{gc::Gc, list::List},
micropython::{gc::Gc, iter::IterBuf, list::List, obj::Obj, util},
strutil::TString,
translations::TR,
ui::{
component::{
connect::Connect,
image::BlendedImage,
text::paragraphs::{
text::{
paragraphs::{
Checklist, Paragraph, ParagraphSource, ParagraphVecLong, ParagraphVecShort,
Paragraphs, VecExt,
},
TextStyle,
},
Border, ComponentExt, Empty, Jpeg, Label, Never, Timeout,
},
layout::{
@ -272,6 +275,35 @@ impl UIFeaturesFirmware for ModelTTFeatures {
Ok(layout)
}
fn confirm_with_info(
title: TString<'static>,
button: TString<'static>,
info_button: TString<'static>,
_verb_cancel: Option<TString<'static>>,
items: Obj,
) -> Result<impl LayoutMaybeTrace, Error> {
let mut paragraphs = ParagraphVecShort::new();
for para in IterBuf::new().try_iterate(items)? {
let [font, text]: [Obj; 2] = util::iter_into_array(para)?;
let style: &TextStyle = theme::textstyle_number(font.try_into()?);
let text: TString = text.try_into()?;
paragraphs.add(Paragraph::new(style, text));
if paragraphs.is_full() {
break;
}
}
let buttons = Button::cancel_info_confirm(button, info_button);
let layout = RootComponent::new(Frame::left_aligned(
theme::label_title(),
title,
Dialog::new(paragraphs.into_paragraphs(), buttons),
));
Ok(layout)
}
fn check_homescreen_format(image: BinaryData, accept_toif: bool) -> bool {
super::component::check_homescreen_format(image, false)
}

View File

@ -64,6 +64,14 @@ pub trait UIFeaturesFirmware {
fn confirm_reset_device(recovery: bool) -> Result<impl LayoutMaybeTrace, Error>;
fn confirm_with_info(
title: TString<'static>,
button: TString<'static>,
info_button: TString<'static>,
verb_cancel: Option<TString<'static>>,
items: Obj, // TODO: replace Obj
) -> Result<impl LayoutMaybeTrace, Error>;
fn continue_recovery_homepage(
text: TString<'static>,
subtext: Option<TString<'static>>,

View File

@ -108,18 +108,6 @@ def confirm_total(
"""Transaction summary. Always hold to confirm."""
# rust/src/ui/model_mercury/layout.rs
def confirm_with_info(
*,
title: str,
button: str,
info_button: str,
items: Iterable[tuple[int, str]],
) -> LayoutObj[UiResult]:
"""Confirm given items but with third button. In mercury, the button is placed in
context menu."""
# rust/src/ui/model_mercury/layout.rs
def confirm_more(
*,
@ -350,19 +338,6 @@ def multiple_pages_texts(
"""Show multiple texts, each on its own page."""
# rust/src/ui/model_tr/layout.rs
def confirm_with_info(
*,
title: str,
button: str,
info_button: str, # unused on TR
items: Iterable[Tuple[int, str | bytes]],
verb_cancel: str | None = None,
) -> LayoutObj[UiResult]:
"""Confirm given items but with third button. Always single page
without scrolling."""
# rust/src/ui/model_tr/layout.rs
def confirm_more(
*,
@ -486,18 +461,6 @@ def confirm_total(
"""Transaction summary. Always hold to confirm."""
# rust/src/ui/model_tt/layout.rs
def confirm_with_info(
*,
title: str,
button: str,
info_button: str,
items: Iterable[tuple[int, str | bytes]],
) -> LayoutObj[UiResult]:
"""Confirm given items but with third button. Always single page
without scrolling."""
# rust/src/ui/model_tt/layout.rs
def confirm_more(
*,

View File

@ -163,6 +163,20 @@ def confirm_reset_device(recovery: bool) -> LayoutObj[UiResult]:
"""Confirm TOS before creating wallet creation or wallet recovery."""
# rust/src/ui/api/firmware_upy.rs
def confirm_with_info(
*,
title: str,
button: str,
info_button: str,
verb_cancel: str | None = None,
items: Iterable[tuple[int, str | bytes]],
) -> LayoutObj[UiResult]:
"""Confirm given items but with third button. Always single page
without scrolling. In mercury, the button is placed in
context menu."""
# rust/src/ui/api/firmware_upy.rs
def continue_recovery_homepage(
*,

View File

@ -394,7 +394,7 @@ async def should_show_payment_request_details(
Raises ActionCancelled if the user cancels.
"""
result = await interact(
trezorui2.confirm_with_info(
trezorui_api.confirm_with_info(
title=TR.send__title_sending,
items=[(ui.NORMAL, f"{amount} to\n{recipient_name}")]
+ [(ui.NORMAL, memo) for memo in memos],
@ -431,7 +431,7 @@ async def should_show_more(
confirm = TR.buttons__confirm
result = await interact(
trezorui2.confirm_with_info(
trezorui_api.confirm_with_info(
title=title,
items=para,
button=confirm,

View File

@ -525,11 +525,11 @@ async def should_show_more(
confirm = TR.buttons__confirm
result = await interact(
trezorui2.confirm_with_info(
trezorui_api.confirm_with_info(
title=title,
items=para,
button=confirm,
verb_cancel=verb_cancel, # type: ignore [No parameter named "verb_cancel"]
verb_cancel=verb_cancel,
info_button=button_text, # unused on TR
),
br_name,
@ -732,7 +732,7 @@ async def confirm_value(
send_button_request = True
while True:
result = await interact(
trezorui2.confirm_with_info(
trezorui_api.confirm_with_info(
title=title,
items=((ui.NORMAL, value),),
button=verb or TR.buttons__confirm,

View File

@ -451,7 +451,7 @@ async def should_show_payment_request_details(
Raises ActionCancelled if the user cancels.
"""
result = await interact(
trezorui2.confirm_with_info(
trezorui_api.confirm_with_info(
title=TR.send__title_sending,
items=[(ui.NORMAL, f"{amount} to\n{recipient_name}")]
+ [(ui.NORMAL, memo) for memo in memos],
@ -488,7 +488,7 @@ async def should_show_more(
confirm = TR.buttons__confirm
result = await interact(
trezorui2.confirm_with_info(
trezorui_api.confirm_with_info(
title=title,
items=para,
button=confirm,