From 106edd43097d8f71dea10979e2e4fe0718108d95 Mon Sep 17 00:00:00 2001 From: Martin Milata Date: Wed, 26 Jun 2024 11:55:15 +0200 Subject: [PATCH] feat(core/ui): T3T1: tutorial flow [no changelog] --- core/embed/rust/librust_qstr.h | 13 +- .../generated/translated_string.rs | 75 ++++-- .../component/hold_to_confirm.rs | 12 +- .../model_mercury/component/prompt_screen.rs | 18 +- .../model_mercury/component/tap_to_confirm.rs | 21 +- .../rust/src/ui/model_mercury/flow/mod.rs | 2 + .../ui/model_mercury/flow/show_tutorial.rs | 229 ++++++++++++++++++ .../embed/rust/src/ui/model_mercury/layout.rs | 4 + core/mocks/generated/trezorui2.pyi | 5 + core/mocks/trezortranslate_keys.pyi | 26 +- core/src/apps/management/show_tutorial.py | 3 - core/src/apps/workflow_handlers.py | 5 +- .../src/trezor/ui/layouts/mercury/__init__.py | 11 + core/translations/cs.json | 5 - core/translations/de.json | 5 - core/translations/en.json | 26 +- core/translations/es.json | 5 - core/translations/fr.json | 5 - core/translations/order.json | 15 +- core/translations/signatures.json | 6 +- 20 files changed, 391 insertions(+), 100 deletions(-) create mode 100644 core/embed/rust/src/ui/model_mercury/flow/show_tutorial.rs diff --git a/core/embed/rust/librust_qstr.h b/core/embed/rust/librust_qstr.h index a76997f576..f40fc1579c 100644 --- a/core/embed/rust/librust_qstr.h +++ b/core/embed/rust/librust_qstr.h @@ -281,9 +281,9 @@ static void _librust_qstrs(void) { MP_QSTR_instructions__continue_holding; MP_QSTR_instructions__continue_in_app; MP_QSTR_instructions__enter_next_share; + MP_QSTR_instructions__exit_tutorial; MP_QSTR_instructions__hold_to_confirm; MP_QSTR_instructions__hold_to_continue; - MP_QSTR_instructions__hold_to_exit_tutorial; MP_QSTR_instructions__hold_to_finish_tutorial; MP_QSTR_instructions__hold_to_sign; MP_QSTR_instructions__learn_more; @@ -663,24 +663,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__get_started; + MP_QSTR_tutorial__lets_begin; 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; diff --git a/core/embed/rust/src/translations/generated/translated_string.rs b/core/embed/rust/src/translations/generated/translated_string.rs index 0e3caf447f..1be0d1f0f0 100644 --- a/core/embed/rust/src/translations/generated/translated_string.rs +++ b/core/embed/rust/src/translations/generated/translated_string.rs @@ -1289,8 +1289,8 @@ pub enum TranslatedString { instructions__continue_holding = 888, // "Continue\nholding" instructions__enter_next_share = 889, // "Enter next share" instructions__hold_to_continue = 890, // "Hold to continue" - instructions__hold_to_exit_tutorial = 891, // "Hold to exit tutorial" - instructions__hold_to_finish_tutorial = 892, // "Hold to finish tutorial" + instructions__exit_tutorial = 891, // "Exit tutorial" + instructions__hold_to_finish_tutorial = 892, // "\"\"" instructions__learn_more = 893, // "Learn more" instructions__shares_continue_with_x_template = 894, // "Continue with Share #{0}" instructions__shares_start_with_1 = 895, // "Start with share #1" @@ -1316,15 +1316,15 @@ pub enum TranslatedString { send__transaction_signed = 915, // "Transaction signed" tutorial__continue = 916, // "Continue tutorial" 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__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__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__first_transaction_finish = 918, // "\"\"" + tutorial__first_transaction_intro = 919, // "\"\"" + tutorial__menu = 920, // "Find context-specific actions and options in the menu." + tutorial__one_more_step = 921, // "\"\"" + tutorial__ready_to_use_safe5 = 922, // "You're all set to start using your device!" + tutorial__subtitle_safe5 = 923, // "\"\"" + 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" @@ -1340,6 +1340,15 @@ pub enum TranslatedString { homescreen__settings_subtitle = 939, // "Settings" homescreen__settings_title = 940, // "Homescreen" reset__the_word_is_repeated = 941, // "The word is repeated" + tutorial__title_lets_begin = 942, // "Let's begin" + tutorial__did_you_know = 943, // "Did you know?" + tutorial__first_wallet = 944, // "The Trezor Model One, created in 2013,\nwas the world's first hardware wallet." + tutorial__restart_tutorial = 945, // "Restart tutorial" + tutorial__title_handy_menu = 946, // "Handy menu" + tutorial__title_hold = 947, // "Hold to confirm important actions" + tutorial__title_well_done = 948, // "Well done!" + tutorial__lets_begin = 949, // "Learn how to use and navigate this device with ease." + tutorial__get_started = 950, // "Get started!" } impl TranslatedString { @@ -2623,8 +2632,8 @@ impl TranslatedString { Self::instructions__continue_holding => "Continue\nholding", Self::instructions__enter_next_share => "Enter next share", Self::instructions__hold_to_continue => "Hold to continue", - Self::instructions__hold_to_exit_tutorial => "Hold to exit tutorial", - Self::instructions__hold_to_finish_tutorial => "Hold to finish tutorial", + Self::instructions__exit_tutorial => "Exit tutorial", + Self::instructions__hold_to_finish_tutorial => "\"\"", Self::instructions__learn_more => "Learn more", Self::instructions__shares_continue_with_x_template => "Continue with Share #{0}", Self::instructions__shares_start_with_1 => "Start with share #1", @@ -2650,15 +2659,15 @@ impl TranslatedString { Self::send__transaction_signed => "Transaction signed", Self::tutorial__continue => "Continue tutorial", 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__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__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__first_transaction_finish => "\"\"", + Self::tutorial__first_transaction_intro => "\"\"", + Self::tutorial__menu => "Find context-specific actions and options in the menu.", + Self::tutorial__one_more_step => "\"\"", + Self::tutorial__ready_to_use_safe5 => "You're all set to start using your device!", + Self::tutorial__subtitle_safe5 => "\"\"", + 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", @@ -2674,6 +2683,15 @@ impl TranslatedString { Self::homescreen__settings_subtitle => "Settings", Self::homescreen__settings_title => "Homescreen", Self::reset__the_word_is_repeated => "The word is repeated", + Self::tutorial__title_lets_begin => "Let's begin", + Self::tutorial__did_you_know => "Did you know?", + Self::tutorial__first_wallet => "The Trezor Model One, 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 => "Hold to confirm important actions", + Self::tutorial__title_well_done => "Well done!", + Self::tutorial__lets_begin => "Learn how to use and navigate this device with ease.", + Self::tutorial__get_started => "Get started!", } } @@ -3958,7 +3976,7 @@ impl TranslatedString { Qstr::MP_QSTR_instructions__continue_holding => Some(Self::instructions__continue_holding), Qstr::MP_QSTR_instructions__enter_next_share => Some(Self::instructions__enter_next_share), Qstr::MP_QSTR_instructions__hold_to_continue => Some(Self::instructions__hold_to_continue), - Qstr::MP_QSTR_instructions__hold_to_exit_tutorial => Some(Self::instructions__hold_to_exit_tutorial), + Qstr::MP_QSTR_instructions__exit_tutorial => Some(Self::instructions__exit_tutorial), Qstr::MP_QSTR_instructions__hold_to_finish_tutorial => Some(Self::instructions__hold_to_finish_tutorial), Qstr::MP_QSTR_instructions__learn_more => Some(Self::instructions__learn_more), Qstr::MP_QSTR_instructions__shares_continue_with_x_template => Some(Self::instructions__shares_continue_with_x_template), @@ -3992,7 +4010,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), @@ -4009,6 +4027,15 @@ impl TranslatedString { 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_reset__the_word_is_repeated => Some(Self::reset__the_word_is_repeated), + 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__get_started => Some(Self::tutorial__get_started), _ => None, } } diff --git a/core/embed/rust/src/ui/model_mercury/component/hold_to_confirm.rs b/core/embed/rust/src/ui/model_mercury/component/hold_to_confirm.rs index b91590bdf3..b8c2cc9a22 100644 --- a/core/embed/rust/src/ui/model_mercury/component/hold_to_confirm.rs +++ b/core/embed/rust/src/ui/model_mercury/component/hold_to_confirm.rs @@ -175,14 +175,8 @@ pub struct HoldToConfirm { finalizing: bool, } -#[derive(Clone)] -enum DismissType { - Tap, - Hold, -} - impl HoldToConfirm { - pub fn new() -> Self { + pub fn new(circle_color: Color, circle_inner_color: Color) -> Self { let button = Button::new(ButtonContent::Empty) .styled(theme::button_default()) .with_long_press(Duration::from_millis(2200)) @@ -195,9 +189,9 @@ impl HoldToConfirm { ) .vertically_centered(), area: Rect::zero(), - circle_color: theme::GREEN, + circle_color, circle_pad_color: theme::GREY_EXTRA_DARK, - circle_inner_color: theme::GREEN_LIGHT, + circle_inner_color, button, anim: HoldToConfirmAnim::default(), finalizing: false, diff --git a/core/embed/rust/src/ui/model_mercury/component/prompt_screen.rs b/core/embed/rust/src/ui/model_mercury/component/prompt_screen.rs index 755ef28e2c..4937c1f894 100644 --- a/core/embed/rust/src/ui/model_mercury/component/prompt_screen.rs +++ b/core/embed/rust/src/ui/model_mercury/component/prompt_screen.rs @@ -17,7 +17,11 @@ pub enum PromptScreen { impl PromptScreen { pub fn new_hold_to_confirm() -> Self { - PromptScreen::Hold(HoldToConfirm::new()) + PromptScreen::Hold(HoldToConfirm::new(theme::GREEN, theme::GREEN_LIGHT)) + } + + pub fn new_hold_to_confirm_danger() -> Self { + PromptScreen::Hold(HoldToConfirm::new(theme::ORANGE_LIGHT, theme::ORANGE_LIGHT)) } pub fn new_tap_to_confirm() -> Self { @@ -26,6 +30,7 @@ impl PromptScreen { theme::GREEN, theme::GREY_EXTRA_DARK, theme::GREEN_LIGHT, + theme::ICON_SIMPLE_CHECKMARK, )) } @@ -35,6 +40,17 @@ impl PromptScreen { theme::ORANGE_LIGHT, theme::GREY_EXTRA_DARK, theme::ORANGE_DIMMED, + theme::ICON_SIMPLE_CHECKMARK, + )) + } + + pub fn new_tap_to_start() -> Self { + PromptScreen::Tap(TapToConfirm::new( + theme::GREY, + theme::GREY, + theme::GREY_EXTRA_DARK, + theme::GREY_LIGHT, + theme::ICON_CHEVRON_RIGHT, )) } } diff --git a/core/embed/rust/src/ui/model_mercury/component/tap_to_confirm.rs b/core/embed/rust/src/ui/model_mercury/component/tap_to_confirm.rs index e56b8f6b16..51965f942f 100644 --- a/core/embed/rust/src/ui/model_mercury/component/tap_to_confirm.rs +++ b/core/embed/rust/src/ui/model_mercury/component/tap_to_confirm.rs @@ -2,7 +2,7 @@ use crate::{ time::Duration, ui::{ component::{Component, Event, EventCtx}, - display::Color, + display::{toif::Icon, Color}, geometry::{Alignment2D, Offset, Rect}, lerp::Lerp, shape, @@ -17,11 +17,11 @@ use crate::{time::Stopwatch, ui::constant::screen}; use pareen; #[derive(Default, Clone)] -struct TapToConfirmAmin { +struct TapToConfirmAnim { pub timer: Stopwatch, } -impl TapToConfirmAmin { +impl TapToConfirmAnim { const DURATION_MS: u32 = 600; pub fn is_active(&self) -> bool { @@ -121,13 +121,8 @@ pub struct TapToConfirm { circle_pad_color: Color, circle_inner_color: Color, mask_color: Color, - anim: TapToConfirmAmin, -} - -#[derive(Clone)] -enum DismissType { - Tap, - Hold, + icon: Icon, + anim: TapToConfirmAnim, } impl TapToConfirm { @@ -136,6 +131,7 @@ impl TapToConfirm { circle_inner_color: Color, circle_pad_color: Color, mask_color: Color, + icon: Icon, ) -> Self { let button = Button::new(ButtonContent::Empty).styled(theme::button_default()); Self { @@ -145,7 +141,8 @@ impl TapToConfirm { circle_pad_color, mask_color, button, - anim: TapToConfirmAmin::default(), + icon, + anim: TapToConfirmAnim::default(), } } } @@ -235,7 +232,7 @@ impl Component for TapToConfirm { .with_fg(theme::BLACK) .render(target); - shape::ToifImage::new(center, theme::ICON_SIMPLE_CHECKMARK.toif) + shape::ToifImage::new(center, self.icon.toif) .with_fg(theme::GREY) .with_alpha(255 - self.anim.get_parent_cover_opacity(t)) .with_align(Alignment2D::CENTER) diff --git a/core/embed/rust/src/ui/model_mercury/flow/mod.rs b/core/embed/rust/src/ui/model_mercury/flow/mod.rs index 726f695a60..decbd0d4ef 100644 --- a/core/embed/rust/src/ui/model_mercury/flow/mod.rs +++ b/core/embed/rust/src/ui/model_mercury/flow/mod.rs @@ -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; diff --git a/core/embed/rust/src/ui/model_mercury/flow/show_tutorial.rs b/core/embed/rust/src/ui/model_mercury/flow/show_tutorial.rs new file mode 100644 index 0000000000..79fdff291d --- /dev/null +++ b/core/embed/rust/src/ui/model_mercury/flow/show_tutorial.rs @@ -0,0 +1,229 @@ +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 { + 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 { + 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 { + let content_step_welcome = Frame::left_aligned( + TR::tutorial__welcome_safe5.into(), + SwipeContent::new(PromptScreen::new_tap_to_start()), + ) + .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__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__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_danger()), + ) + .with_footer(TR::instructions__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()) + } +} diff --git a/core/embed/rust/src/ui/model_mercury/layout.rs b/core/embed/rust/src/ui/model_mercury/layout.rs index be270ed227..5590d5fcb7 100644 --- a/core/embed/rust/src/ui/model_mercury/layout.rs +++ b/core/embed/rust/src/ui/model_mercury/layout.rs @@ -1834,6 +1834,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(), diff --git a/core/mocks/generated/trezorui2.pyi b/core/mocks/generated/trezorui2.pyi index 6cb0911cdf..31af604b90 100644 --- a/core/mocks/generated/trezorui2.pyi +++ b/core/mocks/generated/trezorui2.pyi @@ -546,6 +546,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.""" diff --git a/core/mocks/trezortranslate_keys.pyi b/core/mocks/trezortranslate_keys.pyi index 472a8870a5..085afa155e 100644 --- a/core/mocks/trezortranslate_keys.pyi +++ b/core/mocks/trezortranslate_keys.pyi @@ -378,10 +378,9 @@ class TR: instructions__continue_holding: str = "Continue\nholding" instructions__continue_in_app: str = "Continue in the app" instructions__enter_next_share: str = "Enter next share" + instructions__exit_tutorial: str = "Exit tutorial" instructions__hold_to_confirm: str = "Hold to confirm" instructions__hold_to_continue: str = "Hold to continue" - instructions__hold_to_exit_tutorial: str = "Hold to exit tutorial" - instructions__hold_to_finish_tutorial: str = "Hold to finish tutorial" instructions__hold_to_sign: str = "Hold to sign" instructions__learn_more: str = "Learn more" instructions__shares_continue_with_x_template: str = "Continue with Share #{0}" @@ -848,27 +847,32 @@ class TR: tezos__submit_proposal: str = "Submit proposal" tezos__submit_proposals: str = "Submit proposals" tutorial__continue: str = "Continue tutorial" + 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 One, created in 2013,\nwas the world's first hardware wallet." + tutorial__get_started: str = "Get started!" + tutorial__lets_begin: str = "Learn how to use and navigate this device with ease." + 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 = "Hold to confirm important actions" + 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" diff --git a/core/src/apps/management/show_tutorial.py b/core/src/apps/management/show_tutorial.py index 7f3474c94f..7634db77fc 100644 --- a/core/src/apps/management/show_tutorial.py +++ b/core/src/apps/management/show_tutorial.py @@ -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() diff --git a/core/src/apps/workflow_handlers.py b/core/src/apps/workflow_handlers.py index d8a7f32d2e..2631f614eb 100644 --- a/core/src/apps/workflow_handlers.py +++ b/core/src/apps/workflow_handlers.py @@ -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: diff --git a/core/src/trezor/ui/layouts/mercury/__init__.py b/core/src/trezor/ui/layouts/mercury/__init__.py index c955c293a3..3a1aa1d2f2 100644 --- a/core/src/trezor/ui/layouts/mercury/__init__.py +++ b/core/src/trezor/ui/layouts/mercury/__init__.py @@ -1491,3 +1491,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, + ) + ) diff --git a/core/translations/cs.json b/core/translations/cs.json index a035fa0d26..e2d26c1a53 100644 --- a/core/translations/cs.json +++ b/core/translations/cs.json @@ -415,7 +415,6 @@ "instructions__hold_to_confirm": "Držením potvrďte", "instructions__hold_to_continue": "Držením pokračujte", "instructions__hold_to_exit_tutorial": "Podržením ukončíte tutoriál", - "instructions__hold_to_finish_tutorial": "Podržením dokončíte tutoriál", "instructions__hold_to_sign": "Podržením podepíšete", "instructions__learn_more": "Zjistit více", "instructions__shares_continue_with_x_template": "Pokračujte částí č. {0}", @@ -883,16 +882,12 @@ "tezos__submit_proposals": "Odeslat návrhy", "tutorial__continue": "Pokračovat v tutoriálu", "tutorial__exit": "Ukončit tutoriál", - "tutorial__first_transaction_finish": "se uskutečnila 12. ledna 2009.", - "tutorial__first_transaction_intro": "První bitcoinová transakce na světě", "tutorial__menu": "Nabídka obsahuje kontextové akce a možnosti.", "tutorial__middle_click": "Stiskněte současně levé i pravé tlačítko\npro potvrzení.", - "tutorial__one_more_step": "Ještě jeden krok…", "tutorial__press_and_hold": "Podržením pravého tlačítka\nschválíte důležité operace.", "tutorial__ready_to_use": "Nyní můžete\npoužívat Trezor.", "tutorial__ready_to_use_safe5": "Dobrá práce!\nNyní můžete začít používat svůj Trezor Safe 5.", "tutorial__scroll_down": "Když se text nevejde na jednu obrazovku, pravým tlačítkem posunete text dolů.\n\rLevým tlačítkem se posunete nahoru.", - "tutorial__subtitle_safe5": "Tutoriál pro Trezor Safe 5", "tutorial__sure_you_want_skip": "Opravdu chcete\npřeskočit tutoriál?", "tutorial__swipe_up_and_down": "Přejetím prstem nahoru a dolů procházíte mezi obrazovkami.", "tutorial__title_hello": "Dobrý den", diff --git a/core/translations/de.json b/core/translations/de.json index a7c59a8448..172fd02ddb 100644 --- a/core/translations/de.json +++ b/core/translations/de.json @@ -415,7 +415,6 @@ "instructions__hold_to_confirm": "Zum Bestätigen halten", "instructions__hold_to_continue": "Zum Fortfahren halten", "instructions__hold_to_exit_tutorial": "Zum Verlassen des Tutorials halten", - "instructions__hold_to_finish_tutorial": "Zum Abschließen des Tutorials halten", "instructions__hold_to_sign": "Zum Signieren halten", "instructions__learn_more": "Mehr erfahren", "instructions__shares_continue_with_x_template": "Mit Share #{0} fortfahren", @@ -883,16 +882,12 @@ "tezos__submit_proposals": "Vorschläge senden", "tutorial__continue": "Tutorial fortsetzen", "tutorial__exit": "Tutorial schließen", - "tutorial__first_transaction_finish": "fand am 12. Januar 2009 statt.", - "tutorial__first_transaction_intro": "Die weltweit erste Bitcoin-Transaktion", "tutorial__menu": "Das Menü enthält kontextspezifische Aktionen und Optionen.", "tutorial__middle_click": "Drücke gleichzeitig rechts und links,\num zu bestätigen.", - "tutorial__one_more_step": "Ein Schritt noch ...", "tutorial__press_and_hold": "Halte die rechte Taste gedrückt,\num wichtige Vorgänge zu genehmigen.", "tutorial__ready_to_use": "Du kannst jetzt\nTrezor verwenden.", "tutorial__ready_to_use_safe5": "Gut gemacht!\nJetzt kannst du deinen Trezor Safe 5 verwenden.", "tutorial__scroll_down": "Drücke rechts, um nach unten zu scrollen und alles zu lesen, wenn der Text nicht auf einen Bildschirm passt.\n\rDrücke links, um nach oben zu scrollen.", - "tutorial__subtitle_safe5": "Tutorial zu Trezor Safe 5", "tutorial__sure_you_want_skip": "Möchtest du das Tutorial\nwirklich überspringen?", "tutorial__swipe_up_and_down": "Wische nach oben und unten, um Bildschirme zu wechseln.", "tutorial__title_hello": "Hallo", diff --git a/core/translations/en.json b/core/translations/en.json index f4148d799f..a38777f29c 100644 --- a/core/translations/en.json +++ b/core/translations/en.json @@ -382,8 +382,7 @@ "instructions__enter_next_share": "Enter next share", "instructions__hold_to_confirm": "Hold to confirm", "instructions__hold_to_continue": "Hold to continue", - "instructions__hold_to_exit_tutorial": "Hold to exit tutorial", - "instructions__hold_to_finish_tutorial": "Hold to finish tutorial", + "instructions__exit_tutorial": "Exit tutorial", "instructions__hold_to_sign": "Hold to sign", "instructions__learn_more": "Learn more", "instructions__shares_continue_with_x_template": "Continue with Share #{0}", @@ -850,27 +849,32 @@ "tezos__submit_proposal": "Submit proposal", "tezos__submit_proposals": "Submit proposals", "tutorial__continue": "Continue tutorial", + "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 One, created in 2013,\nwas the world's first hardware wallet.", + "tutorial__lets_begin": "Learn how to use and navigate this device with ease.", + "tutorial__get_started": "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": "Hold to confirm important actions", + "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", diff --git a/core/translations/es.json b/core/translations/es.json index c3d4e38718..7e385f1642 100644 --- a/core/translations/es.json +++ b/core/translations/es.json @@ -415,7 +415,6 @@ "instructions__hold_to_confirm": "Pulsa para confirmar", "instructions__hold_to_continue": "Pulsa para continuar", "instructions__hold_to_exit_tutorial": "Pulsa para salir del tutorial", - "instructions__hold_to_finish_tutorial": "Pulsa para finalizar el tutorial", "instructions__hold_to_sign": "Pulsa para firmar", "instructions__learn_more": "Más información", "instructions__shares_continue_with_x_template": "Continuar con el recurso n.º {0}", @@ -883,16 +882,12 @@ "tezos__submit_proposals": "Enviar propuestas", "tutorial__continue": "Continuar con el tutorial", "tutorial__exit": "Salir del tutorial", - "tutorial__first_transaction_finish": "tuvo lugar el 12 de enero de 2009.", - "tutorial__first_transaction_intro": "La primera transacción en bitcoins del mundo", "tutorial__menu": "El menú incluye funciones y opciones específicas del contexto.", "tutorial__middle_click": "Pulsa ambos botones a la vez\npara confirmar.", - "tutorial__one_more_step": "Un paso más...", "tutorial__press_and_hold": "Mantén pulsado el botón derecho para\naprobar operaciones importantes.", "tutorial__ready_to_use": "Ya puedes\nusar Trezor.", "tutorial__ready_to_use_safe5": "¡Conseguido!\nYa puedes usar Trezor Safe 5.", "tutorial__scroll_down": "Pulsa el botón derecho para ir bajando y leer todo cuando el texto no quepa en una pantalla.\n\rPulsa el botón izquierdo para ir hacia arriba.", - "tutorial__subtitle_safe5": "Tutorial de Trezor Safe 5", "tutorial__sure_you_want_skip": "¿Seguro que quieres\nomitir el tutorial?", "tutorial__swipe_up_and_down": "Desliza hacia arriba y hacia abajo para moverte por las pantallas.", "tutorial__title_hello": "Hola", diff --git a/core/translations/fr.json b/core/translations/fr.json index 180b5fb371..eeb24b93eb 100644 --- a/core/translations/fr.json +++ b/core/translations/fr.json @@ -415,7 +415,6 @@ "instructions__hold_to_confirm": "Appui pour confirmer", "instructions__hold_to_continue": "Appui pour continuer", "instructions__hold_to_exit_tutorial": "Appui pour quitter le tutoriel", - "instructions__hold_to_finish_tutorial": "Appui pour finir le tutoriel", "instructions__hold_to_sign": "Appui pour signer", "instructions__learn_more": "En savoir plus", "instructions__shares_continue_with_x_template": "Continuez avec le fragment #{0}", @@ -883,16 +882,12 @@ "tezos__submit_proposals": "Soumettre des propositions", "tutorial__continue": "Continuer le tutoriel", "tutorial__exit": "Quitter le tutoriel", - "tutorial__first_transaction_finish": "a eu lieu le 12 janvier 2009.", - "tutorial__first_transaction_intro": "La première transaction bitcoin au monde", "tutorial__menu": "Le menu comprend des actions et des options spécifiques au contexte.", "tutorial__middle_click": "App. simultanément sur les boutons gauche et droit\npour conf.", - "tutorial__one_more_step": "Encore une étape...", "tutorial__press_and_hold": "Maintenez enfoncé le bouton droit\npour accepter les choix importants.", "tutorial__ready_to_use": "Vous êtes prêt à\nutiliser Trezor.", "tutorial__ready_to_use_safe5": "Bravo !\nVous êtes prêt à utiliser votre Trezor Safe 5.", "tutorial__scroll_down": "Utilisez le bouton droit pour lire le contenu lorsqu'il dépasse.\n\rBouton gauche pour faire défiler l'écran vers le haut.", - "tutorial__subtitle_safe5": "Tutoriel Trezor Safe 5", "tutorial__sure_you_want_skip": "Voulez-vous vraiment\nignorer le tutoriel ?", "tutorial__swipe_up_and_down": "Faites glisser vers le haut ou vers le bas pour naviguer entre les écrans.", "tutorial__title_hello": "Bonjour", diff --git a/core/translations/order.json b/core/translations/order.json index 076ca0eda1..f3a3c15e15 100644 --- a/core/translations/order.json +++ b/core/translations/order.json @@ -890,7 +890,7 @@ "888": "instructions__continue_holding", "889": "instructions__enter_next_share", "890": "instructions__hold_to_continue", - "891": "instructions__hold_to_exit_tutorial", + "891": "instructions__exit_tutorial", "892": "instructions__hold_to_finish_tutorial", "893": "instructions__learn_more", "894": "instructions__shares_continue_with_x_template", @@ -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", @@ -940,5 +940,14 @@ "938": "reset__repeat_for_all_shares", "939": "homescreen__settings_subtitle", "940": "homescreen__settings_title", - "941": "reset__the_word_is_repeated" + "941": "reset__the_word_is_repeated", + "942": "tutorial__title_lets_begin", + "943": "tutorial__did_you_know", + "944": "tutorial__first_wallet", + "945": "tutorial__restart_tutorial", + "946": "tutorial__title_handy_menu", + "947": "tutorial__title_hold", + "948": "tutorial__title_well_done", + "949": "tutorial__lets_begin", + "950": "tutorial__get_started" } diff --git a/core/translations/signatures.json b/core/translations/signatures.json index cae558bf2a..72d59e63a5 100644 --- a/core/translations/signatures.json +++ b/core/translations/signatures.json @@ -1,8 +1,8 @@ { "current": { - "merkle_root": "21b44a01ac264efd5336977e2da46f69e223dd8c80071599cbf4836a53f39953", - "datetime": "2024-06-27T14:58:08.073537", - "commit": "3bf052f81a87afd9a2ac94499f095acd3971133b" + "merkle_root": "90d6cff1d798ae305bcc046a548fb6dd1e81dd1ba417c28115bc7bf8fd73bbae", + "datetime": "2024-06-30T13:54:36.644531", + "commit": "2ef7f7074a9436e1a632c90f5b721580e51269bb" }, "history": [ {