1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-02-20 11:32:04 +00:00

fix(core/ui): T3T1: prompt screen for confirm_action

[no changelog]
This commit is contained in:
Martin Milata 2024-06-05 13:29:27 +02:00 committed by matejcik
parent 4d6af487f4
commit 320fa06122
10 changed files with 90 additions and 70 deletions

View File

@ -398,6 +398,7 @@ static void _librust_qstrs(void) {
MP_QSTR_progress_event;
MP_QSTR_prompt;
MP_QSTR_prompt_screen;
MP_QSTR_prompt_title;
MP_QSTR_qr_title;
MP_QSTR_reboot_to_bootloader__just_a_moment;
MP_QSTR_reboot_to_bootloader__restart;

View File

@ -141,6 +141,7 @@ fn new_confirm_action_obj(_args: &[Obj], kwargs: &Map) -> Result<Obj, error::Err
let hold: bool = kwargs.get_or(Qstr::MP_QSTR_hold, false)?;
// let hold_danger: bool = kwargs.get_or(Qstr::MP_QSTR_hold_danger, false)?;
let prompt_screen: bool = kwargs.get_or(Qstr::MP_QSTR_prompt_screen, false)?;
let prompt_title: TString = kwargs.get_or(Qstr::MP_QSTR_prompt_title, title)?;
let paragraphs = {
let action = action.unwrap_or("".into());
@ -158,8 +159,27 @@ fn new_confirm_action_obj(_args: &[Obj], kwargs: &Map) -> Result<Obj, error::Err
paragraphs.into_paragraphs()
};
new_confirm_action_simple(
paragraphs,
title,
subtitle,
verb_cancel,
prompt_screen.then_some(prompt_title),
hold,
)
}
#[inline(never)]
pub fn new_confirm_action_simple<T: Component + Paginate + MaybeTrace + 'static>(
content: T,
title: TString<'static>,
subtitle: Option<TString<'static>>,
verb_cancel: Option<TString<'static>>,
prompt_screen: Option<TString<'static>>,
hold: bool,
) -> Result<Obj, error::Error> {
let mut content_intro =
Frame::left_aligned(title, SwipeContent::new(SwipePage::vertical(paragraphs)))
Frame::left_aligned(title, SwipeContent::new(SwipePage::vertical(content)))
.with_menu_button()
.with_footer(TR::instructions__swipe_up.into(), None)
.with_swipe(SwipeDirection::Up, SwipeSettings::default())
@ -170,10 +190,13 @@ fn new_confirm_action_obj(_args: &[Obj], kwargs: &Map) -> Result<Obj, error::Err
content_intro = content_intro.with_subtitle(subtitle);
}
let content_intro = content_intro.map(move |msg| match msg {
FrameMsg::Button(_) => Some(FlowMsg::Info),
_ => None,
});
let prompt_pages: usize = prompt_screen.is_some().into();
let content_intro = content_intro
.map(move |msg| match msg {
FrameMsg::Button(_) => Some(FlowMsg::Info),
_ => None,
})
.with_pages(move |intro_pages| intro_pages + prompt_pages);
let content_menu = if let Some(verb_cancel) = verb_cancel {
Frame::left_aligned(
@ -193,11 +216,7 @@ fn new_confirm_action_obj(_args: &[Obj], kwargs: &Map) -> Result<Obj, error::Err
FrameMsg::Button(_) => Some(FlowMsg::Cancelled),
});
if !prompt_screen && !hold {
let store = flow_store().add(content_intro)?.add(content_menu)?;
let res = SwipeFlow::new(ConfirmActionSimple::Intro, store)?;
Ok(LayoutObj::new(res)?.into())
} else {
if let Some(prompt_title) = prompt_screen {
let (prompt, prompt_action) = if hold {
(
PromptScreen::new_hold_to_confirm(),
@ -210,9 +229,7 @@ fn new_confirm_action_obj(_args: &[Obj], kwargs: &Map) -> Result<Obj, error::Err
)
};
let content_intro = content_intro.with_pages(|p| p + 1);
let mut content_confirm = Frame::left_aligned(title, SwipeContent::new(prompt))
let mut content_confirm = Frame::left_aligned(prompt_title, SwipeContent::new(prompt))
.with_footer(prompt_action, None)
.with_menu_button()
.with_swipe(SwipeDirection::Down, SwipeSettings::default())
@ -233,47 +250,9 @@ fn new_confirm_action_obj(_args: &[Obj], kwargs: &Map) -> Result<Obj, error::Err
.add(content_confirm)?;
let res = SwipeFlow::new(ConfirmAction::Intro, store)?;
Ok(LayoutObj::new(res)?.into())
}
}
pub fn new_confirm_action_simple<T: Component + Paginate + MaybeTrace + 'static>(
content: T,
title: TString<'static>,
subtitle: Option<TString<'static>>,
verb: Option<TString<'static>>,
verb_cancel: Option<TString<'static>>,
) -> Result<Obj, error::Error> {
let mut frame = Frame::left_aligned(title, SwipeContent::new(SwipePage::vertical(content)))
.with_menu_button()
.with_footer(TR::instructions__swipe_up.into(), verb)
.with_swipe(SwipeDirection::Up, SwipeSettings::default())
.with_swipe(SwipeDirection::Left, SwipeSettings::immediate())
.with_vertical_pages();
if let Some(subtitle) = subtitle {
frame = frame.with_subtitle(subtitle)
}
let content_intro =
frame.map(|msg| matches!(msg, FrameMsg::Button(_)).then_some(FlowMsg::Info));
let content_menu = if let Some(verb_cancel) = verb_cancel {
Frame::left_aligned(
"".into(),
VerticalMenu::empty().danger(theme::ICON_CANCEL, verb_cancel),
)
} else {
Frame::left_aligned(
"".into(),
VerticalMenu::empty().danger(theme::ICON_CANCEL, TR::buttons__cancel.into()),
)
let store = flow_store().add(content_intro)?.add(content_menu)?;
let res = SwipeFlow::new(ConfirmActionSimple::Intro, store)?;
Ok(LayoutObj::new(res)?.into())
}
.with_cancel_button()
.with_swipe(SwipeDirection::Right, SwipeSettings::immediate())
.map(move |msg| match msg {
FrameMsg::Content(VerticalMenuChoiceMsg::Selected(i)) => Some(FlowMsg::Choice(i)),
FrameMsg::Button(_) => Some(FlowMsg::Cancelled),
});
let store = flow_store().add(content_intro)?.add(content_menu)?;
let res = SwipeFlow::new(ConfirmActionSimple::Intro, store)?;
Ok(LayoutObj::new(res)?.into())
}

View File

@ -271,10 +271,6 @@ impl ComponentMsgObj for super::component::bl_confirm::Confirm<'_> {
extern "C" fn new_confirm_emphasized(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 verb: Option<TString> = kwargs
.get(Qstr::MP_QSTR_verb)
.unwrap_or_else(|_| Obj::const_none())
.try_into_option()?;
let items: Obj = kwargs.get(Qstr::MP_QSTR_items)?;
let mut ops = OpTextLayout::new(theme::TEXT_NORMAL);
@ -296,8 +292,9 @@ extern "C" fn new_confirm_emphasized(n_args: usize, args: *const Obj, kwargs: *m
FormattedText::new(ops).vertically_centered(),
title,
None,
verb,
None,
Some(title),
false,
)
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
@ -312,6 +309,7 @@ struct ConfirmBlobParams {
verb: Option<TString<'static>>,
verb_cancel: Option<TString<'static>>,
info_button: bool,
prompt: bool,
hold: bool,
chunkify: bool,
text_mono: bool,
@ -324,6 +322,7 @@ impl ConfirmBlobParams {
description: Option<TString<'static>>,
verb: Option<TString<'static>>,
verb_cancel: Option<TString<'static>>,
prompt: bool,
hold: bool,
) -> Self {
Self {
@ -335,6 +334,7 @@ impl ConfirmBlobParams {
verb,
verb_cancel,
info_button: false,
prompt,
hold,
chunkify: false,
text_mono: true,
@ -388,8 +388,9 @@ impl ConfirmBlobParams {
paragraphs,
self.title,
self.subtitle,
self.verb,
self.verb_cancel,
self.prompt.then_some(self.title),
self.hold,
)
}
}
@ -414,11 +415,20 @@ extern "C" fn new_confirm_blob(n_args: usize, args: *const Obj, kwargs: *mut Map
.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 prompt_screen: bool = kwargs.get_or(Qstr::MP_QSTR_prompt_screen, true)?;
ConfirmBlobParams::new(title, data, description, verb, verb_cancel, hold)
.with_extra(extra)
.with_chunkify(chunkify)
.into_flow()
ConfirmBlobParams::new(
title,
data,
description,
verb,
verb_cancel,
prompt_screen,
hold,
)
.with_extra(extra)
.with_chunkify(chunkify)
.into_flow()
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
@ -449,7 +459,7 @@ extern "C" fn new_confirm_address(n_args: usize, args: *const Obj, kwargs: *mut
}
.into_paragraphs();
flow::new_confirm_action_simple(paragraphs, title, None, None, None)
flow::new_confirm_action_simple(paragraphs, title, None, None, None, false)
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
@ -457,7 +467,7 @@ extern "C" fn new_confirm_address(n_args: usize, args: *const Obj, kwargs: *mut
extern "C" fn new_confirm_properties(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
let block = move |_args: &[Obj], kwargs: &Map| {
let title: TString = kwargs.get(Qstr::MP_QSTR_title)?.try_into()?;
let _hold: bool = kwargs.get_or(Qstr::MP_QSTR_hold, false)?; // FIXME
let hold: bool = kwargs.get_or(Qstr::MP_QSTR_hold, false)?;
let items: Obj = kwargs.get(Qstr::MP_QSTR_items)?;
let paragraphs = PropsList::new(
@ -471,8 +481,9 @@ extern "C" fn new_confirm_properties(n_args: usize, args: *const Obj, kwargs: *m
paragraphs.into_paragraphs(),
title,
None,
Some(TR::buttons__confirm.into()),
None,
hold.then_some(title),
hold,
)
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
@ -579,7 +590,7 @@ extern "C" fn new_confirm_value(n_args: usize, args: *const Obj, kwargs: *mut Ma
let chunkify: bool = kwargs.get_or(Qstr::MP_QSTR_chunkify, false)?;
let text_mono: bool = kwargs.get_or(Qstr::MP_QSTR_text_mono, true)?;
ConfirmBlobParams::new(title, value, description, verb, verb_cancel, hold)
ConfirmBlobParams::new(title, value, description, verb, verb_cancel, hold, hold)
.with_subtitle(subtitle)
.with_info_button(info_button)
.with_chunkify(chunkify)
@ -900,8 +911,14 @@ extern "C" fn new_confirm_coinjoin(n_args: usize, args: *const Obj, kwargs: *mut
Paragraph::new(&theme::TEXT_MONO, max_feerate),
]);
// FIXME: hold
flow::new_confirm_action_simple(paragraphs, TR::coinjoin__title.into(), None, None, None)
flow::new_confirm_action_simple(
paragraphs,
TR::coinjoin__title.into(),
None,
None,
Some(TR::coinjoin__title.into()),
true,
)
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
}
@ -1367,6 +1384,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// hold_danger: bool = False,
/// reverse: bool = False,
/// prompt_screen: bool = False,
/// prompt_title: str | None = None,
/// ) -> LayoutObj[UiResult]:
/// """Confirm action."""
Qstr::MP_QSTR_confirm_action => obj_fn_kw!(0, flow::confirm_action::new_confirm_action).as_obj(),
@ -1399,6 +1417,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// verb_cancel: str | None = None,
/// hold: bool = False,
/// chunkify: bool = False,
/// prompt_screen: bool = False,
/// ) -> LayoutObj[UiResult]:
/// """Confirm byte sequence data."""
Qstr::MP_QSTR_confirm_blob => obj_fn_kw!(0, new_confirm_blob).as_obj(),

View File

@ -1652,6 +1652,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// hold_danger: bool = False, # unused on TR
/// reverse: bool = False,
/// prompt_screen: bool = False,
/// prompt_title: str | None = None,
/// ) -> LayoutObj[UiResult]:
/// """Confirm action."""
Qstr::MP_QSTR_confirm_action => obj_fn_kw!(0, new_confirm_action).as_obj(),
@ -1674,6 +1675,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// verb_cancel: str | None = None,
/// hold: bool = False,
/// chunkify: bool = False,
/// prompt_screen: bool = False,
/// ) -> LayoutObj[UiResult]:
/// """Confirm byte sequence data."""
Qstr::MP_QSTR_confirm_blob => obj_fn_kw!(0, new_confirm_blob).as_obj(),

View File

@ -1721,6 +1721,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// hold_danger: bool = False,
/// reverse: bool = False,
/// prompt_screen: bool = False,
/// prompt_title: str | None = None,
/// ) -> LayoutObj[UiResult]:
/// """Confirm action."""
Qstr::MP_QSTR_confirm_action => obj_fn_kw!(0, new_confirm_action).as_obj(),
@ -1753,6 +1754,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// verb_cancel: str | None = None,
/// hold: bool = False,
/// chunkify: bool = False,
/// prompt_screen: bool = False,
/// ) -> LayoutObj[UiResult]:
/// """Confirm byte sequence data."""
Qstr::MP_QSTR_confirm_blob => obj_fn_kw!(0, new_confirm_blob).as_obj(),

View File

@ -85,6 +85,7 @@ def confirm_action(
hold_danger: bool = False,
reverse: bool = False,
prompt_screen: bool = False,
prompt_title: str | None = None,
) -> LayoutObj[UiResult]:
"""Confirm action."""
@ -120,6 +121,7 @@ def confirm_blob(
verb_cancel: str | None = None,
hold: bool = False,
chunkify: bool = False,
prompt_screen: bool = False,
) -> LayoutObj[UiResult]:
"""Confirm byte sequence data."""
@ -632,6 +634,7 @@ def confirm_action(
hold_danger: bool = False, # unused on TR
reverse: bool = False,
prompt_screen: bool = False,
prompt_title: str | None = None,
) -> LayoutObj[UiResult]:
"""Confirm action."""
@ -656,6 +659,7 @@ def confirm_blob(
verb_cancel: str | None = None,
hold: bool = False,
chunkify: bool = False,
prompt_screen: bool = False,
) -> LayoutObj[UiResult]:
"""Confirm byte sequence data."""
@ -1160,6 +1164,7 @@ def confirm_action(
hold_danger: bool = False,
reverse: bool = False,
prompt_screen: bool = False,
prompt_title: str | None = None,
) -> LayoutObj[UiResult]:
"""Confirm action."""
@ -1195,6 +1200,7 @@ def confirm_blob(
verb_cancel: str | None = None,
hold: bool = False,
chunkify: bool = False,
prompt_screen: bool = False,
) -> LayoutObj[UiResult]:
"""Confirm byte sequence data."""

View File

@ -63,6 +63,8 @@ async def _request_on_host() -> str:
"passphrase_host1_hidden",
TR.passphrase__hidden_wallet,
description=TR.passphrase__from_host_not_shown,
prompt_screen=True,
prompt_title=TR.passphrase__access_hidden_wallet,
)
else:
await confirm_action(

View File

@ -296,6 +296,7 @@ async def confirm_action(
exc: ExceptionType = ActionCancelled,
br_code: ButtonRequestType = BR_TYPE_OTHER,
prompt_screen: bool = False,
prompt_title: str | None = None,
) -> None:
if description is not None and description_param is not None:
description = description.format(description_param)
@ -314,6 +315,7 @@ async def confirm_action(
hold_danger=hold_danger,
reverse=reverse,
prompt_screen=prompt_screen,
prompt_title=prompt_title or title,
)
),
br_type,
@ -727,6 +729,7 @@ async def confirm_blob(
br_code: ButtonRequestType = BR_TYPE_OTHER,
ask_pagination: bool = False,
chunkify: bool = False,
prompt_screen: bool = True,
) -> None:
layout = RustLayout(
trezorui2.confirm_blob(
@ -738,6 +741,7 @@ async def confirm_blob(
verb=verb,
verb_cancel=verb_cancel,
chunkify=chunkify,
prompt_screen=prompt_screen,
)
)
@ -987,6 +991,7 @@ if not utils.BITCOIN_ONLY:
recipient,
verb=TR.buttons__continue,
chunkify=chunkify,
prompt_screen=False,
)
try:

View File

@ -387,6 +387,7 @@ def confirm_action(
exc: ExceptionType = ActionCancelled,
br_code: ButtonRequestType = BR_TYPE_OTHER,
prompt_screen: bool = False,
prompt_title: str | None = None,
) -> Awaitable[None]:
verb = verb or TR.buttons__confirm # def_arg
if description is not None and description_param is not None:
@ -860,6 +861,7 @@ def confirm_blob(
br_code: ButtonRequestType = BR_TYPE_OTHER,
ask_pagination: bool = False,
chunkify: bool = False,
prompt_screen: bool = True,
) -> Awaitable[None]:
verb = verb or TR.buttons__confirm # def_arg
layout = RustLayout(

View File

@ -302,6 +302,7 @@ def confirm_action(
exc: ExceptionType = ActionCancelled,
br_code: ButtonRequestType = BR_TYPE_OTHER,
prompt_screen: bool = False,
prompt_title: str | None = None,
) -> Awaitable[None]:
if description is not None and description_param is not None:
description = description.format(description_param)
@ -825,6 +826,7 @@ def confirm_blob(
br_code: ButtonRequestType = BR_TYPE_OTHER,
ask_pagination: bool = False,
chunkify: bool = False,
prompt_screen: bool = True,
) -> Awaitable[None]:
verb = verb or TR.buttons__confirm # def_arg
layout = RustLayout(