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

feat(core/ui): add page counter to paginated blobs

[no changelog]
This commit is contained in:
Ioan Bizău 2024-11-13 17:53:51 +01:00
parent fc54ad1b77
commit e0e0c11db2
24 changed files with 104 additions and 54 deletions

View File

@ -357,6 +357,7 @@ static void _librust_qstrs(void) {
MP_QSTR_notification; MP_QSTR_notification;
MP_QSTR_notification_level; MP_QSTR_notification_level;
MP_QSTR_page_count; MP_QSTR_page_count;
MP_QSTR_page_counter;
MP_QSTR_page_limit; MP_QSTR_page_limit;
MP_QSTR_pages; MP_QSTR_pages;
MP_QSTR_paint; MP_QSTR_paint;

View File

@ -150,7 +150,7 @@ where
} }
impl<T: Paginate> Paginate for Child<T> { impl<T: Paginate> Paginate for Child<T> {
fn page_count(&mut self) -> usize { fn page_count(&self) -> usize {
self.component.page_count() self.component.page_count()
} }

View File

@ -22,7 +22,7 @@ pub enum PageMsg<T> {
pub trait Paginate { pub trait Paginate {
/// How many pages of content are there in total? /// How many pages of content are there in total?
fn page_count(&mut self) -> usize; fn page_count(&self) -> usize;
/// Navigate to the given page. /// Navigate to the given page.
fn change_page(&mut self, active_page: usize); fn change_page(&mut self, active_page: usize);
} }

View File

@ -37,6 +37,16 @@ impl FormattedText {
.layout_ops(self.char_offset, Offset::y(self.y_offset), sink) .layout_ops(self.char_offset, Offset::y(self.y_offset), sink)
} }
pub(crate) fn layout_content_with_offset(
&self,
sink: &mut dyn LayoutSink,
char_offset: usize,
y_offset: i16,
) -> LayoutFit {
self.op_layout
.layout_ops(char_offset, Offset::y(y_offset), sink)
}
fn align_vertically(&mut self, content_height: i16) { fn align_vertically(&mut self, content_height: i16) {
let bounds_height = self.op_layout.layout.bounds.height(); let bounds_height = self.op_layout.layout.bounds.height();
if content_height >= bounds_height { if content_height >= bounds_height {
@ -53,20 +63,15 @@ impl FormattedText {
// Pagination // Pagination
impl Paginate for FormattedText { impl Paginate for FormattedText {
fn page_count(&mut self) -> usize { fn page_count(&self) -> usize {
let mut page_count = 1; // There's always at least one page. let mut page_count = 1; // There's always at least one page.
// Make sure we're starting page counting from the very beginning let mut char_offset = 0;
// (but remembering the offsets not to change them).
let initial_y_offset = self.y_offset;
let initial_char_offset = self.char_offset;
self.char_offset = 0;
self.y_offset = 0;
// Looping through the content and counting pages // Looping through the content and counting pages
// until we finally fit. // until we finally fit.
loop { loop {
let fit = self.layout_content(&mut TextNoOp); let fit = self.layout_content_with_offset(&mut TextNoOp, char_offset, 0);
match fit { match fit {
LayoutFit::Fitting { .. } => { LayoutFit::Fitting { .. } => {
break; break;
@ -75,15 +80,11 @@ impl Paginate for FormattedText {
processed_chars, .. processed_chars, ..
} => { } => {
page_count += 1; page_count += 1;
self.char_offset += processed_chars; char_offset += processed_chars;
} }
} }
} }
// Setting the offsets back to the initial values.
self.char_offset = initial_char_offset;
self.y_offset = initial_y_offset;
page_count page_count
} }

View File

@ -210,7 +210,7 @@ impl<'a, T> Paginate for Paragraphs<T>
where where
T: ParagraphSource<'a>, T: ParagraphSource<'a>,
{ {
fn page_count(&mut self) -> usize { fn page_count(&self) -> usize {
// There's always at least one page. // There's always at least one page.
self.break_pages().count().max(1) self.break_pages().count().max(1)
} }
@ -374,7 +374,7 @@ struct PageOffset {
} }
impl PageOffset { impl PageOffset {
/// Given an `PageOffset` and a `Rect` area, returns: /// Given a `PageOffset` and a `Rect` area, returns:
/// ///
/// - The next offset. /// - The next offset.
/// - Part of `area` that remains free after the current offset is rendered /// - Part of `area` that remains free after the current offset is rendered
@ -690,7 +690,7 @@ impl<'a, T> Paginate for Checklist<T>
where where
T: ParagraphSource<'a>, T: ParagraphSource<'a>,
{ {
fn page_count(&mut self) -> usize { fn page_count(&self) -> usize {
1 1
} }

View File

@ -47,6 +47,14 @@ impl<T: Component + Paginate> SwipePage<T> {
self.limit = limit; self.limit = limit;
self self
} }
pub fn page_count(&self) -> usize {
self.pages
}
pub fn current_page(&self) -> usize {
self.current
}
} }
impl<T: Component + Paginate> Component for SwipePage<T> { impl<T: Component + Paginate> Component for SwipePage<T> {

View File

@ -117,7 +117,7 @@ impl AddressDetails {
} }
impl Paginate for AddressDetails { impl Paginate for AddressDetails {
fn page_count(&mut self) -> usize { fn page_count(&self) -> usize {
self.get_internal_page_count() self.get_internal_page_count()
} }

View File

@ -69,11 +69,8 @@ impl<'a> Footer<'a> {
) )
} }
pub fn with_page_counter(max_pages: u8, instruction: TString<'static>) -> Self { pub fn with_page_counter(instruction: TString<'static>) -> Self {
Self::from_content(FooterContent::PageCounter(PageCounter::new( Self::from_content(FooterContent::PageCounter(PageCounter::new(instruction)))
max_pages,
instruction,
)))
} }
pub fn with_page_hint( pub fn with_page_hint(
@ -115,18 +112,18 @@ impl<'a> Footer<'a> {
} }
} }
pub fn update_page_counter(&mut self, ctx: &mut EventCtx, current: usize, max: Option<usize>) { pub fn update_page_counter(&mut self, ctx: &mut EventCtx, current: usize, max: usize) {
match &mut self.content { match &mut self.content {
FooterContent::PageCounter(counter) => { FooterContent::PageCounter(counter) => {
counter.update_current_page(current); counter.update_current_page(current, max);
self.swipe_allow_down = counter.is_first_page(); self.swipe_allow_down = counter.is_first_page();
self.swipe_allow_up = counter.is_last_page(); self.swipe_allow_up = counter.is_last_page();
ctx.request_paint(); ctx.request_paint();
} }
FooterContent::PageHint(page_hint) => { FooterContent::PageHint(hint) => {
page_hint.update_current_page(current, max); hint.update_current_page(current, max);
self.swipe_allow_down = page_hint.is_first_page(); self.swipe_allow_down = hint.is_first_page();
self.swipe_allow_up = page_hint.is_last_page(); self.swipe_allow_up = hint.is_last_page();
ctx.request_paint(); ctx.request_paint();
} }
_ => { _ => {
@ -322,16 +319,17 @@ struct PageCounter {
} }
impl PageCounter { impl PageCounter {
fn new(page_max: u8, instruction: TString<'static>) -> Self { fn new(instruction: TString<'static>) -> Self {
Self { Self {
instruction, instruction,
page_curr: 0, page_curr: 0,
page_max, page_max: 0,
font: Font::SUB, font: Font::SUB,
} }
} }
fn update_current_page(&mut self, new_value: usize) { fn update_current_page(&mut self, new_value: usize, max: usize) {
self.page_max = max as u8;
self.page_curr = (new_value as u8).clamp(0, self.page_max.saturating_sub(1)); self.page_curr = (new_value as u8).clamp(0, self.page_max.saturating_sub(1));
} }
@ -410,11 +408,9 @@ struct PageHint {
} }
impl PageHint { impl PageHint {
fn update_current_page(&mut self, current: usize, max: Option<usize>) { fn update_current_page(&mut self, current: usize, max: usize) {
self.page_curr = (current as u8).clamp(0, self.page_num.saturating_sub(1));
if let Some(max) = max {
self.page_num = max as u8; self.page_num = max as u8;
} self.page_curr = (current as u8).clamp(0, self.page_num.saturating_sub(1));
} }
fn update_max_page(&mut self, max: usize) { fn update_max_page(&mut self, max: usize) {

View File

@ -195,8 +195,8 @@ where
} }
#[inline(never)] #[inline(never)]
pub fn with_footer_counter(mut self, instruction: TString<'static>, max_value: u8) -> Self { pub fn with_footer_counter(mut self, instruction: TString<'static>) -> Self {
self.footer = Some(Footer::with_page_counter(max_value, instruction)); self.footer = Some(Footer::with_page_counter(instruction));
self self
} }

View File

@ -335,7 +335,7 @@ impl<F: Fn(usize) -> TString<'static>> PagedVerticalMenu<F> {
} }
impl<F: Fn(usize) -> TString<'static>> Paginate for PagedVerticalMenu<F> { impl<F: Fn(usize) -> TString<'static>> Paginate for PagedVerticalMenu<F> {
fn page_count(&mut self) -> usize { fn page_count(&self) -> usize {
self.num_pages() self.num_pages()
} }

View File

@ -8,7 +8,7 @@ use crate::{
component::{ component::{
swipe_detect::SwipeSettings, swipe_detect::SwipeSettings,
text::paragraphs::{Paragraph, ParagraphSource, ParagraphVecShort, VecExt}, text::paragraphs::{Paragraph, ParagraphSource, ParagraphVecShort, VecExt},
Component, ComponentExt, Paginate, Component, ComponentExt, EventCtx, Paginate,
}, },
flow::{ flow::{
base::{Decision, DecisionBuilder as _}, base::{Decision, DecisionBuilder as _},
@ -21,7 +21,8 @@ use crate::{
use super::super::{ use super::super::{
component::{ component::{
Frame, FrameMsg, PromptMsg, PromptScreen, SwipeContent, VerticalMenu, VerticalMenuChoiceMsg, Footer, Frame, FrameMsg, PromptMsg, PromptScreen, SwipeContent, VerticalMenu,
VerticalMenuChoiceMsg,
}, },
theme, theme,
}; };
@ -188,15 +189,17 @@ fn new_confirm_action_obj(_args: &[Obj], kwargs: &Map) -> Result<Obj, error::Err
ConfirmActionStrings::new(title, subtitle, None, prompt_screen.then_some(prompt_title)), ConfirmActionStrings::new(title, subtitle, None, prompt_screen.then_some(prompt_title)),
hold, hold,
None, None,
false,
) )
} }
#[inline(never)] #[inline(never)]
fn new_confirm_action_uni<T: Component + MaybeTrace + 'static>( fn new_confirm_action_uni<T: Component + Paginate + MaybeTrace + 'static>(
content: T, content: SwipeContent<SwipePage<T>>,
menu: ConfirmActionMenu, menu: ConfirmActionMenu,
strings: ConfirmActionStrings, strings: ConfirmActionStrings,
hold: bool, hold: bool,
show_page_counter: bool,
) -> Result<Obj, error::Error> { ) -> Result<Obj, error::Error> {
let (prompt_screen, prompt_pages, flow, page) = let (prompt_screen, prompt_pages, flow, page) =
create_flow(strings.title, strings.prompt_screen, hold); create_flow(strings.title, strings.prompt_screen, hold);
@ -208,6 +211,22 @@ fn new_confirm_action_uni<T: Component + MaybeTrace + 'static>(
.with_menu_button() .with_menu_button()
.with_footer(TR::instructions__swipe_up.into(), None); .with_footer(TR::instructions__swipe_up.into(), None);
if show_page_counter {
fn footer_update_fn<T: Component + Paginate>(
content: &SwipeContent<SwipePage<T>>,
ctx: &mut EventCtx,
footer: &mut Footer,
) {
let current_page = content.inner().current_page();
let page_count = content.inner().page_count();
footer.update_page_counter(ctx, current_page, page_count);
}
content_intro = content_intro
.with_footer_counter(TR::instructions__swipe_up.into())
.register_footer_update_fn(footer_update_fn::<T>);
}
if let Some(subtitle) = strings.subtitle { if let Some(subtitle) = strings.subtitle {
content_intro = content_intro.with_subtitle(subtitle); content_intro = content_intro.with_subtitle(subtitle);
} }
@ -335,11 +354,13 @@ pub fn new_confirm_action_simple<T: Component + Paginate + MaybeTrace + 'static>
strings: ConfirmActionStrings, strings: ConfirmActionStrings,
hold: bool, hold: bool,
page_limit: Option<usize>, page_limit: Option<usize>,
show_page_counter: bool,
) -> Result<Obj, error::Error> { ) -> Result<Obj, error::Error> {
new_confirm_action_uni( new_confirm_action_uni(
SwipeContent::new(SwipePage::vertical(content).with_limit(page_limit)), SwipeContent::new(SwipePage::vertical(content).with_limit(page_limit)),
menu, menu,
strings, strings,
hold, hold,
show_page_counter,
) )
} }

View File

@ -100,7 +100,7 @@ fn footer_update_fn(
) { ) {
let current_page = content.inner().inner().current_page(); let current_page = content.inner().inner().current_page();
let total_pages = content.inner().inner().num_pages(); let total_pages = content.inner().inner().num_pages();
footer.update_page_counter(ctx, current_page, Some(total_pages)); footer.update_page_counter(ctx, current_page, total_pages);
} }
impl ConfirmFido { impl ConfirmFido {

View File

@ -147,6 +147,7 @@ impl FlowController for ContinueRecoveryBetweenSharesAdvanced {
pub extern "C" fn new_continue_recovery(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj { pub extern "C" fn new_continue_recovery(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, new_obj) } unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, new_obj) }
} }
fn footer_update_fn( fn footer_update_fn(
content: &SwipeContent<SwipePage<Paragraphs<ParagraphVecLong>>>, content: &SwipeContent<SwipePage<Paragraphs<ParagraphVecLong>>>,
ctx: &mut EventCtx, ctx: &mut EventCtx,
@ -156,7 +157,7 @@ fn footer_update_fn(
// to get total pages instead of using Paginate because it borrows mutably // to get total pages instead of using Paginate because it borrows mutably
let current_page = content.inner().inner().current_page(); let current_page = content.inner().inner().current_page();
let total_pages = content.inner().inner().inner().len() / 2; // 2 paragraphs per page let total_pages = content.inner().inner().inner().len() / 2; // 2 paragraphs per page
footer.update_page_counter(ctx, current_page, Some(total_pages)); footer.update_page_counter(ctx, current_page, total_pages);
} }
fn new_obj(_args: &[Obj], kwargs: &Map) -> Result<Obj, error::Error> { fn new_obj(_args: &[Obj], kwargs: &Map) -> Result<Obj, error::Error> {

View File

@ -81,7 +81,7 @@ fn footer_updating_func(
) { ) {
let current_page = content.inner().current_page(); let current_page = content.inner().current_page();
let total_pages = content.inner().num_pages(); let total_pages = content.inner().num_pages();
footer.update_page_counter(ctx, current_page, Some(total_pages)); footer.update_page_counter(ctx, current_page, total_pages);
} }
impl ShowShareWords { impl ShowShareWords {
@ -119,7 +119,6 @@ impl ShowShareWords {
.one_button_request(ButtonRequestCode::ResetDevice.with_name("share_words")) .one_button_request(ButtonRequestCode::ResetDevice.with_name("share_words"))
.with_pages(move |_| nwords + 2); .with_pages(move |_| nwords + 2);
let n_words = share_words_vec.len();
let content_words = Frame::left_aligned( let content_words = Frame::left_aligned(
title, title,
InternallySwipableContent::new(ShareWords::new(share_words_vec, subtitle)), InternallySwipableContent::new(ShareWords::new(share_words_vec, subtitle)),
@ -129,7 +128,7 @@ impl ShowShareWords {
.with_vertical_pages() .with_vertical_pages()
.with_subtitle(subtitle) .with_subtitle(subtitle)
.register_header_update_fn(header_updating_func) .register_header_update_fn(header_updating_func)
.with_footer_counter(TR::instructions__swipe_up.into(), n_words as u8) .with_footer_counter(TR::instructions__swipe_up.into())
.register_footer_update_fn(footer_updating_func) .register_footer_update_fn(footer_updating_func)
.map(|_| None); .map(|_| None);

View File

@ -245,6 +245,7 @@ extern "C" fn new_confirm_emphasized(n_args: usize, args: *const Obj, kwargs: *m
ConfirmActionStrings::new(title, None, None, Some(title)), ConfirmActionStrings::new(title, None, None, Some(title)),
false, false,
None, None,
false,
) )
}; };
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
@ -265,6 +266,7 @@ struct ConfirmBlobParams {
hold: bool, hold: bool,
chunkify: bool, chunkify: bool,
text_mono: bool, text_mono: bool,
page_counter: bool,
page_limit: Option<usize>, page_limit: Option<usize>,
} }
@ -293,6 +295,7 @@ impl ConfirmBlobParams {
hold, hold,
chunkify: false, chunkify: false,
text_mono: true, text_mono: true,
page_counter: false,
page_limit: None, page_limit: None,
} }
} }
@ -327,6 +330,11 @@ impl ConfirmBlobParams {
self self
} }
fn with_page_counter(mut self, page_counter: bool) -> Self {
self.page_counter = page_counter;
self
}
fn with_page_limit(mut self, page_limit: Option<usize>) -> Self { fn with_page_limit(mut self, page_limit: Option<usize>) -> Self {
self.page_limit = page_limit; self.page_limit = page_limit;
self self
@ -366,6 +374,7 @@ impl ConfirmBlobParams {
), ),
self.hold, self.hold,
self.page_limit, self.page_limit,
self.page_counter,
) )
} }
} }
@ -402,6 +411,7 @@ extern "C" fn new_confirm_blob(n_args: usize, args: *const Obj, kwargs: *mut Map
let info: bool = kwargs.get_or(Qstr::MP_QSTR_info, true)?; let info: bool = kwargs.get_or(Qstr::MP_QSTR_info, true)?;
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)?;
let page_counter: bool = kwargs.get_or(Qstr::MP_QSTR_page_counter, false)?;
let prompt_screen: bool = kwargs.get_or(Qstr::MP_QSTR_prompt_screen, true)?; let prompt_screen: bool = kwargs.get_or(Qstr::MP_QSTR_prompt_screen, true)?;
let page_limit: Option<usize> = kwargs let page_limit: Option<usize> = kwargs
.get(Qstr::MP_QSTR_page_limit) .get(Qstr::MP_QSTR_page_limit)
@ -433,6 +443,7 @@ extern "C" fn new_confirm_blob(n_args: usize, args: *const Obj, kwargs: *mut Map
.with_extra(extra) .with_extra(extra)
.with_info_button(info) .with_info_button(info)
.with_chunkify(chunkify) .with_chunkify(chunkify)
.with_page_counter(page_counter)
.with_page_limit(page_limit) .with_page_limit(page_limit)
.into_flow() .into_flow()
}; };
@ -471,6 +482,7 @@ extern "C" fn new_confirm_address(n_args: usize, args: *const Obj, kwargs: *mut
ConfirmActionStrings::new(title, None, None, None), ConfirmActionStrings::new(title, None, None, None),
false, false,
None, None,
false,
) )
}; };
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
@ -495,6 +507,7 @@ extern "C" fn new_confirm_properties(n_args: usize, args: *const Obj, kwargs: *m
ConfirmActionStrings::new(title, None, None, hold.then_some(title)), ConfirmActionStrings::new(title, None, None, hold.then_some(title)),
hold, hold,
None, None,
false,
) )
}; };
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
@ -527,6 +540,7 @@ extern "C" fn new_confirm_homescreen(n_args: usize, args: *const Obj, kwargs: *m
), ),
false, false,
None, None,
false,
) )
} else { } else {
if !check_homescreen_format(jpeg) { if !check_homescreen_format(jpeg) {
@ -634,6 +648,7 @@ extern "C" fn new_confirm_total(n_args: usize, args: *const Obj, kwargs: *mut Ma
ConfirmActionStrings::new(title, None, None, Some(title)), ConfirmActionStrings::new(title, None, None, Some(title)),
true, true,
None, None,
false,
) )
}; };
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
@ -923,6 +938,7 @@ extern "C" fn new_confirm_coinjoin(n_args: usize, args: *const Obj, kwargs: *mut
), ),
true, true,
None, None,
false,
) )
}; };
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) } unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
@ -1260,6 +1276,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// info: bool = True, /// info: bool = True,
/// hold: bool = False, /// hold: bool = False,
/// chunkify: bool = False, /// chunkify: bool = False,
/// page_counter: bool = False,
/// prompt_screen: bool = False, /// prompt_screen: bool = False,
/// page_limit: int | None = None, /// page_limit: int | None = None,
/// ) -> LayoutObj[UiResult]: /// ) -> LayoutObj[UiResult]:

View File

@ -199,7 +199,7 @@ impl Page {
// Pagination // Pagination
impl Paginate for Page { impl Paginate for Page {
fn page_count(&mut self) -> usize { fn page_count(&self) -> usize {
self.formatted.page_count() self.formatted.page_count()
} }

View File

@ -87,7 +87,7 @@ impl<T> Paginate for Frame<T>
where where
T: Component + Paginate, T: Component + Paginate,
{ {
fn page_count(&mut self) -> usize { fn page_count(&self) -> usize {
self.content.page_count() self.content.page_count()
} }

View File

@ -225,7 +225,7 @@ impl Component for ScrollBar {
} }
impl Paginate for ScrollBar { impl Paginate for ScrollBar {
fn page_count(&mut self) -> usize { fn page_count(&self) -> usize {
self.page_count self.page_count
} }

View File

@ -150,7 +150,7 @@ impl<'a> Component for ShareWords<'a> {
} }
impl<'a> Paginate for ShareWords<'a> { impl<'a> Paginate for ShareWords<'a> {
fn page_count(&mut self) -> usize { fn page_count(&self) -> usize {
// Not defining the logic here, as we do not want it to be `&mut`. // Not defining the logic here, as we do not want it to be `&mut`.
self.total_page_count() self.total_page_count()
} }

View File

@ -1709,6 +1709,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// info: bool = True, /// info: bool = True,
/// hold: bool = False, /// hold: bool = False,
/// chunkify: bool = False, /// chunkify: bool = False,
/// page_counter: bool = False,
/// prompt_screen: bool = False, /// prompt_screen: bool = False,
/// page_limit: int | None = None, /// page_limit: int | None = None,
/// ) -> LayoutObj[UiResult]: /// ) -> LayoutObj[UiResult]:

View File

@ -125,7 +125,7 @@ impl AddressDetails {
} }
impl Paginate for AddressDetails { impl Paginate for AddressDetails {
fn page_count(&mut self) -> usize { fn page_count(&self) -> usize {
let total_xpub_pages: u8 = self.xpub_page_count.iter().copied().sum(); let total_xpub_pages: u8 = self.xpub_page_count.iter().copied().sum();
2usize.saturating_add(total_xpub_pages.into()) 2usize.saturating_add(total_xpub_pages.into())
} }

View File

@ -1803,6 +1803,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// info: bool = True, /// info: bool = True,
/// hold: bool = False, /// hold: bool = False,
/// chunkify: bool = False, /// chunkify: bool = False,
/// page_counter: bool = False,
/// prompt_screen: bool = False, /// prompt_screen: bool = False,
/// page_limit: int | None = None, /// page_limit: int | None = None,
/// ) -> LayoutObj[UiResult]: /// ) -> LayoutObj[UiResult]:

View File

@ -68,6 +68,7 @@ def confirm_blob(
info: bool = True, info: bool = True,
hold: bool = False, hold: bool = False,
chunkify: bool = False, chunkify: bool = False,
page_counter: bool = False,
prompt_screen: bool = False, prompt_screen: bool = False,
page_limit: int | None = None, page_limit: int | None = None,
) -> LayoutObj[UiResult]: ) -> LayoutObj[UiResult]:
@ -640,6 +641,7 @@ def confirm_blob(
info: bool = True, info: bool = True,
hold: bool = False, hold: bool = False,
chunkify: bool = False, chunkify: bool = False,
page_counter: bool = False,
prompt_screen: bool = False, prompt_screen: bool = False,
page_limit: int | None = None, page_limit: int | None = None,
) -> LayoutObj[UiResult]: ) -> LayoutObj[UiResult]:
@ -1211,6 +1213,7 @@ def confirm_blob(
info: bool = True, info: bool = True,
hold: bool = False, hold: bool = False,
chunkify: bool = False, chunkify: bool = False,
page_counter: bool = False,
prompt_screen: bool = False, prompt_screen: bool = False,
page_limit: int | None = None, page_limit: int | None = None,
) -> LayoutObj[UiResult]: ) -> LayoutObj[UiResult]:

View File

@ -500,6 +500,7 @@ def confirm_blob(
info=False, info=False,
hold=False, hold=False,
chunkify=chunkify, chunkify=chunkify,
page_counter=True,
prompt_screen=False, prompt_screen=False,
) )