1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-07-09 08:08:09 +00:00

feat(core): allow ProgressLayout with danger

- adds `danger` parameter to `show_progress` which can be used by
individual layout implementations to render a loader with a sever color
- this feature is used for wipe device handler
- this feature is implemented for Eckhart layout in this commit

[no changelog]
This commit is contained in:
obrusvit 2025-05-18 14:47:14 +02:00 committed by Vít Obrusník
parent c73351f6df
commit ee8bba40b2
11 changed files with 47 additions and 8 deletions

View File

@ -951,8 +951,9 @@ extern "C" fn new_show_progress(n_args: usize, args: *const Obj, kwargs: *mut Ma
.get(Qstr::MP_QSTR_title)
.and_then(Obj::try_into_option)
.unwrap_or(None);
let danger: bool = kwargs.get_or(Qstr::MP_QSTR_danger, false)?;
let layout = ModelUI::show_progress(description, indeterminate, title)?;
let layout = ModelUI::show_progress(description, indeterminate, title, danger)?;
Ok(LayoutObj::new_root(layout)?.into())
};
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
@ -1739,6 +1740,7 @@ pub static mp_module_trezorui_api: Module = obj_module! {
/// description: str,
/// indeterminate: bool = False,
/// title: str | None = None,
/// danger: bool = False,
/// ) -> LayoutObj[UiResult]:
/// """Show progress loader. Please note that the number of lines reserved on screen for
/// description is determined at construction time. If you want multiline descriptions

View File

@ -1031,6 +1031,7 @@ impl FirmwareUI for UIBolt {
description: TString<'static>,
indeterminate: bool,
title: Option<TString<'static>>,
_danger: bool,
) -> Result<impl LayoutMaybeTrace, Error> {
let (title, description) = if let Some(title) = title {
(title, description)

View File

@ -1166,6 +1166,7 @@ impl FirmwareUI for UICaesar {
description: TString<'static>,
indeterminate: bool,
title: Option<TString<'static>>,
_danger: bool,
) -> Result<impl LayoutMaybeTrace, Error> {
let mut progress = Progress::new(indeterminate, description);
if let Some(title) = title {

View File

@ -1003,6 +1003,7 @@ impl FirmwareUI for UIDelizia {
description: TString<'static>,
indeterminate: bool,
title: Option<TString<'static>>,
_danger: bool,
) -> Result<impl LayoutMaybeTrace, Error> {
let (title, description) = if let Some(title) = title {
(title, description)

View File

@ -38,12 +38,17 @@ impl ProgressScreen {
title: TString<'static>,
indeterminate: bool,
description: TString<'static>,
danger: bool,
) -> Self {
Self {
indeterminate,
text: Self::create_paragraphs(title, description),
value: 0,
border: ScreenBorder::new(theme::GREEN_LIME),
border: ScreenBorder::new(if danger {
theme::ORANGE
} else {
theme::GREEN_LIME
}),
coinjoin_progress: false,
coinjoin_do_not_disconnect: None,
}

View File

@ -1191,6 +1191,7 @@ impl FirmwareUI for UIEckhart {
description: TString<'static>,
indeterminate: bool,
title: Option<TString<'static>>,
danger: bool,
) -> Result<impl LayoutMaybeTrace, Error> {
let (title, description) = if let Some(title) = title {
(title, description)
@ -1202,6 +1203,7 @@ impl FirmwareUI for UIEckhart {
title,
indeterminate,
description,
danger,
));
Ok(layout)
}

View File

@ -358,6 +358,7 @@ pub trait FirmwareUI {
description: TString<'static>,
indeterminate: bool,
title: Option<TString<'static>>,
danger: bool,
) -> Result<impl LayoutMaybeTrace, Error>;
fn show_progress_coinjoin(

View File

@ -626,6 +626,7 @@ def show_progress(
description: str,
indeterminate: bool = False,
title: str | None = None,
danger: bool = False,
) -> LayoutObj[UiResult]:
"""Show progress loader. Please note that the number of lines reserved on screen for
description is determined at construction time. If you want multiline descriptions

View File

@ -27,7 +27,7 @@ async def wipe_device(msg: WipeDevice) -> Success:
)
# start an empty progress screen so that the screen is not blank while waiting
render_empty_loader(config.StorageMessage.PROCESSING_MSG)
render_empty_loader(config.StorageMessage.PROCESSING_MSG, danger=True)
# wipe storage
storage.wipe()

View File

@ -26,14 +26,22 @@ def allow_all_loader_messages() -> None:
_ignore_loader_messages = False
def render_empty_loader(message: config.StorageMessage, description: str = "") -> None:
"""Render empty loader to prevent the screen appear to be frozen."""
def render_empty_loader(
message: config.StorageMessage, description: str = "", danger: bool = False
) -> None:
"""Render empty loader to prevent the screen from appearing frozen.
Args:
message (config.StorageMessage): The message to display in the loader.
description (str, optional): Additional description to display. Defaults to an empty string.
danger (bool, optional): If True, renders the loader in a 'danger' style to indicate a critical operation (e.g. wipe device). Defaults to False.
"""
from trezor.ui.layouts.progress import pin_progress
global _progress_layout
global _started_with_empty_loader
_progress_layout = pin_progress(message, description)
_progress_layout = pin_progress(message, description, danger)
_progress_layout.report(0, None)
_started_with_empty_loader = True

View File

@ -25,7 +25,19 @@ def progress(
description: str | None = None,
title: str | None = None,
indeterminate: bool = False,
danger: bool = False,
) -> ui.ProgressLayout:
"""
Displays a progress layout with optional description and title.
Args:
description (str | None): The description text to display. Defaults to a generic "please wait" message.
title (str | None): The title text to display. Defaults to None.
indeterminate (bool): Whether the progress is indeterminate (e.g., a spinner). Defaults to False.
danger (bool): Whether to apply the "danger" style to indicate a critical operation, e.g. wipe device. Defaults to False.
Returns:
ui.ProgressLayout: The configured progress layout.
"""
if description is None:
description = TR.progress__please_wait # def_arg
@ -34,6 +46,7 @@ def progress(
description=description,
title=title,
indeterminate=indeterminate,
danger=danger,
)
)
@ -48,8 +61,12 @@ def coinjoin_progress(message: str) -> ui.ProgressLayout:
)
def pin_progress(title: config.StorageMessage, description: str) -> ui.ProgressLayout:
return progress(description=description, title=_storage_message_to_str(title))
def pin_progress(
title: config.StorageMessage, description: str, danger: bool = False
) -> ui.ProgressLayout:
return progress(
description=description, title=_storage_message_to_str(title), danger=danger
)
if not utils.BITCOIN_ONLY: