feat(core/ui): T3T1: tutorial flow

[no changelog]
Martin Milata 2 weeks ago
parent 3a039c505f
commit 7c23e52cc5

@ -660,24 +660,33 @@ static void _librust_qstrs(void) {
MP_QSTR_trezorui2;
MP_QSTR_tutorial;
MP_QSTR_tutorial__continue;
MP_QSTR_tutorial__did_you_know;
MP_QSTR_tutorial__exit;
MP_QSTR_tutorial__first_transaction_finish;
MP_QSTR_tutorial__first_transaction_intro;
MP_QSTR_tutorial__first_wallet;
MP_QSTR_tutorial__lets_begin;
MP_QSTR_tutorial__lets_get_started;
MP_QSTR_tutorial__menu;
MP_QSTR_tutorial__middle_click;
MP_QSTR_tutorial__one_more_step;
MP_QSTR_tutorial__press_and_hold;
MP_QSTR_tutorial__ready_to_use;
MP_QSTR_tutorial__ready_to_use_safe5;
MP_QSTR_tutorial__restart_tutorial;
MP_QSTR_tutorial__scroll_down;
MP_QSTR_tutorial__subtitle_safe5;
MP_QSTR_tutorial__sure_you_want_skip;
MP_QSTR_tutorial__swipe_up_and_down;
MP_QSTR_tutorial__title_easy_navigation;
MP_QSTR_tutorial__title_handy_menu;
MP_QSTR_tutorial__title_hello;
MP_QSTR_tutorial__title_navigation;
MP_QSTR_tutorial__title_hold;
MP_QSTR_tutorial__title_lets_begin;
MP_QSTR_tutorial__title_screen_scroll;
MP_QSTR_tutorial__title_skip;
MP_QSTR_tutorial__title_tutorial_complete;
MP_QSTR_tutorial__title_well_done;
MP_QSTR_tutorial__use_trezor;
MP_QSTR_tutorial__welcome_press_right;
MP_QSTR_tutorial__welcome_safe5;

@ -1314,17 +1314,17 @@ pub enum TranslatedString {
reset__slip39_checklist_num_shares_x_template = 913, // "Number of shares: {0}"
reset__slip39_checklist_threshold_x_template = 914, // "Recovery threshold: {0}"
send__transaction_signed = 915, // "Transaction signed"
tutorial__continue = 916, // "Continue tutorial"
tutorial__continue = 916, // "Continue walkthrough"
tutorial__exit = 917, // "Exit tutorial"
tutorial__first_transaction_finish = 918, // "took place on 12 January 2009."
tutorial__first_transaction_intro = 919, // "The world's first bitcoin transaction"
tutorial__menu = 920, // "Menu includes context-specific actions and options."
tutorial__menu = 920, // "Find context-specific actions and options in the menu."
tutorial__one_more_step = 921, // "One more step..."
tutorial__ready_to_use_safe5 = 922, // "Well done!\nNow you're ready to use your Trezor Safe 5."
tutorial__ready_to_use_safe5 = 922, // "You're all set to start using your device!"
tutorial__subtitle_safe5 = 923, // "Trezor Safe 5 tutorial"
tutorial__swipe_up_and_down = 924, // "Swipe up & down to move through screens."
tutorial__title_navigation = 925, // "Navigation"
tutorial__welcome_safe5 = 926, // "Welcome to Trezor Safe 5."
tutorial__swipe_up_and_down = 924, // "Swipe up & down\nto move through screens."
tutorial__title_easy_navigation = 925, // "Easy navigation"
tutorial__welcome_safe5 = 926, // "Welcome to\nTrezor Safe 5"
words__good_to_know = 927, // "Good to know"
words__operation_cancelled = 928, // "Operation cancelled"
words__settings = 929, // "Settings"
@ -1339,6 +1339,15 @@ pub enum TranslatedString {
reset__repeat_for_all_shares = 938, // "Repeat for all shares."
homescreen__settings_subtitle = 939, // "Settings"
homescreen__settings_title = 940, // "Homescreen"
tutorial__title_lets_begin = 941, // "Let's begin"
tutorial__did_you_know = 942, // "Did you know?"
tutorial__first_wallet = 943, // "The Trezor Model 1, created in 2013,\nwas the world's first hardware wallet."
tutorial__restart_tutorial = 944, // "Restart tutorial"
tutorial__title_handy_menu = 945, // "Handy menu"
tutorial__title_hold = 946, // "Important actions\nneed extra time!"
tutorial__title_well_done = 947, // "Well done!"
tutorial__lets_begin = 948, // "Time for a speedy tutorial on using this device."
tutorial__lets_get_started = 949, // "Let's get started!"
}
impl TranslatedString {
@ -2647,17 +2656,17 @@ impl TranslatedString {
Self::reset__slip39_checklist_num_shares_x_template => "Number of shares: {0}",
Self::reset__slip39_checklist_threshold_x_template => "Recovery threshold: {0}",
Self::send__transaction_signed => "Transaction signed",
Self::tutorial__continue => "Continue tutorial",
Self::tutorial__continue => "Continue walkthrough",
Self::tutorial__exit => "Exit tutorial",
Self::tutorial__first_transaction_finish => "took place on 12 January 2009.",
Self::tutorial__first_transaction_intro => "The world's first bitcoin transaction",
Self::tutorial__menu => "Menu includes context-specific actions and options.",
Self::tutorial__menu => "Find context-specific actions and options in the menu.",
Self::tutorial__one_more_step => "One more step...",
Self::tutorial__ready_to_use_safe5 => "Well done!\nNow you're ready to use your Trezor Safe 5.",
Self::tutorial__ready_to_use_safe5 => "You're all set to start using your device!",
Self::tutorial__subtitle_safe5 => "Trezor Safe 5 tutorial",
Self::tutorial__swipe_up_and_down => "Swipe up & down to move through screens.",
Self::tutorial__title_navigation => "Navigation",
Self::tutorial__welcome_safe5 => "Welcome to Trezor Safe 5.",
Self::tutorial__swipe_up_and_down => "Swipe up & down\nto move through screens.",
Self::tutorial__title_easy_navigation => "Easy navigation",
Self::tutorial__welcome_safe5 => "Welcome to\nTrezor Safe 5",
Self::words__good_to_know => "Good to know",
Self::words__operation_cancelled => "Operation cancelled",
Self::words__settings => "Settings",
@ -2672,6 +2681,15 @@ impl TranslatedString {
Self::reset__repeat_for_all_shares => "Repeat for all shares.",
Self::homescreen__settings_subtitle => "Settings",
Self::homescreen__settings_title => "Homescreen",
Self::tutorial__title_lets_begin => "Let's begin",
Self::tutorial__did_you_know => "Did you know?",
Self::tutorial__first_wallet => "The Trezor Model 1, created in 2013,\nwas the world's first hardware wallet.",
Self::tutorial__restart_tutorial => "Restart tutorial",
Self::tutorial__title_handy_menu => "Handy menu",
Self::tutorial__title_hold => "Important actions\nneed extra time!",
Self::tutorial__title_well_done => "Well done!",
Self::tutorial__lets_begin => "Time for a speedy tutorial on using this device.",
Self::tutorial__lets_get_started => "Let's get started!",
}
}
@ -3990,7 +4008,7 @@ impl TranslatedString {
Qstr::MP_QSTR_tutorial__ready_to_use_safe5 => Some(Self::tutorial__ready_to_use_safe5),
Qstr::MP_QSTR_tutorial__subtitle_safe5 => Some(Self::tutorial__subtitle_safe5),
Qstr::MP_QSTR_tutorial__swipe_up_and_down => Some(Self::tutorial__swipe_up_and_down),
Qstr::MP_QSTR_tutorial__title_navigation => Some(Self::tutorial__title_navigation),
Qstr::MP_QSTR_tutorial__title_easy_navigation => Some(Self::tutorial__title_easy_navigation),
Qstr::MP_QSTR_tutorial__welcome_safe5 => Some(Self::tutorial__welcome_safe5),
Qstr::MP_QSTR_words__good_to_know => Some(Self::words__good_to_know),
Qstr::MP_QSTR_words__operation_cancelled => Some(Self::words__operation_cancelled),
@ -4006,6 +4024,15 @@ impl TranslatedString {
Qstr::MP_QSTR_reset__repeat_for_all_shares => Some(Self::reset__repeat_for_all_shares),
Qstr::MP_QSTR_homescreen__settings_subtitle => Some(Self::homescreen__settings_subtitle),
Qstr::MP_QSTR_homescreen__settings_title => Some(Self::homescreen__settings_title),
Qstr::MP_QSTR_tutorial__title_lets_begin => Some(Self::tutorial__title_lets_begin),
Qstr::MP_QSTR_tutorial__did_you_know => Some(Self::tutorial__did_you_know),
Qstr::MP_QSTR_tutorial__first_wallet => Some(Self::tutorial__first_wallet),
Qstr::MP_QSTR_tutorial__restart_tutorial => Some(Self::tutorial__restart_tutorial),
Qstr::MP_QSTR_tutorial__title_handy_menu => Some(Self::tutorial__title_handy_menu),
Qstr::MP_QSTR_tutorial__title_hold => Some(Self::tutorial__title_hold),
Qstr::MP_QSTR_tutorial__title_well_done => Some(Self::tutorial__title_well_done),
Qstr::MP_QSTR_tutorial__lets_begin => Some(Self::tutorial__lets_begin),
Qstr::MP_QSTR_tutorial__lets_get_started => Some(Self::tutorial__lets_get_started),
_ => None,
}
}

@ -8,6 +8,7 @@ pub mod get_address;
pub mod prompt_backup;
pub mod request_number;
pub mod show_share_words;
pub mod show_tutorial;
pub mod warning_hi_prio;
pub use confirm_action::{new_confirm_action, new_confirm_action_simple};
@ -22,4 +23,5 @@ pub use get_address::GetAddress;
pub use prompt_backup::PromptBackup;
pub use request_number::RequestNumber;
pub use show_share_words::ShowShareWords;
pub use show_tutorial::ShowTutorial;
pub use warning_hi_prio::WarningHiPrio;

@ -0,0 +1,230 @@
use crate::{
error,
translations::TR,
ui::{
component::{
swipe_detect::SwipeSettings,
text::paragraphs::{Paragraph, Paragraphs},
ComponentExt, SwipeDirection,
},
flow::{base::Decision, flow_store, FlowMsg, FlowState, FlowStore, SwipeFlow},
layout::obj::LayoutObj,
model_mercury::component::SwipeContent,
},
};
use super::super::{
component::{Frame, FrameMsg, PromptScreen, VerticalMenu, VerticalMenuChoiceMsg},
theme,
};
#[derive(Copy, Clone, PartialEq, Eq, ToPrimitive)]
pub enum ShowTutorial {
StepWelcome,
StepBegin,
StepNavigation,
StepMenu,
StepHold,
StepDone,
Menu,
DidYouKnow,
HoldToExit,
}
impl FlowState for ShowTutorial {
fn handle_swipe(&self, direction: SwipeDirection) -> Decision<Self> {
match (self, direction) {
(ShowTutorial::StepBegin, SwipeDirection::Up) => {
Decision::Goto(ShowTutorial::StepNavigation, direction)
}
(ShowTutorial::StepNavigation, SwipeDirection::Up) => {
Decision::Goto(ShowTutorial::StepMenu, direction)
}
(ShowTutorial::StepNavigation, SwipeDirection::Down) => {
Decision::Goto(ShowTutorial::StepBegin, direction)
}
(ShowTutorial::StepMenu, SwipeDirection::Up) => {
Decision::Goto(ShowTutorial::StepHold, direction)
}
(ShowTutorial::StepMenu, SwipeDirection::Down) => {
Decision::Goto(ShowTutorial::StepNavigation, direction)
}
(ShowTutorial::StepMenu, SwipeDirection::Left) => {
Decision::Goto(ShowTutorial::Menu, direction)
}
(ShowTutorial::Menu, SwipeDirection::Left) => {
Decision::Goto(ShowTutorial::DidYouKnow, direction)
}
(ShowTutorial::Menu, SwipeDirection::Right) => {
Decision::Goto(ShowTutorial::StepBegin, direction)
}
(ShowTutorial::DidYouKnow, SwipeDirection::Right) => {
Decision::Goto(ShowTutorial::Menu, direction)
}
(ShowTutorial::StepDone, SwipeDirection::Up) => Decision::Return(FlowMsg::Confirmed),
_ => Decision::Nothing,
}
}
fn handle_event(&self, msg: FlowMsg) -> Decision<Self> {
match (self, msg) {
(ShowTutorial::StepWelcome, FlowMsg::Confirmed) => {
Decision::Goto(ShowTutorial::StepBegin, SwipeDirection::Up)
}
(ShowTutorial::StepMenu, FlowMsg::Info) => {
Decision::Goto(ShowTutorial::Menu, SwipeDirection::Left)
}
(ShowTutorial::Menu, FlowMsg::Choice(0)) => {
Decision::Goto(ShowTutorial::DidYouKnow, SwipeDirection::Left)
}
(ShowTutorial::Menu, FlowMsg::Choice(1)) => {
Decision::Goto(ShowTutorial::StepBegin, SwipeDirection::Right)
}
(ShowTutorial::Menu, FlowMsg::Choice(2)) => {
Decision::Goto(ShowTutorial::HoldToExit, SwipeDirection::Up)
}
(ShowTutorial::Menu, FlowMsg::Cancelled) => {
Decision::Goto(ShowTutorial::StepMenu, SwipeDirection::Right)
}
(ShowTutorial::DidYouKnow, FlowMsg::Cancelled) => {
Decision::Goto(ShowTutorial::Menu, SwipeDirection::Right)
}
(ShowTutorial::StepHold, FlowMsg::Confirmed) => {
Decision::Goto(ShowTutorial::StepDone, SwipeDirection::Up)
}
(ShowTutorial::HoldToExit, FlowMsg::Confirmed) => {
Decision::Goto(ShowTutorial::StepDone, SwipeDirection::Up)
}
_ => Decision::Nothing,
}
}
}
use crate::micropython::{map::Map, obj::Obj, util};
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub extern "C" fn new_show_tutorial(_n_args: usize, _args: *const Obj, _kwargs: *mut Map) -> Obj {
unsafe { util::try_or_raise(ShowTutorial::new_obj) }
}
impl ShowTutorial {
fn new_obj() -> Result<Obj, error::Error> {
let content_step_welcome = Frame::left_aligned(
TR::tutorial__welcome_safe5.into(),
SwipeContent::new(PromptScreen::new_tap_to_confirm()), /* FIXME: grey circle,
* chevron_right */
)
.with_footer(TR::instructions__tap_to_start.into(), None)
.map(|msg| matches!(msg, FrameMsg::Content(())).then_some(FlowMsg::Confirmed));
let content_step_begin = Frame::left_aligned(
TR::tutorial__title_lets_begin.into(),
SwipeContent::new(Paragraphs::new(Paragraph::new(
&theme::TEXT_MAIN_GREY_LIGHT,
TR::tutorial__lets_begin,
))),
)
.with_footer(
TR::instructions__swipe_up.into(),
Some(TR::tutorial__lets_get_started.into()),
)
.with_swipe(SwipeDirection::Up, SwipeSettings::default())
.map(|_| None);
let content_step_navigation = Frame::left_aligned(
TR::tutorial__title_easy_navigation.into(),
SwipeContent::new(Paragraphs::new(Paragraph::new(
&theme::TEXT_MAIN_GREY_LIGHT,
TR::tutorial__swipe_up_and_down,
))),
)
.with_footer(
TR::instructions__swipe_up.into(),
Some(TR::tutorial__continue.into()),
)
.with_swipe(SwipeDirection::Up, SwipeSettings::default())
.with_swipe(SwipeDirection::Down, SwipeSettings::default())
.map(|_| None);
let content_step_menu = Frame::left_aligned(
TR::tutorial__title_handy_menu.into(),
SwipeContent::new(Paragraphs::new(Paragraph::new(
&theme::TEXT_MAIN_GREY_LIGHT,
TR::tutorial__menu,
))),
)
.with_menu_button()
.button_styled(theme::button_warning_low())
.with_footer(
TR::instructions__swipe_up.into(),
Some(TR::buttons__continue.into()),
)
.with_swipe(SwipeDirection::Up, SwipeSettings::default())
.with_swipe(SwipeDirection::Down, SwipeSettings::default())
.map(|msg| matches!(msg, FrameMsg::Button(_)).then_some(FlowMsg::Info));
let content_step_hold = Frame::left_aligned(
TR::tutorial__title_hold.into(),
SwipeContent::new(PromptScreen::new_hold_to_confirm()),
)
.with_footer(TR::instructions__hold_to_exit_tutorial.into(), None)
.map(|msg| matches!(msg, FrameMsg::Content(())).then_some(FlowMsg::Confirmed));
let content_step_done = Frame::left_aligned(
TR::tutorial__title_well_done.into(),
SwipeContent::new(Paragraphs::new(Paragraph::new(
&theme::TEXT_MAIN_GREY_LIGHT,
TR::tutorial__ready_to_use_safe5,
))),
)
.with_footer(TR::instructions__swipe_up.into(), None)
.with_swipe(SwipeDirection::Up, SwipeSettings::default())
.map(|_| None);
let content_menu = Frame::left_aligned(
"".into(),
VerticalMenu::empty()
.item(theme::ICON_CHEVRON_RIGHT, TR::tutorial__did_you_know.into())
.item(theme::ICON_REBOOT, TR::tutorial__restart_tutorial.into())
.danger(theme::ICON_CANCEL, TR::tutorial__exit.into()),
)
.with_cancel_button()
.with_swipe(SwipeDirection::Right, SwipeSettings::immediate())
.with_swipe(SwipeDirection::Left, SwipeSettings::immediate())
.map(|msg| match msg {
FrameMsg::Content(VerticalMenuChoiceMsg::Selected(i)) => Some(FlowMsg::Choice(i)),
FrameMsg::Button(_) => Some(FlowMsg::Cancelled),
});
let content_did_you_know = Frame::left_aligned(
"".into(),
SwipeContent::new(Paragraphs::new(Paragraph::new(
&theme::TEXT_MAIN_GREY_LIGHT,
TR::tutorial__first_wallet,
))),
)
.with_cancel_button()
.with_swipe(SwipeDirection::Right, SwipeSettings::immediate())
.map(|msg| matches!(msg, FrameMsg::Button(_)).then_some(FlowMsg::Cancelled));
let content_hold_to_exit = Frame::left_aligned(
TR::tutorial__title_hold.into(),
SwipeContent::new(PromptScreen::new_hold_to_confirm()), // FIXME: style
)
.with_footer(TR::instructions__hold_to_exit_tutorial.into(), None)
.map(|msg| matches!(msg, FrameMsg::Content(())).then_some(FlowMsg::Confirmed));
let store = flow_store()
.add(content_step_welcome)?
.add(content_step_begin)?
.add(content_step_navigation)?
.add(content_step_menu)?
.add(content_step_hold)?
.add(content_step_done)?
.add(content_menu)?
.add(content_did_you_know)?
.add(content_hold_to_exit)?;
let res = SwipeFlow::new(ShowTutorial::StepWelcome, store)?;
Ok(LayoutObj::new(res)?.into())
}
}

@ -1831,6 +1831,10 @@ pub static mp_module_trezorui2: Module = obj_module! {
/// """Ask whether to update firmware, optionally show fingerprint. Shared with bootloader."""
Qstr::MP_QSTR_confirm_firmware_update => obj_fn_kw!(0, new_confirm_firmware_update).as_obj(),
/// def tutorial() -> LayoutObj[UiResult]:
/// """Show user how to interact with the device."""
Qstr::MP_QSTR_tutorial => obj_fn_kw!(0, flow::show_tutorial::new_show_tutorial).as_obj(), // FIXME turn this into obj_fn_0, T2B1 as well
/// def show_wait_text(message: str, /) -> LayoutObj[None]:
/// """Show single-line text in the middle of the screen."""
Qstr::MP_QSTR_show_wait_text => obj_fn_1!(new_show_wait_text).as_obj(),

@ -538,6 +538,11 @@ def confirm_firmware_update(
"""Ask whether to update firmware, optionally show fingerprint. Shared with bootloader."""
# rust/src/ui/model_mercury/layout.rs
def tutorial() -> LayoutObj[UiResult]:
"""Show user how to interact with the device."""
# rust/src/ui/model_mercury/layout.rs
def show_wait_text(message: str, /) -> LayoutObj[None]:
"""Show single-line text in the middle of the screen."""

@ -846,28 +846,37 @@ class TR:
tezos__submit_ballot: str = "Submit ballot"
tezos__submit_proposal: str = "Submit proposal"
tezos__submit_proposals: str = "Submit proposals"
tutorial__continue: str = "Continue tutorial"
tutorial__continue: str = "Continue walkthrough"
tutorial__did_you_know: str = "Did you know?"
tutorial__exit: str = "Exit tutorial"
tutorial__first_transaction_finish: str = "took place on 12 January 2009."
tutorial__first_transaction_intro: str = "The world's first bitcoin transaction"
tutorial__menu: str = "Menu includes context-specific actions and options."
tutorial__first_wallet: str = "The Trezor Model 1, created in 2013,\nwas the world's first hardware wallet."
tutorial__lets_begin: str = "Time for a speedy tutorial on using this device."
tutorial__lets_get_started: str = "Let's get started!"
tutorial__menu: str = "Find context-specific actions and options in the menu."
tutorial__middle_click: str = "Press both left and right at the same\ntime to confirm."
tutorial__one_more_step: str = "One more step..."
tutorial__press_and_hold: str = "Press and hold the right button to\napprove important operations."
tutorial__ready_to_use: str = "You're ready to\nuse Trezor."
tutorial__ready_to_use_safe5: str = "Well done!\nNow you're ready to use your Trezor Safe 5."
tutorial__ready_to_use_safe5: str = "You're all set to start using your device!"
tutorial__restart_tutorial: str = "Restart tutorial"
tutorial__scroll_down: str = "Press right to scroll down to read all content when text doesn't fit on one screen.\n\rPress left to scroll up."
tutorial__subtitle_safe5: str = "Trezor Safe 5 tutorial"
tutorial__sure_you_want_skip: str = "Are you sure you\nwant to skip the tutorial?"
tutorial__swipe_up_and_down: str = "Swipe up & down to move through screens."
tutorial__swipe_up_and_down: str = "Swipe up & down\nto move through screens."
tutorial__title_easy_navigation: str = "Easy navigation"
tutorial__title_handy_menu: str = "Handy menu"
tutorial__title_hello: str = "Hello"
tutorial__title_navigation: str = "Navigation"
tutorial__title_hold: str = "Important actions\nneed extra time!"
tutorial__title_lets_begin: str = "Let's begin"
tutorial__title_screen_scroll: str = "Screen scroll"
tutorial__title_skip: str = "Skip tutorial"
tutorial__title_tutorial_complete: str = "Tutorial complete"
tutorial__title_well_done: str = "Well done!"
tutorial__use_trezor: str = "Use Trezor by\nclicking the left and right buttons.\n\rContinue right."
tutorial__welcome_press_right: str = "Welcome to Trezor. Press right to continue."
tutorial__welcome_safe5: str = "Welcome to Trezor Safe 5."
tutorial__welcome_safe5: str = "Welcome to\nTrezor Safe 5"
u2f__get: str = "Increase and retrieve the U2F counter?"
u2f__set_template: str = "Set the U2F counter to {0}?"
u2f__title_get: str = "Get U2F counter"

@ -6,9 +6,6 @@ if TYPE_CHECKING:
async def show_tutorial(msg: ShowDeviceTutorial) -> Success:
from trezor.messages import Success
# NOTE: tutorial is defined only for TR, and this function should
# also be called only in case of TR
from trezor.ui.layouts import tutorial
await tutorial()

@ -55,7 +55,10 @@ def _find_message_handler_module(msg_type: int) -> str:
if msg_type == MessageType.RebootToBootloader:
return "apps.management.reboot_to_bootloader"
if utils.INTERNAL_MODEL in ("T2B1",) and msg_type == MessageType.ShowDeviceTutorial:
if (
utils.INTERNAL_MODEL in ("T2B1", "T3T1")
and msg_type == MessageType.ShowDeviceTutorial
):
return "apps.management.show_tutorial"
if utils.USE_BACKLIGHT and msg_type == MessageType.SetBrightness:

@ -1487,3 +1487,14 @@ async def set_brightness(current: int | None = None) -> None:
"set_brightness",
BR_TYPE_OTHER,
)
def tutorial(br_code: ButtonRequestType = BR_TYPE_OTHER) -> Awaitable[None]:
"""Showing users how to interact with the device."""
return raise_if_not_confirmed(
interact(
RustLayout(trezorui2.tutorial()),
"tutorial",
br_code,
)
)

@ -848,28 +848,37 @@
"tezos__submit_ballot": "Submit ballot",
"tezos__submit_proposal": "Submit proposal",
"tezos__submit_proposals": "Submit proposals",
"tutorial__continue": "Continue tutorial",
"tutorial__continue": "Continue walkthrough",
"tutorial__did_you_know": "Did you know?",
"tutorial__exit": "Exit tutorial",
"tutorial__first_transaction_finish": "took place on 12 January 2009.",
"tutorial__first_transaction_intro": "The world's first bitcoin transaction",
"tutorial__menu": "Menu includes context-specific actions and options.",
"tutorial__first_wallet": "The Trezor Model 1, created in 2013,\nwas the world's first hardware wallet.",
"tutorial__lets_begin": "Time for a speedy tutorial on using this device.",
"tutorial__lets_get_started": "Let's get started!",
"tutorial__menu": "Find context-specific actions and options in the menu.",
"tutorial__middle_click": "Press both left and right at the same\ntime to confirm.",
"tutorial__one_more_step": "One more step...",
"tutorial__press_and_hold": "Press and hold the right button to\napprove important operations.",
"tutorial__ready_to_use": "You're ready to\nuse Trezor.",
"tutorial__ready_to_use_safe5": "Well done!\nNow you're ready to use your Trezor Safe 5.",
"tutorial__ready_to_use_safe5": "You're all set to start using your device!",
"tutorial__restart_tutorial": "Restart tutorial",
"tutorial__scroll_down": "Press right to scroll down to read all content when text doesn't fit on one screen.\n\rPress left to scroll up.",
"tutorial__subtitle_safe5": "Trezor Safe 5 tutorial",
"tutorial__sure_you_want_skip": "Are you sure you\nwant to skip the tutorial?",
"tutorial__swipe_up_and_down": "Swipe up & down to move through screens.",
"tutorial__swipe_up_and_down": "Swipe up & down\nto move through screens.",
"tutorial__title_handy_menu": "Handy menu",
"tutorial__title_hello": "Hello",
"tutorial__title_navigation": "Navigation",
"tutorial__title_hold": "Important actions\nneed extra time!",
"tutorial__title_lets_begin": "Let's begin",
"tutorial__title_easy_navigation": "Easy navigation",
"tutorial__title_screen_scroll": "Screen scroll",
"tutorial__title_skip": "Skip tutorial",
"tutorial__title_tutorial_complete": "Tutorial complete",
"tutorial__title_well_done": "Well done!",
"tutorial__use_trezor": "Use Trezor by\nclicking the left and right buttons.\n\rContinue right.",
"tutorial__welcome_press_right": "Welcome to Trezor. Press right to continue.",
"tutorial__welcome_safe5": "Welcome to Trezor Safe 5.",
"tutorial__welcome_safe5": "Welcome to\nTrezor Safe 5",
"u2f__get": "Increase and retrieve the U2F counter?",
"u2f__set_template": "Set the U2F counter to {0}?",
"u2f__title_get": "Get U2F counter",

@ -924,7 +924,7 @@
"922": "tutorial__ready_to_use_safe5",
"923": "tutorial__subtitle_safe5",
"924": "tutorial__swipe_up_and_down",
"925": "tutorial__title_navigation",
"925": "tutorial__title_easy_navigation",
"926": "tutorial__welcome_safe5",
"927": "words__good_to_know",
"928": "words__operation_cancelled",
@ -939,5 +939,14 @@
"937": "reset__words_may_repeat",
"938": "reset__repeat_for_all_shares",
"939": "homescreen__settings_subtitle",
"940": "homescreen__settings_title"
"940": "homescreen__settings_title",
"941": "tutorial__title_lets_begin",
"942": "tutorial__did_you_know",
"943": "tutorial__first_wallet",
"944": "tutorial__restart_tutorial",
"945": "tutorial__title_handy_menu",
"946": "tutorial__title_hold",
"947": "tutorial__title_well_done",
"948": "tutorial__lets_begin",
"949": "tutorial__lets_get_started"
}

@ -1,8 +1,8 @@
{
"current": {
"merkle_root": "5b5781c3374ff27125228c121ab97436a2ba1f0581657ee56b9fa601fe3bde97",
"datetime": "2024-06-24T13:47:55.544267",
"commit": "d79768cec726c26ac1f82e62fc71b6d4568786a2"
"merkle_root": "bf8e8bc9f411fd9c96abfe7a13ef4a38640b0bdc940416ce48fa1e399fb0d65f",
"datetime": "2024-06-26T09:00:51.554147",
"commit": "95c2cb2008a298d4ac78977bb43b437d516a7abf"
},
"history": [
{

Loading…
Cancel
Save