mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-25 17:09:44 +00:00
feat(core): introdue UiFeaturesFirmware
This commit introduces a trait defining high level UI building blocks. The trait is common for all models. trezorui_api module exposes these functions to MicroPython world. `show_info` is implemented as a first function.
This commit is contained in:
parent
c51f51d233
commit
f354a3d6ba
@ -1,12 +1,43 @@
|
||||
use crate::micropython::map::Map;
|
||||
use crate::ui::layout::obj::ATTACH_TYPE_OBJ;
|
||||
use crate::ui::layout::base::LAYOUT_STATE;
|
||||
use crate::ui::backlight::BACKLIGHT_LEVELS_OBJ;
|
||||
use crate::{
|
||||
micropython::{macros::obj_module, module::Module, qstr::Qstr},
|
||||
ui::layout::result::{CANCELLED, CONFIRMED, INFO},
|
||||
micropython::{
|
||||
macros::{obj_fn_kw, obj_module},
|
||||
map::Map,
|
||||
module::Module,
|
||||
obj::Obj,
|
||||
qstr::Qstr,
|
||||
util,
|
||||
},
|
||||
strutil::TString,
|
||||
ui::{
|
||||
backlight::BACKLIGHT_LEVELS_OBJ,
|
||||
layout::{
|
||||
base::LAYOUT_STATE,
|
||||
obj::{LayoutObj, ATTACH_TYPE_OBJ},
|
||||
result::{CANCELLED, CONFIRMED, INFO},
|
||||
},
|
||||
ui_features::ModelUI,
|
||||
ui_features_fw::UIFeaturesFirmware,
|
||||
},
|
||||
};
|
||||
|
||||
// free-standing functions exported to MicroPython mirror `trait
|
||||
// UIFeaturesFirmware`
|
||||
|
||||
extern "C" fn show_info(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 description: TString = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?;
|
||||
let button: TString = kwargs
|
||||
.get_or(Qstr::MP_QSTR_button, TString::empty())?
|
||||
.try_into()?;
|
||||
let time_ms: u32 = kwargs.get_or(Qstr::MP_QSTR_time_ms, 0)?.try_into()?;
|
||||
|
||||
let obj = ModelUI::show_info(title, description, button, time_ms)?;
|
||||
Ok(obj.into())
|
||||
};
|
||||
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub static mp_module_trezorui_api: Module = obj_module! {
|
||||
/// from trezor import utils
|
||||
@ -103,6 +134,16 @@ pub static mp_module_trezorui_api: Module = obj_module! {
|
||||
/// INFO: UiResult
|
||||
Qstr::MP_QSTR_INFO => INFO.as_obj(),
|
||||
|
||||
/// def show_info(
|
||||
/// *,
|
||||
/// title: str,
|
||||
/// description: str = "",
|
||||
/// button: str = "",
|
||||
/// time_ms: int = 0,
|
||||
/// ) -> LayoutObj[UiResult]:
|
||||
/// """Info screen."""
|
||||
Qstr::MP_QSTR_show_info => obj_fn_kw!(0, show_info).as_obj(),
|
||||
|
||||
/// class BacklightLevels:
|
||||
/// """Backlight levels. Values dynamically update based on user settings."""
|
||||
/// MAX: ClassVar[int]
|
||||
@ -130,4 +171,5 @@ pub static mp_module_trezorui_api: Module = obj_module! {
|
||||
/// TRANSITIONING: "ClassVar[LayoutState]"
|
||||
/// DONE: "ClassVar[LayoutState]"
|
||||
Qstr::MP_QSTR_LayoutState => LAYOUT_STATE.as_obj(),
|
||||
|
||||
};
|
||||
|
@ -94,7 +94,7 @@ pub trait ComponentMsgObj: Component {
|
||||
pub trait ComponentMaybeTrace: Component + ComponentMsgObj + MaybeTrace {}
|
||||
impl<T> ComponentMaybeTrace for T where T: Component + ComponentMsgObj + MaybeTrace {}
|
||||
|
||||
struct RootComponent<T, M>
|
||||
pub struct RootComponent<T, M>
|
||||
where
|
||||
T: Component,
|
||||
M: UIFeaturesCommon,
|
||||
|
@ -23,6 +23,7 @@ pub mod model_mercury;
|
||||
pub mod model_tr;
|
||||
#[cfg(feature = "model_tt")]
|
||||
pub mod model_tt;
|
||||
|
||||
pub mod ui_features;
|
||||
#[cfg(feature = "micropython")]
|
||||
pub mod ui_features_fw;
|
||||
|
@ -964,21 +964,6 @@ extern "C" fn new_show_success(n_args: usize, args: *const Obj, kwargs: *mut Map
|
||||
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
|
||||
}
|
||||
|
||||
extern "C" fn new_show_info(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 description: TString = kwargs.get(Qstr::MP_QSTR_description)?.try_into()?;
|
||||
let content = Paragraphs::new(Paragraph::new(&theme::TEXT_MAIN_GREY_LIGHT, description));
|
||||
let obj = LayoutObj::new(SwipeUpScreen::new(
|
||||
Frame::left_aligned(title, SwipeContent::new(content))
|
||||
.with_footer(TR::instructions__swipe_up.into(), None)
|
||||
.with_swipe(Direction::Up, SwipeSettings::default()),
|
||||
))?;
|
||||
Ok(obj.into())
|
||||
};
|
||||
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
|
||||
}
|
||||
|
||||
extern "C" fn new_show_mismatch(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()?;
|
||||
@ -1512,7 +1497,6 @@ pub static mp_module_trezorui2: Module = obj_module! {
|
||||
///
|
||||
Qstr::MP_QSTR___name__ => Qstr::MP_QSTR_trezorui2.to_obj(),
|
||||
|
||||
|
||||
/// def disable_animation(disable: bool) -> None:
|
||||
/// """Disable animations, debug builds only."""
|
||||
Qstr::MP_QSTR_disable_animation => obj_fn_1!(upy_disable_animation).as_obj(),
|
||||
@ -1716,17 +1700,6 @@ pub static mp_module_trezorui2: Module = obj_module! {
|
||||
/// """Success screen. Description is used in the footer."""
|
||||
Qstr::MP_QSTR_show_success => obj_fn_kw!(0, new_show_success).as_obj(),
|
||||
|
||||
/// def show_info(
|
||||
/// *,
|
||||
/// title: str,
|
||||
/// button: str = "CONTINUE",
|
||||
/// description: str = "",
|
||||
/// allow_cancel: bool = False,
|
||||
/// time_ms: int = 0,
|
||||
/// ) -> LayoutObj[UiResult]:
|
||||
/// """Info modal. No buttons shown when `button` is empty string."""
|
||||
Qstr::MP_QSTR_show_info => obj_fn_kw!(0, new_show_info).as_obj(),
|
||||
|
||||
/// def show_mismatch(*, title: str) -> LayoutObj[UiResult]:
|
||||
/// """Warning modal, receiving address mismatch."""
|
||||
Qstr::MP_QSTR_show_mismatch => obj_fn_kw!(0, new_show_mismatch).as_obj(),
|
||||
|
37
core/embed/rust/src/ui/model_mercury/ui_features_fw.rs
Normal file
37
core/embed/rust/src/ui/model_mercury/ui_features_fw.rs
Normal file
@ -0,0 +1,37 @@
|
||||
use crate::{
|
||||
error::Error,
|
||||
micropython::gc::Gc,
|
||||
strutil::TString,
|
||||
translations::TR,
|
||||
ui::{
|
||||
component::{
|
||||
swipe_detect::SwipeSettings,
|
||||
text::paragraphs::{Paragraph, Paragraphs},
|
||||
},
|
||||
geometry::Direction,
|
||||
layout::obj::{LayoutMaybeTrace, LayoutObj, RootComponent},
|
||||
ui_features_fw::UIFeaturesFirmware,
|
||||
},
|
||||
};
|
||||
|
||||
use super::{
|
||||
component::{Frame, SwipeContent, SwipeUpScreen},
|
||||
theme, ModelMercuryFeatures,
|
||||
};
|
||||
|
||||
impl UIFeaturesFirmware for ModelMercuryFeatures {
|
||||
fn show_info(
|
||||
title: TString<'static>,
|
||||
description: TString<'static>,
|
||||
_button: TString<'static>,
|
||||
_time_ms: u32,
|
||||
) -> Result<Gc<LayoutObj>, Error> {
|
||||
let content = Paragraphs::new(Paragraph::new(&theme::TEXT_MAIN_GREY_LIGHT, description));
|
||||
let obj = LayoutObj::new(SwipeUpScreen::new(
|
||||
Frame::left_aligned(title, SwipeContent::new(content))
|
||||
.with_footer(TR::instructions__swipe_up.into(), None)
|
||||
.with_swipe(Direction::Up, SwipeSettings::default()),
|
||||
))?;
|
||||
Ok(obj)
|
||||
}
|
||||
}
|
@ -1098,31 +1098,6 @@ extern "C" fn new_show_warning(n_args: usize, args: *const Obj, kwargs: *mut Map
|
||||
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
|
||||
}
|
||||
|
||||
extern "C" fn new_show_info(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 description: TString = kwargs.get_or(Qstr::MP_QSTR_description, "".into())?;
|
||||
let time_ms: u32 = kwargs.get_or(Qstr::MP_QSTR_time_ms, 0)?;
|
||||
|
||||
let content = Frame::new(
|
||||
title,
|
||||
Paragraphs::new([Paragraph::new(&theme::TEXT_NORMAL, description)]),
|
||||
);
|
||||
let obj = if time_ms == 0 {
|
||||
// No timer, used when we only want to draw the dialog once and
|
||||
// then throw away the layout object.
|
||||
LayoutObj::new(content)?
|
||||
} else {
|
||||
// Timeout.
|
||||
let timeout = Timeout::new(time_ms);
|
||||
LayoutObj::new((timeout, content.map(|_| None)))?
|
||||
};
|
||||
|
||||
Ok(obj.into())
|
||||
};
|
||||
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
|
||||
}
|
||||
|
||||
extern "C" fn new_show_passphrase() -> Obj {
|
||||
let block = move || {
|
||||
let text: TString = TR::passphrase__please_enter.into();
|
||||
@ -1871,15 +1846,6 @@ pub static mp_module_trezorui2: Module = obj_module! {
|
||||
/// """Warning modal with middle button and centered text."""
|
||||
Qstr::MP_QSTR_show_warning => obj_fn_kw!(0, new_show_warning).as_obj(),
|
||||
|
||||
/// def show_info(
|
||||
/// *,
|
||||
/// title: str,
|
||||
/// description: str = "",
|
||||
/// time_ms: int = 0,
|
||||
/// ) -> LayoutObj[UiResult]:
|
||||
/// """Info modal."""
|
||||
Qstr::MP_QSTR_show_info => obj_fn_kw!(0, new_show_info).as_obj(),
|
||||
|
||||
/// def show_passphrase() -> LayoutObj[UiResult]:
|
||||
/// """Show passphrase on host dialog."""
|
||||
Qstr::MP_QSTR_show_passphrase => obj_fn_0!(new_show_passphrase).as_obj(),
|
||||
|
@ -12,6 +12,7 @@ mod screens;
|
||||
pub mod theme;
|
||||
|
||||
pub struct ModelTRFeatures {}
|
||||
pub mod ui_features_fw;
|
||||
|
||||
impl UIFeaturesCommon for ModelTRFeatures {
|
||||
const SCREEN: Rect = constant::SCREEN;
|
||||
|
38
core/embed/rust/src/ui/model_tr/ui_features_fw.rs
Normal file
38
core/embed/rust/src/ui/model_tr/ui_features_fw.rs
Normal file
@ -0,0 +1,38 @@
|
||||
use crate::{
|
||||
error::Error,
|
||||
micropython::gc::Gc,
|
||||
strutil::TString,
|
||||
ui::{
|
||||
component::{
|
||||
text::paragraphs::{Paragraph, Paragraphs}, ComponentExt, Timeout
|
||||
},
|
||||
layout::obj::{LayoutMaybeTrace, LayoutObj, RootComponent},
|
||||
ui_features_fw::UIFeaturesFirmware,
|
||||
},
|
||||
};
|
||||
|
||||
use super::{component::Frame, theme, ModelTRFeatures};
|
||||
|
||||
impl UIFeaturesFirmware for ModelTRFeatures {
|
||||
fn show_info(
|
||||
title: TString<'static>,
|
||||
description: TString<'static>,
|
||||
_button: TString<'static>,
|
||||
time_ms: u32,
|
||||
) -> Result<Gc<LayoutObj>, Error> {
|
||||
let content = Frame::new(
|
||||
title,
|
||||
Paragraphs::new([Paragraph::new(&theme::TEXT_NORMAL, description)]),
|
||||
);
|
||||
let obj = if time_ms == 0 {
|
||||
// No timer, used when we only want to draw the dialog once and
|
||||
// then throw away the layout object.
|
||||
LayoutObj::new(content)?
|
||||
} else {
|
||||
// Timeout.
|
||||
let timeout = Timeout::new(time_ms);
|
||||
LayoutObj::new((timeout, content.map(|_| None)))?
|
||||
};
|
||||
Ok(obj)
|
||||
}
|
||||
}
|
@ -1024,20 +1024,6 @@ extern "C" fn new_show_success(n_args: usize, args: *const Obj, kwargs: *mut Map
|
||||
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
|
||||
}
|
||||
|
||||
extern "C" fn new_show_info(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
|
||||
let block = move |_args: &[Obj], kwargs: &Map| {
|
||||
let icon = BlendedImage::new(
|
||||
theme::IMAGE_BG_CIRCLE,
|
||||
theme::IMAGE_FG_INFO,
|
||||
theme::INFO_COLOR,
|
||||
theme::FG,
|
||||
theme::BG,
|
||||
);
|
||||
new_show_modal(kwargs, icon, theme::button_info())
|
||||
};
|
||||
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
|
||||
}
|
||||
|
||||
extern "C" fn new_show_mismatch(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()?;
|
||||
@ -1653,7 +1639,6 @@ pub static mp_module_trezorui2: Module = obj_module! {
|
||||
/// from trezor import utils
|
||||
/// from trezorui_api import *
|
||||
///
|
||||
|
||||
/// def disable_animation(disable: bool) -> None:
|
||||
/// """Disable animations, debug builds only."""
|
||||
Qstr::MP_QSTR_disable_animation => obj_fn_1!(upy_disable_animation).as_obj(),
|
||||
@ -1865,17 +1850,6 @@ pub static mp_module_trezorui2: Module = obj_module! {
|
||||
/// """Success modal. No buttons shown when `button` is empty string."""
|
||||
Qstr::MP_QSTR_show_success => obj_fn_kw!(0, new_show_success).as_obj(),
|
||||
|
||||
/// def show_info(
|
||||
/// *,
|
||||
/// title: str,
|
||||
/// button: str = "CONTINUE",
|
||||
/// description: str = "",
|
||||
/// allow_cancel: bool = False,
|
||||
/// time_ms: int = 0,
|
||||
/// ) -> LayoutObj[UiResult]:
|
||||
/// """Info modal. No buttons shown when `button` is empty string."""
|
||||
Qstr::MP_QSTR_show_info => obj_fn_kw!(0, new_show_info).as_obj(),
|
||||
|
||||
/// def show_mismatch(*, title: str) -> LayoutObj[UiResult]:
|
||||
/// """Warning modal, receiving address mismatch."""
|
||||
Qstr::MP_QSTR_show_mismatch => obj_fn_kw!(0, new_show_mismatch).as_obj(),
|
||||
|
@ -19,6 +19,7 @@ use crate::ui::{
|
||||
};
|
||||
|
||||
pub struct ModelTTFeatures;
|
||||
pub mod ui_features_fw;
|
||||
|
||||
impl UIFeaturesCommon for ModelTTFeatures {
|
||||
#[cfg(feature = "backlight")]
|
||||
|
111
core/embed/rust/src/ui/model_tt/ui_features_fw.rs
Normal file
111
core/embed/rust/src/ui/model_tt/ui_features_fw.rs
Normal file
@ -0,0 +1,111 @@
|
||||
use crate::{
|
||||
error::Error,
|
||||
micropython::gc::Gc,
|
||||
strutil::TString,
|
||||
ui::{
|
||||
component::{image::BlendedImage, ComponentExt, Empty, Timeout},
|
||||
layout::obj::{LayoutMaybeTrace, LayoutObj, RootComponent},
|
||||
ui_features_fw::UIFeaturesFirmware,
|
||||
},
|
||||
};
|
||||
|
||||
use super::{
|
||||
component::{Button, ButtonMsg, ButtonStyleSheet, CancelConfirmMsg, IconDialog},
|
||||
theme, ModelTTFeatures,
|
||||
};
|
||||
|
||||
impl UIFeaturesFirmware for ModelTTFeatures {
|
||||
fn show_info(
|
||||
title: TString<'static>,
|
||||
description: TString<'static>,
|
||||
button: TString<'static>,
|
||||
time_ms: u32,
|
||||
) -> Result<Gc<LayoutObj>, Error> {
|
||||
assert!(
|
||||
!button.is_empty() || time_ms > 0,
|
||||
"either button or timeout must be set"
|
||||
);
|
||||
|
||||
let icon = BlendedImage::new(
|
||||
theme::IMAGE_BG_CIRCLE,
|
||||
theme::IMAGE_FG_INFO,
|
||||
theme::INFO_COLOR,
|
||||
theme::FG,
|
||||
theme::BG,
|
||||
);
|
||||
let res = new_show_modal(
|
||||
title,
|
||||
TString::empty(),
|
||||
description,
|
||||
TString::empty(),
|
||||
false,
|
||||
time_ms,
|
||||
icon,
|
||||
theme::button_info(),
|
||||
)?;
|
||||
Ok(res)
|
||||
}
|
||||
}
|
||||
|
||||
fn new_show_modal(
|
||||
title: TString<'static>,
|
||||
value: TString<'static>,
|
||||
description: TString<'static>,
|
||||
button: TString<'static>,
|
||||
allow_cancel: bool,
|
||||
time_ms: u32,
|
||||
icon: BlendedImage,
|
||||
button_style: ButtonStyleSheet,
|
||||
) -> Result<Gc<LayoutObj>, Error> {
|
||||
let no_buttons = button.is_empty();
|
||||
let obj = if no_buttons && time_ms == 0 {
|
||||
// No buttons and no timer, used when we only want to draw the dialog once and
|
||||
// then throw away the layout object.
|
||||
LayoutObj::new(
|
||||
IconDialog::new(icon, title, Empty)
|
||||
.with_value(value)
|
||||
.with_description(description),
|
||||
)?
|
||||
} else if no_buttons && time_ms > 0 {
|
||||
// Timeout, no buttons.
|
||||
LayoutObj::new(
|
||||
IconDialog::new(
|
||||
icon,
|
||||
title,
|
||||
Timeout::new(time_ms).map(|_| Some(CancelConfirmMsg::Confirmed)),
|
||||
)
|
||||
.with_value(value)
|
||||
.with_description(description),
|
||||
)?
|
||||
} else if allow_cancel {
|
||||
// Two buttons.
|
||||
LayoutObj::new(
|
||||
IconDialog::new(
|
||||
icon,
|
||||
title,
|
||||
Button::cancel_confirm(
|
||||
Button::with_icon(theme::ICON_CANCEL),
|
||||
Button::with_text(button).styled(button_style),
|
||||
false,
|
||||
),
|
||||
)
|
||||
.with_value(value)
|
||||
.with_description(description),
|
||||
)?
|
||||
} else {
|
||||
// Single button.
|
||||
LayoutObj::new(
|
||||
IconDialog::new(
|
||||
icon,
|
||||
title,
|
||||
theme::button_bar(Button::with_text(button).styled(button_style).map(|msg| {
|
||||
(matches!(msg, ButtonMsg::Clicked)).then(|| CancelConfirmMsg::Confirmed)
|
||||
})),
|
||||
)
|
||||
.with_value(value)
|
||||
.with_description(description),
|
||||
)?
|
||||
};
|
||||
|
||||
Ok(obj)
|
||||
}
|
12
core/embed/rust/src/ui/ui_features_fw.rs
Normal file
12
core/embed/rust/src/ui/ui_features_fw.rs
Normal file
@ -0,0 +1,12 @@
|
||||
use crate::{error::Error, micropython::gc::Gc, strutil::TString};
|
||||
|
||||
use super::layout::obj::{LayoutMaybeTrace, LayoutObj};
|
||||
|
||||
pub trait UIFeaturesFirmware {
|
||||
fn show_info(
|
||||
title: TString<'static>,
|
||||
description: TString<'static>,
|
||||
button: TString<'static>,
|
||||
time_ms: u32,
|
||||
) -> Result<Gc<LayoutObj>, Error>;
|
||||
}
|
@ -223,18 +223,6 @@ def show_success(
|
||||
"""Success screen. Description is used in the footer."""
|
||||
|
||||
|
||||
# rust/src/ui/model_mercury/layout.rs
|
||||
def show_info(
|
||||
*,
|
||||
title: str,
|
||||
button: str = "CONTINUE",
|
||||
description: str = "",
|
||||
allow_cancel: bool = False,
|
||||
time_ms: int = 0,
|
||||
) -> LayoutObj[UiResult]:
|
||||
"""Info modal. No buttons shown when `button` is empty string."""
|
||||
|
||||
|
||||
# rust/src/ui/model_mercury/layout.rs
|
||||
def show_mismatch(*, title: str) -> LayoutObj[UiResult]:
|
||||
"""Warning modal, receiving address mismatch."""
|
||||
@ -793,16 +781,6 @@ def show_warning(
|
||||
"""Warning modal with middle button and centered text."""
|
||||
|
||||
|
||||
# rust/src/ui/model_tr/layout.rs
|
||||
def show_info(
|
||||
*,
|
||||
title: str,
|
||||
description: str = "",
|
||||
time_ms: int = 0,
|
||||
) -> LayoutObj[UiResult]:
|
||||
"""Info modal."""
|
||||
|
||||
|
||||
# rust/src/ui/model_tr/layout.rs
|
||||
def show_passphrase() -> LayoutObj[UiResult]:
|
||||
"""Show passphrase on host dialog."""
|
||||
@ -1251,18 +1229,6 @@ def show_success(
|
||||
"""Success modal. No buttons shown when `button` is empty string."""
|
||||
|
||||
|
||||
# rust/src/ui/model_tt/layout.rs
|
||||
def show_info(
|
||||
*,
|
||||
title: str,
|
||||
button: str = "CONTINUE",
|
||||
description: str = "",
|
||||
allow_cancel: bool = False,
|
||||
time_ms: int = 0,
|
||||
) -> LayoutObj[UiResult]:
|
||||
"""Info modal. No buttons shown when `button` is empty string."""
|
||||
|
||||
|
||||
# rust/src/ui/model_tt/layout.rs
|
||||
def show_mismatch(*, title: str) -> LayoutObj[UiResult]:
|
||||
"""Warning modal, receiving address mismatch."""
|
||||
|
@ -68,6 +68,17 @@ CANCELLED: UiResult
|
||||
INFO: UiResult
|
||||
|
||||
|
||||
# rust/src/ui/api/firmware_upy.rs
|
||||
def show_info(
|
||||
*,
|
||||
title: str,
|
||||
description: str = "",
|
||||
button: str = "",
|
||||
time_ms: int = 0,
|
||||
) -> LayoutObj[UiResult]:
|
||||
"""Info screen."""
|
||||
|
||||
|
||||
# rust/src/ui/api/firmware_upy.rs
|
||||
class BacklightLevels:
|
||||
"""Backlight levels. Values dynamically update based on user settings."""
|
||||
|
@ -290,8 +290,9 @@ async def show_intro_backup(single_share: bool, num_of_words: int | None) -> Non
|
||||
description = TR.backup__info_multi_share_backup
|
||||
|
||||
await interact(
|
||||
trezorui2.show_info(
|
||||
title=TR.backup__title_create_wallet_backup, description=description
|
||||
trezorui_api.show_info(
|
||||
title=TR.backup__title_create_wallet_backup,
|
||||
description=description,
|
||||
),
|
||||
"backup_intro",
|
||||
ButtonRequestType.ResetDevice,
|
||||
|
@ -1136,7 +1136,7 @@ def error_popup(
|
||||
description = description.format(description_param)
|
||||
if subtitle:
|
||||
description = f"{subtitle}\n{description}"
|
||||
return trezorui2.show_info(
|
||||
return trezorui_api.show_info(
|
||||
title=title,
|
||||
description=description,
|
||||
time_ms=timeout_ms,
|
||||
|
@ -313,11 +313,10 @@ def show_intro_backup(single_share: bool, num_of_words: int | None) -> Awaitable
|
||||
description = TR.backup__info_multi_share_backup
|
||||
|
||||
return raise_if_not_confirmed(
|
||||
trezorui2.show_info(
|
||||
trezorui_api.show_info(
|
||||
title="",
|
||||
button=TR.buttons__continue,
|
||||
description=description,
|
||||
allow_cancel=False,
|
||||
button=TR.buttons__continue,
|
||||
),
|
||||
"backup_intro",
|
||||
ButtonRequestType.ResetDevice,
|
||||
@ -326,10 +325,10 @@ def show_intro_backup(single_share: bool, num_of_words: int | None) -> Awaitable
|
||||
|
||||
def show_warning_backup() -> Awaitable[trezorui_api.UiResult]:
|
||||
return interact(
|
||||
trezorui2.show_info(
|
||||
trezorui_api.show_info(
|
||||
title=TR.reset__never_make_digital_copy,
|
||||
description="",
|
||||
button=TR.buttons__ok_i_understand,
|
||||
allow_cancel=False,
|
||||
),
|
||||
"backup_warning",
|
||||
ButtonRequestType.ResetDevice,
|
||||
|
Loading…
Reference in New Issue
Block a user