mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-22 07:28:10 +00:00
feat(core/ui): add cancel button to paginated blobs
[no changelog]
This commit is contained in:
parent
8313c30d5a
commit
2bc787a652
@ -174,6 +174,7 @@ static void _librust_qstrs(void) {
|
||||
MP_QSTR_buttons__turn_on;
|
||||
MP_QSTR_buttons__view_all_data;
|
||||
MP_QSTR_can_go_back;
|
||||
MP_QSTR_cancel;
|
||||
MP_QSTR_cancel_arrow;
|
||||
MP_QSTR_cancel_cross;
|
||||
MP_QSTR_cancel_text;
|
||||
|
@ -25,94 +25,20 @@ use super::super::{
|
||||
theme,
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub enum ConfirmAction {
|
||||
Intro,
|
||||
Menu,
|
||||
Confirm,
|
||||
}
|
||||
const MENU_ITEM_CANCEL: usize = 0;
|
||||
const MENU_ITEM_INFO: usize = 1;
|
||||
|
||||
impl FlowController for ConfirmAction {
|
||||
fn index(&'static self) -> usize {
|
||||
*self as usize
|
||||
}
|
||||
|
||||
fn handle_swipe(&'static self, direction: Direction) -> Decision {
|
||||
match (self, direction) {
|
||||
(Self::Intro, Direction::Left) => Self::Menu.swipe(direction),
|
||||
(Self::Menu, Direction::Right) => Self::Intro.swipe(direction),
|
||||
(Self::Intro, Direction::Up) => Self::Confirm.swipe(direction),
|
||||
(Self::Confirm, Direction::Down) => Self::Intro.swipe(direction),
|
||||
(Self::Confirm, Direction::Left) => Self::Menu.swipe(direction),
|
||||
_ => self.do_nothing(),
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
|
||||
match (self, msg) {
|
||||
(Self::Intro, FlowMsg::Info) => Self::Menu.goto(),
|
||||
(Self::Menu, FlowMsg::Cancelled) => Self::Intro.swipe_right(),
|
||||
(Self::Menu, FlowMsg::Choice(0)) => self.return_msg(FlowMsg::Cancelled),
|
||||
(Self::Menu, FlowMsg::Choice(1)) => self.return_msg(FlowMsg::Info),
|
||||
(Self::Confirm, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Confirmed),
|
||||
(Self::Confirm, FlowMsg::Info) => Self::Menu.goto(),
|
||||
_ => self.do_nothing(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// ConfirmAction flow without a separate "Tap to confirm" or "Hold to confirm"
|
||||
/// screen. Swiping up directly from the intro screen confirms action.
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub enum ConfirmActionSimple {
|
||||
Intro,
|
||||
Menu,
|
||||
}
|
||||
|
||||
impl FlowController for ConfirmActionSimple {
|
||||
#[inline]
|
||||
fn index(&'static self) -> usize {
|
||||
*self as usize
|
||||
}
|
||||
|
||||
fn handle_swipe(&'static self, direction: Direction) -> Decision {
|
||||
match (self, direction) {
|
||||
(Self::Intro, Direction::Left) => Self::Menu.swipe(direction),
|
||||
(Self::Menu, Direction::Right) => Self::Intro.swipe(direction),
|
||||
(Self::Intro, Direction::Up) => self.return_msg(FlowMsg::Confirmed),
|
||||
_ => self.do_nothing(),
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
|
||||
match (self, msg) {
|
||||
(Self::Intro, FlowMsg::Info) => Self::Menu.goto(),
|
||||
(Self::Menu, FlowMsg::Cancelled) => Self::Intro.swipe_right(),
|
||||
(Self::Menu, FlowMsg::Choice(0)) => self.return_msg(FlowMsg::Cancelled),
|
||||
(Self::Menu, FlowMsg::Choice(1)) => self.return_msg(FlowMsg::Info),
|
||||
_ => self.do_nothing(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ConfirmActionMenu {
|
||||
verb_cancel: Option<TString<'static>>,
|
||||
info: bool,
|
||||
verb_info: Option<TString<'static>>,
|
||||
}
|
||||
|
||||
impl ConfirmActionMenu {
|
||||
pub fn new(
|
||||
// Extra button at the top-right corner of the Action screen
|
||||
#[derive(PartialEq)]
|
||||
pub enum ConfirmActionExtra {
|
||||
// Opens a menu which can (optionally) lead to an extra Info screen, or cancel the action
|
||||
Menu {
|
||||
verb_cancel: Option<TString<'static>>,
|
||||
info: bool,
|
||||
has_info: bool,
|
||||
verb_info: Option<TString<'static>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
verb_cancel,
|
||||
info,
|
||||
verb_info,
|
||||
}
|
||||
}
|
||||
},
|
||||
// Shows a cancel button directly
|
||||
Cancel,
|
||||
}
|
||||
|
||||
pub struct ConfirmActionStrings {
|
||||
@ -138,6 +64,106 @@ impl ConfirmActionStrings {
|
||||
}
|
||||
}
|
||||
|
||||
/// The simplest form of the ConfirmAction flow:
|
||||
/// no menu, nor a separate "Tap to confirm" or "Hold to confirm".
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
enum ConfirmAction {
|
||||
Action,
|
||||
}
|
||||
|
||||
impl FlowController for ConfirmAction {
|
||||
#[inline]
|
||||
fn index(&'static self) -> usize {
|
||||
*self as usize
|
||||
}
|
||||
|
||||
fn handle_swipe(&'static self, direction: Direction) -> Decision {
|
||||
match (self, direction) {
|
||||
(Self::Action, Direction::Up) => self.return_msg(FlowMsg::Confirmed),
|
||||
_ => self.do_nothing(),
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
|
||||
match (self, msg) {
|
||||
(Self::Action, FlowMsg::Cancelled) => self.return_msg(FlowMsg::Cancelled),
|
||||
_ => self.do_nothing(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A ConfirmAction flow with a menu which can contain various items
|
||||
/// as defined by ConfirmActionExtra::Menu.
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
enum ConfirmActionWithMenu {
|
||||
Action,
|
||||
Menu,
|
||||
}
|
||||
|
||||
impl FlowController for ConfirmActionWithMenu {
|
||||
#[inline]
|
||||
fn index(&'static self) -> usize {
|
||||
*self as usize
|
||||
}
|
||||
|
||||
fn handle_swipe(&'static self, direction: Direction) -> Decision {
|
||||
match (self, direction) {
|
||||
(Self::Action, Direction::Left) => Self::Menu.swipe(direction),
|
||||
(Self::Menu, Direction::Right) => Self::Action.swipe(direction),
|
||||
(Self::Action, Direction::Up) => self.return_msg(FlowMsg::Confirmed),
|
||||
_ => self.do_nothing(),
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
|
||||
match (self, msg) {
|
||||
(Self::Action, FlowMsg::Info) => Self::Menu.goto(),
|
||||
(Self::Menu, FlowMsg::Cancelled) => Self::Action.swipe_right(),
|
||||
(Self::Menu, FlowMsg::Choice(MENU_ITEM_CANCEL)) => self.return_msg(FlowMsg::Cancelled),
|
||||
(Self::Menu, FlowMsg::Choice(MENU_ITEM_INFO)) => self.return_msg(FlowMsg::Info),
|
||||
_ => self.do_nothing(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A ConfirmAction flow with a menu and
|
||||
// a separate "Tap to confirm" or "Hold to confirm" screen.
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
enum ConfirmActionWithMenuAndConfirmation {
|
||||
Action,
|
||||
Menu,
|
||||
Confirmation,
|
||||
}
|
||||
|
||||
impl FlowController for ConfirmActionWithMenuAndConfirmation {
|
||||
fn index(&'static self) -> usize {
|
||||
*self as usize
|
||||
}
|
||||
|
||||
fn handle_swipe(&'static self, direction: Direction) -> Decision {
|
||||
match (self, direction) {
|
||||
(Self::Action, Direction::Left) => Self::Menu.swipe(direction),
|
||||
(Self::Menu, Direction::Right) => Self::Action.swipe(direction),
|
||||
(Self::Action, Direction::Up) => Self::Confirmation.swipe(direction),
|
||||
(Self::Confirmation, Direction::Down) => Self::Action.swipe(direction),
|
||||
(Self::Confirmation, Direction::Left) => Self::Menu.swipe(direction),
|
||||
_ => self.do_nothing(),
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_event(&'static self, msg: FlowMsg) -> Decision {
|
||||
match (self, msg) {
|
||||
(Self::Action, FlowMsg::Info) => Self::Menu.goto(),
|
||||
(Self::Menu, FlowMsg::Cancelled) => Self::Action.swipe_right(),
|
||||
(Self::Menu, FlowMsg::Choice(MENU_ITEM_CANCEL)) => self.return_msg(FlowMsg::Cancelled),
|
||||
(Self::Menu, FlowMsg::Choice(MENU_ITEM_INFO)) => self.return_msg(FlowMsg::Info),
|
||||
(Self::Confirmation, FlowMsg::Confirmed) => self.return_msg(FlowMsg::Confirmed),
|
||||
(Self::Confirmation, FlowMsg::Info) => Self::Menu.goto(),
|
||||
_ => self.do_nothing(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new_confirm_action(
|
||||
title: TString<'static>,
|
||||
@ -168,7 +194,11 @@ pub fn new_confirm_action(
|
||||
|
||||
new_confirm_action_simple(
|
||||
paragraphs,
|
||||
ConfirmActionMenu::new(verb_cancel, false, None),
|
||||
ConfirmActionExtra::Menu {
|
||||
verb_cancel,
|
||||
has_info: false,
|
||||
verb_info: None,
|
||||
},
|
||||
ConfirmActionStrings::new(title, subtitle, None, prompt_screen.then_some(prompt_title)),
|
||||
hold,
|
||||
None,
|
||||
@ -179,21 +209,29 @@ pub fn new_confirm_action(
|
||||
#[inline(never)]
|
||||
fn new_confirm_action_uni<T: Component + Paginate + MaybeTrace + 'static>(
|
||||
content: SwipeContent<SwipePage<T>>,
|
||||
menu: ConfirmActionMenu,
|
||||
extra: ConfirmActionExtra,
|
||||
strings: ConfirmActionStrings,
|
||||
hold: bool,
|
||||
show_page_counter: bool,
|
||||
) -> Result<SwipeFlow, error::Error> {
|
||||
let (prompt_screen, prompt_pages, flow, page) =
|
||||
create_flow(strings.title, strings.prompt_screen, hold);
|
||||
create_flow(strings.title, strings.prompt_screen, hold, &extra);
|
||||
|
||||
let mut content_intro = Frame::left_aligned(strings.title, content)
|
||||
let mut content = Frame::left_aligned(strings.title, content)
|
||||
.with_swipe(Direction::Up, SwipeSettings::default())
|
||||
.with_swipe(Direction::Left, SwipeSettings::default())
|
||||
.with_vertical_pages()
|
||||
.with_menu_button()
|
||||
.with_footer(TR::instructions__swipe_up.into(), None);
|
||||
|
||||
match extra {
|
||||
ConfirmActionExtra::Menu { .. } => {
|
||||
content = content.with_menu_button();
|
||||
}
|
||||
ConfirmActionExtra::Cancel => {
|
||||
content = content.with_cancel_button();
|
||||
}
|
||||
}
|
||||
|
||||
if show_page_counter {
|
||||
fn footer_update_fn<T: Component + Paginate>(
|
||||
content: &SwipeContent<SwipePage<T>>,
|
||||
@ -205,26 +243,25 @@ fn new_confirm_action_uni<T: Component + Paginate + MaybeTrace + 'static>(
|
||||
footer.update_page_counter(ctx, current_page, page_count);
|
||||
}
|
||||
|
||||
content_intro = content_intro
|
||||
content = content
|
||||
.with_footer_counter(TR::instructions__swipe_up.into())
|
||||
.register_footer_update_fn(footer_update_fn::<T>);
|
||||
}
|
||||
|
||||
if let Some(subtitle) = strings.subtitle {
|
||||
content_intro = content_intro.with_subtitle(subtitle);
|
||||
content = content.with_subtitle(subtitle);
|
||||
}
|
||||
|
||||
let content_intro = content_intro
|
||||
let content = content
|
||||
.map(move |msg| match msg {
|
||||
FrameMsg::Button(_) => Some(FlowMsg::Info),
|
||||
FrameMsg::Button(FlowMsg::Info) => Some(FlowMsg::Info),
|
||||
FrameMsg::Button(FlowMsg::Cancelled) => Some(FlowMsg::Cancelled),
|
||||
_ => None,
|
||||
})
|
||||
.with_pages(move |intro_pages| intro_pages + prompt_pages);
|
||||
|
||||
let flow = flow?.with_page(page, content_intro)?;
|
||||
|
||||
let flow = create_menu(flow, menu, prompt_screen)?;
|
||||
|
||||
let flow = flow?.with_page(page, content)?;
|
||||
let flow = create_menu(flow, extra, prompt_screen)?;
|
||||
let flow = create_confirm(flow, strings.subtitle, hold, prompt_screen)?;
|
||||
|
||||
Ok(flow)
|
||||
@ -234,6 +271,7 @@ fn create_flow(
|
||||
title: TString<'static>,
|
||||
prompt_screen: Option<TString<'static>>,
|
||||
hold: bool,
|
||||
extra: &ConfirmActionExtra,
|
||||
) -> (
|
||||
Option<TString<'static>>,
|
||||
usize,
|
||||
@ -242,53 +280,69 @@ fn create_flow(
|
||||
) {
|
||||
let prompt_screen = prompt_screen.or_else(|| hold.then_some(title));
|
||||
let prompt_pages: usize = prompt_screen.is_some().into();
|
||||
|
||||
let (flow, page): (Result<SwipeFlow, Error>, &dyn FlowController) = if prompt_screen.is_some() {
|
||||
(SwipeFlow::new(&ConfirmAction::Intro), &ConfirmAction::Intro)
|
||||
} else {
|
||||
(
|
||||
SwipeFlow::new(&ConfirmActionSimple::Intro),
|
||||
&ConfirmActionSimple::Intro,
|
||||
)
|
||||
let initial_page: &dyn FlowController = match (extra, prompt_screen.is_some()) {
|
||||
(ConfirmActionExtra::Menu { .. }, false) => &ConfirmActionWithMenu::Action,
|
||||
(ConfirmActionExtra::Menu { .. }, true) => &ConfirmActionWithMenuAndConfirmation::Action,
|
||||
_ => &ConfirmAction::Action,
|
||||
};
|
||||
|
||||
(prompt_screen, prompt_pages, flow, page)
|
||||
(
|
||||
prompt_screen,
|
||||
prompt_pages,
|
||||
SwipeFlow::new(initial_page),
|
||||
initial_page,
|
||||
)
|
||||
}
|
||||
|
||||
fn create_menu(
|
||||
flow: SwipeFlow,
|
||||
menu: ConfirmActionMenu,
|
||||
extra: ConfirmActionExtra,
|
||||
prompt_screen: Option<TString<'static>>,
|
||||
) -> Result<SwipeFlow, Error> {
|
||||
let mut menu_choices = VerticalMenu::empty().danger(
|
||||
theme::ICON_CANCEL,
|
||||
menu.verb_cancel.unwrap_or(TR::buttons__cancel.into()),
|
||||
);
|
||||
|
||||
if menu.info {
|
||||
menu_choices = menu_choices.item(
|
||||
theme::ICON_CHEVRON_RIGHT,
|
||||
menu.verb_info
|
||||
.unwrap_or(TR::words__title_information.into()),
|
||||
if let ConfirmActionExtra::Menu {
|
||||
verb_cancel,
|
||||
has_info,
|
||||
verb_info,
|
||||
} = extra
|
||||
{
|
||||
// NB: The Cancel menu item is always the first,
|
||||
// because of the MENU_ITEM_CANCEL = 0.
|
||||
// If we want the cancel item to be somewhere else,
|
||||
// we would need to account for that and we could not use a constant.
|
||||
let mut menu_choices = VerticalMenu::empty().danger(
|
||||
theme::ICON_CANCEL,
|
||||
verb_cancel.unwrap_or(TR::buttons__cancel.into()),
|
||||
);
|
||||
}
|
||||
|
||||
let content_menu = Frame::left_aligned("".into(), menu_choices)
|
||||
.with_cancel_button()
|
||||
.with_swipe(Direction::Right, SwipeSettings::immediate());
|
||||
if has_info {
|
||||
// The Info menu item (if present) has to be the 2nd,
|
||||
// because of MENU_ITEM_INFO = 1!
|
||||
menu_choices = menu_choices.item(
|
||||
theme::ICON_CHEVRON_RIGHT,
|
||||
verb_info.unwrap_or(TR::words__title_information.into()),
|
||||
);
|
||||
}
|
||||
|
||||
let content_menu = content_menu.map(move |msg| match msg {
|
||||
FrameMsg::Content(VerticalMenuChoiceMsg::Selected(i)) => Some(FlowMsg::Choice(i)),
|
||||
FrameMsg::Button(_) => Some(FlowMsg::Cancelled),
|
||||
});
|
||||
let content_menu = Frame::left_aligned("".into(), menu_choices)
|
||||
.with_cancel_button()
|
||||
.with_swipe(Direction::Right, SwipeSettings::immediate());
|
||||
|
||||
if prompt_screen.is_some() {
|
||||
flow.with_page(&ConfirmAction::Menu, content_menu)
|
||||
let content_menu = content_menu.map(move |msg| match msg {
|
||||
FrameMsg::Content(VerticalMenuChoiceMsg::Selected(i)) => Some(FlowMsg::Choice(i)),
|
||||
FrameMsg::Button(_) => Some(FlowMsg::Cancelled),
|
||||
});
|
||||
|
||||
if prompt_screen.is_some() {
|
||||
flow.with_page(&ConfirmActionWithMenuAndConfirmation::Menu, content_menu)
|
||||
} else {
|
||||
flow.with_page(&ConfirmActionWithMenu::Menu, content_menu)
|
||||
}
|
||||
} else {
|
||||
flow.with_page(&ConfirmActionSimple::Menu, content_menu)
|
||||
Ok(flow) // no menu being added
|
||||
}
|
||||
}
|
||||
|
||||
// Create the extra confirmation screen (optional).
|
||||
fn create_confirm(
|
||||
flow: SwipeFlow,
|
||||
subtitle: Option<TString<'static>>,
|
||||
@ -324,7 +378,10 @@ fn create_confirm(
|
||||
_ => None,
|
||||
});
|
||||
|
||||
flow.with_page(&ConfirmAction::Confirm, content_confirm)
|
||||
flow.with_page(
|
||||
&ConfirmActionWithMenuAndConfirmation::Confirmation,
|
||||
content_confirm,
|
||||
)
|
||||
} else {
|
||||
Ok(flow)
|
||||
}
|
||||
@ -333,7 +390,7 @@ fn create_confirm(
|
||||
#[inline(never)]
|
||||
pub fn new_confirm_action_simple<T: Component + Paginate + MaybeTrace + 'static>(
|
||||
content: T,
|
||||
menu: ConfirmActionMenu,
|
||||
extra: ConfirmActionExtra,
|
||||
strings: ConfirmActionStrings,
|
||||
hold: bool,
|
||||
page_limit: Option<usize>,
|
||||
@ -341,7 +398,7 @@ pub fn new_confirm_action_simple<T: Component + Paginate + MaybeTrace + 'static>
|
||||
) -> Result<SwipeFlow, error::Error> {
|
||||
new_confirm_action_uni(
|
||||
SwipeContent::new(SwipePage::vertical(content).with_limit(page_limit)),
|
||||
menu,
|
||||
extra,
|
||||
strings,
|
||||
hold,
|
||||
show_page_counter,
|
||||
|
@ -19,7 +19,7 @@ pub mod util;
|
||||
pub mod warning_hi_prio;
|
||||
|
||||
pub use confirm_action::{
|
||||
new_confirm_action, new_confirm_action_simple, ConfirmActionMenu, ConfirmActionStrings,
|
||||
new_confirm_action, new_confirm_action_simple, ConfirmActionExtra, ConfirmActionStrings,
|
||||
};
|
||||
#[cfg(feature = "universal_fw")]
|
||||
pub use confirm_fido::new_confirm_fido;
|
||||
|
@ -3,7 +3,7 @@ use super::{
|
||||
component::{Frame, FrameMsg},
|
||||
theme,
|
||||
},
|
||||
ConfirmActionMenu, ConfirmActionStrings,
|
||||
ConfirmActionExtra, ConfirmActionStrings,
|
||||
};
|
||||
use crate::{
|
||||
error::Error,
|
||||
@ -52,6 +52,7 @@ pub struct ConfirmBlobParams {
|
||||
swipe_up: bool,
|
||||
swipe_down: bool,
|
||||
swipe_right: bool,
|
||||
cancel: bool,
|
||||
}
|
||||
|
||||
impl ConfirmBlobParams {
|
||||
@ -84,6 +85,7 @@ impl ConfirmBlobParams {
|
||||
swipe_up: false,
|
||||
swipe_down: false,
|
||||
swipe_right: false,
|
||||
cancel: false,
|
||||
}
|
||||
}
|
||||
|
||||
@ -152,6 +154,11 @@ impl ConfirmBlobParams {
|
||||
self
|
||||
}
|
||||
|
||||
pub const fn with_cancel(mut self, cancel: bool) -> Self {
|
||||
self.cancel = cancel;
|
||||
self
|
||||
}
|
||||
|
||||
pub const fn with_footer(
|
||||
mut self,
|
||||
instruction: TString<'static>,
|
||||
@ -262,9 +269,19 @@ impl ConfirmBlobParams {
|
||||
}
|
||||
.into_paragraphs();
|
||||
|
||||
let confirm_extra = if self.cancel {
|
||||
ConfirmActionExtra::Cancel
|
||||
} else {
|
||||
ConfirmActionExtra::Menu {
|
||||
verb_cancel: self.verb_cancel,
|
||||
has_info: self.info_button,
|
||||
verb_info: self.verb_info,
|
||||
}
|
||||
};
|
||||
|
||||
flow::new_confirm_action_simple(
|
||||
paragraphs,
|
||||
ConfirmActionMenu::new(self.verb_cancel, self.info_button, self.verb_info),
|
||||
confirm_extra,
|
||||
ConfirmActionStrings::new(
|
||||
self.title,
|
||||
self.subtitle,
|
||||
|
@ -55,7 +55,7 @@ use crate::{
|
||||
flow::{
|
||||
new_confirm_action_simple,
|
||||
util::{ConfirmBlobParams, ShowInfoParams},
|
||||
ConfirmActionMenu, ConfirmActionStrings,
|
||||
ConfirmActionExtra, ConfirmActionStrings,
|
||||
},
|
||||
theme::ICON_BULLET_CHECKMARK,
|
||||
},
|
||||
@ -246,7 +246,11 @@ extern "C" fn new_confirm_emphasized(n_args: usize, args: *const Obj, kwargs: *m
|
||||
|
||||
new_confirm_action_simple(
|
||||
FormattedText::new(ops).vertically_centered(),
|
||||
ConfirmActionMenu::new(None, false, None),
|
||||
ConfirmActionExtra::Menu {
|
||||
verb_cancel: None,
|
||||
has_info: false,
|
||||
verb_info: None,
|
||||
},
|
||||
ConfirmActionStrings::new(title, None, None, Some(title)),
|
||||
false,
|
||||
None,
|
||||
@ -296,6 +300,7 @@ extern "C" fn new_confirm_blob(n_args: usize, args: *const Obj, kwargs: *mut Map
|
||||
.get(Qstr::MP_QSTR_page_limit)
|
||||
.unwrap_or_else(|_| Obj::const_none())
|
||||
.try_into_option()?;
|
||||
let cancel: bool = kwargs.get_or(Qstr::MP_QSTR_cancel, false)?;
|
||||
|
||||
let (description, description_font) = if page_limit == Some(1) {
|
||||
(
|
||||
@ -318,6 +323,7 @@ extern "C" fn new_confirm_blob(n_args: usize, args: *const Obj, kwargs: *mut Map
|
||||
.with_chunkify(chunkify)
|
||||
.with_page_counter(page_counter)
|
||||
.with_page_limit(page_limit)
|
||||
.with_cancel(cancel)
|
||||
.with_prompt(prompt_screen)
|
||||
.with_hold(hold)
|
||||
.into_flow()
|
||||
@ -389,7 +395,11 @@ extern "C" fn new_confirm_address(n_args: usize, args: *const Obj, kwargs: *mut
|
||||
|
||||
flow::new_confirm_action_simple(
|
||||
paragraphs,
|
||||
ConfirmActionMenu::new(None, false, None),
|
||||
ConfirmActionExtra::Menu {
|
||||
verb_cancel: None,
|
||||
has_info: false,
|
||||
verb_info: None,
|
||||
},
|
||||
ConfirmActionStrings::new(title, None, None, None),
|
||||
false,
|
||||
None,
|
||||
@ -432,7 +442,11 @@ extern "C" fn new_confirm_properties(n_args: usize, args: *const Obj, kwargs: *m
|
||||
|
||||
new_confirm_action_simple(
|
||||
paragraphs.into_paragraphs(),
|
||||
ConfirmActionMenu::new(None, false, None),
|
||||
ConfirmActionExtra::Menu {
|
||||
verb_cancel: None,
|
||||
has_info: false,
|
||||
verb_info: None,
|
||||
},
|
||||
ConfirmActionStrings::new(title, None, None, hold.then_some(title)),
|
||||
hold,
|
||||
None,
|
||||
@ -462,7 +476,11 @@ extern "C" fn new_confirm_homescreen(n_args: usize, args: *const Obj, kwargs: *m
|
||||
|
||||
new_confirm_action_simple(
|
||||
paragraphs,
|
||||
ConfirmActionMenu::new(None, false, None),
|
||||
ConfirmActionExtra::Menu {
|
||||
verb_cancel: None,
|
||||
has_info: false,
|
||||
verb_info: None,
|
||||
},
|
||||
ConfirmActionStrings::new(
|
||||
TR::homescreen__settings_title.into(),
|
||||
Some(TR::homescreen__settings_subtitle.into()),
|
||||
@ -774,7 +792,11 @@ extern "C" fn new_confirm_total(n_args: usize, args: *const Obj, kwargs: *mut Ma
|
||||
|
||||
new_confirm_action_simple(
|
||||
paragraphs.into_paragraphs(),
|
||||
ConfirmActionMenu::new(None, true, None),
|
||||
ConfirmActionExtra::Menu {
|
||||
verb_cancel: None,
|
||||
has_info: true,
|
||||
verb_info: None,
|
||||
},
|
||||
ConfirmActionStrings::new(title, None, None, Some(title)),
|
||||
true,
|
||||
None,
|
||||
@ -1091,7 +1113,11 @@ extern "C" fn new_confirm_coinjoin(n_args: usize, args: *const Obj, kwargs: *mut
|
||||
|
||||
new_confirm_action_simple(
|
||||
paragraphs,
|
||||
ConfirmActionMenu::new(None, false, None),
|
||||
ConfirmActionExtra::Menu {
|
||||
verb_cancel: None,
|
||||
has_info: false,
|
||||
verb_info: None,
|
||||
},
|
||||
ConfirmActionStrings::new(
|
||||
TR::coinjoin__title.into(),
|
||||
None,
|
||||
@ -1587,6 +1613,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
|
||||
/// page_counter: bool = False,
|
||||
/// prompt_screen: bool = False,
|
||||
/// page_limit: int | None = None,
|
||||
/// cancel: bool = False,
|
||||
/// ) -> LayoutObj[UiResult]:
|
||||
/// """Confirm byte sequence data."""
|
||||
Qstr::MP_QSTR_confirm_blob => obj_fn_kw!(0, new_confirm_blob).as_obj(),
|
||||
|
@ -1712,6 +1712,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
|
||||
/// page_counter: bool = False,
|
||||
/// prompt_screen: bool = False,
|
||||
/// page_limit: int | None = None,
|
||||
/// cancel: bool = False,
|
||||
/// ) -> LayoutObj[UiResult]:
|
||||
/// """Confirm byte sequence data."""
|
||||
Qstr::MP_QSTR_confirm_blob => obj_fn_kw!(0, new_confirm_blob).as_obj(),
|
||||
|
@ -1806,6 +1806,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
|
||||
/// page_counter: bool = False,
|
||||
/// prompt_screen: bool = False,
|
||||
/// page_limit: int | None = None,
|
||||
/// cancel: bool = False,
|
||||
/// ) -> LayoutObj[UiResult]:
|
||||
/// """Confirm byte sequence data."""
|
||||
Qstr::MP_QSTR_confirm_blob => obj_fn_kw!(0, new_confirm_blob).as_obj(),
|
||||
|
@ -71,6 +71,7 @@ def confirm_blob(
|
||||
page_counter: bool = False,
|
||||
prompt_screen: bool = False,
|
||||
page_limit: int | None = None,
|
||||
cancel: bool = False,
|
||||
) -> LayoutObj[UiResult]:
|
||||
"""Confirm byte sequence data."""
|
||||
|
||||
@ -644,6 +645,7 @@ def confirm_blob(
|
||||
page_counter: bool = False,
|
||||
prompt_screen: bool = False,
|
||||
page_limit: int | None = None,
|
||||
cancel: bool = False,
|
||||
) -> LayoutObj[UiResult]:
|
||||
"""Confirm byte sequence data."""
|
||||
|
||||
@ -1216,6 +1218,7 @@ def confirm_blob(
|
||||
page_counter: bool = False,
|
||||
prompt_screen: bool = False,
|
||||
page_limit: int | None = None,
|
||||
cancel: bool = False,
|
||||
) -> LayoutObj[UiResult]:
|
||||
"""Confirm byte sequence data."""
|
||||
|
||||
|
@ -480,6 +480,7 @@ def confirm_blob(
|
||||
info_layout = trezorui2.confirm_blob(
|
||||
title=title,
|
||||
data=data,
|
||||
subtitle=description,
|
||||
description=None,
|
||||
verb=None,
|
||||
verb_cancel=verb_cancel,
|
||||
@ -488,6 +489,7 @@ def confirm_blob(
|
||||
chunkify=chunkify,
|
||||
page_counter=True,
|
||||
prompt_screen=False,
|
||||
cancel=True,
|
||||
)
|
||||
|
||||
return with_info(
|
||||
|
Loading…
Reference in New Issue
Block a user