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:
parent
4d6af487f4
commit
320fa06122
@ -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;
|
||||
|
@ -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())
|
||||
}
|
||||
|
@ -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(),
|
||||
|
@ -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(),
|
||||
|
@ -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(),
|
||||
|
@ -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."""
|
||||
|
||||
|
@ -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(
|
||||
|
@ -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:
|
||||
|
@ -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(
|
||||
|
@ -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(
|
||||
|
Loading…
Reference in New Issue
Block a user