mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-01-30 01:01:00 +00:00
fix(core/mercury): change status screen - display message in center after animation
Because some messages didn't fit the title
This commit is contained in:
parent
747303fd39
commit
f2bdd6e189
1
core/.changelog.d/4023.fixed
Normal file
1
core/.changelog.d/4023.fixed
Normal file
@ -0,0 +1 @@
|
||||
[T3T1] Fixed title sometimes not fitting into result screen
|
@ -771,6 +771,7 @@ static void _librust_qstrs(void) {
|
||||
MP_QSTR_words__sign;
|
||||
MP_QSTR_words__signer;
|
||||
MP_QSTR_words__title_check;
|
||||
MP_QSTR_words__title_done;
|
||||
MP_QSTR_words__title_group;
|
||||
MP_QSTR_words__title_information;
|
||||
MP_QSTR_words__title_remember;
|
||||
|
@ -1354,6 +1354,7 @@ pub enum TranslatedString {
|
||||
setting__apply = 953, // "Apply"
|
||||
brightness__changed_title = 954, // "Display brightness changed"
|
||||
brightness__change_title = 955, // "Change display brightness"
|
||||
words__title_done = 956, // "Done"
|
||||
}
|
||||
|
||||
impl TranslatedString {
|
||||
@ -2702,6 +2703,7 @@ impl TranslatedString {
|
||||
Self::setting__apply => "Apply",
|
||||
Self::brightness__changed_title => "Display brightness changed",
|
||||
Self::brightness__change_title => "Change display brightness",
|
||||
Self::words__title_done => "Done",
|
||||
}
|
||||
}
|
||||
|
||||
@ -4051,6 +4053,7 @@ impl TranslatedString {
|
||||
Qstr::MP_QSTR_setting__apply => Some(Self::setting__apply),
|
||||
Qstr::MP_QSTR_brightness__changed_title => Some(Self::brightness__changed_title),
|
||||
Qstr::MP_QSTR_brightness__change_title => Some(Self::brightness__change_title),
|
||||
Qstr::MP_QSTR_words__title_done => Some(Self::words__title_done),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
use super::{theme, ButtonMsg, ButtonStyleSheet, CancelInfoConfirmMsg, Footer, Header};
|
||||
use crate::{
|
||||
strutil::TString,
|
||||
ui::{
|
||||
@ -8,7 +9,7 @@ use crate::{
|
||||
Event::Swipe,
|
||||
EventCtx, SwipeDetect, SwipeDirection,
|
||||
},
|
||||
display::Icon,
|
||||
display::{Color, Icon},
|
||||
event::SwipeEvent,
|
||||
geometry::{Alignment, Insets, Point, Rect},
|
||||
lerp::Lerp,
|
||||
@ -18,8 +19,6 @@ use crate::{
|
||||
},
|
||||
};
|
||||
|
||||
use super::{theme, ButtonMsg, ButtonStyleSheet, CancelInfoConfirmMsg, Footer, Header};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct HorizontalSwipe {
|
||||
progress: i16,
|
||||
@ -179,6 +178,11 @@ where
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_result_icon(mut self, icon: Icon, color: Color) -> Self {
|
||||
self.header = self.header.with_result_icon(icon, color);
|
||||
self
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub fn with_footer(
|
||||
mut self,
|
||||
|
@ -1,18 +1,65 @@
|
||||
use crate::{
|
||||
strutil::TString,
|
||||
time::{Duration, Stopwatch},
|
||||
ui::{
|
||||
component::{text::TextStyle, Component, Event, EventCtx, Label},
|
||||
display::Icon,
|
||||
geometry::{Alignment, Insets, Rect},
|
||||
display::{Color, Icon},
|
||||
geometry::{Alignment, Alignment2D, Insets, Offset, Rect},
|
||||
lerp::Lerp,
|
||||
model_mercury::{
|
||||
component::{Button, ButtonMsg, ButtonStyleSheet},
|
||||
theme,
|
||||
theme::TITLE_HEIGHT,
|
||||
},
|
||||
shape,
|
||||
shape::Renderer,
|
||||
util::animation_disabled,
|
||||
},
|
||||
};
|
||||
|
||||
const ANIMATION_TIME_MS: u32 = 1000;
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
struct AttachAnimation {
|
||||
pub timer: Stopwatch,
|
||||
}
|
||||
|
||||
impl AttachAnimation {
|
||||
pub fn is_active(&self) -> bool {
|
||||
if animation_disabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
self.timer
|
||||
.is_running_within(Duration::from_millis(ANIMATION_TIME_MS))
|
||||
}
|
||||
|
||||
pub fn eval(&self) -> f32 {
|
||||
if animation_disabled() {
|
||||
return ANIMATION_TIME_MS as f32 / 1000.0;
|
||||
}
|
||||
self.timer.elapsed().to_millis() as f32 / 1000.0
|
||||
}
|
||||
|
||||
pub fn get_title_offset(&self, t: f32) -> i16 {
|
||||
let fnc = pareen::constant(0.0).seq_ease_in_out(
|
||||
0.8,
|
||||
easer::functions::Cubic,
|
||||
0.2,
|
||||
pareen::constant(1.0),
|
||||
);
|
||||
i16::lerp(0, 25, fnc.eval(t))
|
||||
}
|
||||
|
||||
pub fn start(&mut self) {
|
||||
self.timer.start();
|
||||
}
|
||||
|
||||
pub fn reset(&mut self) {
|
||||
self.timer = Stopwatch::new_stopped();
|
||||
}
|
||||
}
|
||||
|
||||
const BUTTON_EXPAND_BORDER: i16 = 32;
|
||||
#[derive(Clone)]
|
||||
pub struct Header {
|
||||
@ -20,6 +67,10 @@ pub struct Header {
|
||||
title: Label<'static>,
|
||||
subtitle: Option<Label<'static>>,
|
||||
button: Option<Button>,
|
||||
anim: Option<AttachAnimation>,
|
||||
icon: Option<Icon>,
|
||||
color: Option<Color>,
|
||||
title_style: TextStyle,
|
||||
}
|
||||
|
||||
impl Header {
|
||||
@ -29,32 +80,37 @@ impl Header {
|
||||
title: Label::new(title, alignment, theme::label_title_main()).vertically_centered(),
|
||||
subtitle: None,
|
||||
button: None,
|
||||
anim: None,
|
||||
icon: None,
|
||||
color: None,
|
||||
title_style: theme::label_title_main(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub fn with_subtitle(mut self, subtitle: TString<'static>) -> Self {
|
||||
let style = theme::TEXT_SUB_GREY;
|
||||
self.title = self.title.top_aligned();
|
||||
self.subtitle = Some(Label::new(subtitle, self.title.alignment(), style));
|
||||
self
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub fn styled(mut self, style: TextStyle) -> Self {
|
||||
self.title_style = style;
|
||||
self.title = self.title.styled(style);
|
||||
self
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub fn subtitle_styled(mut self, style: TextStyle) -> Self {
|
||||
if let Some(subtitle) = self.subtitle.take() {
|
||||
self.subtitle = Some(subtitle.styled(style))
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub fn update_title(&mut self, title: TString<'static>) {
|
||||
self.title.set_text(title);
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub fn update_subtitle(
|
||||
&mut self,
|
||||
new_subtitle: TString<'static>,
|
||||
@ -72,6 +128,7 @@ impl Header {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub fn with_button(mut self, icon: Icon, enabled: bool) -> Self {
|
||||
let touch_area = Insets::uniform(BUTTON_EXPAND_BORDER);
|
||||
self.button = Some(
|
||||
@ -82,6 +139,7 @@ impl Header {
|
||||
);
|
||||
self
|
||||
}
|
||||
#[inline(never)]
|
||||
|
||||
pub fn button_styled(mut self, style: ButtonStyleSheet) -> Self {
|
||||
if self.button.is_some() {
|
||||
@ -89,6 +147,16 @@ impl Header {
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub fn with_result_icon(mut self, icon: Icon, color: Color) -> Self {
|
||||
self.anim = Some(AttachAnimation::default());
|
||||
self.icon = Some(icon);
|
||||
self.color = Some(color);
|
||||
let mut title_style = self.title_style;
|
||||
title_style.text_color = color;
|
||||
self.styled(title_style)
|
||||
}
|
||||
}
|
||||
|
||||
impl Component for Header {
|
||||
@ -111,6 +179,7 @@ impl Component for Header {
|
||||
self.title.place(header_area);
|
||||
}
|
||||
|
||||
self.area = bounds;
|
||||
bounds
|
||||
}
|
||||
|
||||
@ -118,6 +187,20 @@ impl Component for Header {
|
||||
self.title.event(ctx, event);
|
||||
self.subtitle.event(ctx, event);
|
||||
|
||||
if let Some(anim) = &mut self.anim {
|
||||
if let Event::Attach(_) = event {
|
||||
anim.start();
|
||||
ctx.request_paint();
|
||||
ctx.request_anim_frame();
|
||||
}
|
||||
if let Event::Timer(EventCtx::ANIM_FRAME_TIMER) = event {
|
||||
if anim.is_active() {
|
||||
ctx.request_anim_frame();
|
||||
ctx.request_paint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.button.event(ctx, event)
|
||||
}
|
||||
|
||||
@ -126,9 +209,28 @@ impl Component for Header {
|
||||
}
|
||||
|
||||
fn render<'s>(&'s self, target: &mut impl Renderer<'s>) {
|
||||
let offset = if let Some(anim) = &self.anim {
|
||||
Offset::x(anim.get_title_offset(anim.eval()))
|
||||
} else {
|
||||
Offset::zero()
|
||||
};
|
||||
|
||||
self.button.render(target);
|
||||
self.title.render(target);
|
||||
self.subtitle.render(target);
|
||||
|
||||
target.in_clip(self.area.split_left(offset.x).0, &|target| {
|
||||
if let Some(icon) = self.icon {
|
||||
let color = self.color.unwrap_or(theme::GREEN);
|
||||
shape::ToifImage::new(self.title.area().left_center(), icon.toif)
|
||||
.with_fg(color)
|
||||
.with_align(Alignment2D::CENTER_LEFT)
|
||||
.render(target);
|
||||
}
|
||||
});
|
||||
|
||||
target.with_origin(offset, &|target| {
|
||||
self.title.render(target);
|
||||
self.subtitle.render(target);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,12 @@
|
||||
use super::theme;
|
||||
use crate::{
|
||||
strutil::TString,
|
||||
time::{Duration, Stopwatch},
|
||||
ui::{
|
||||
component::{Component, Event, EventCtx, Timeout},
|
||||
component::{Component, Event, EventCtx, Label, Timeout},
|
||||
constant::screen,
|
||||
display::{Color, Icon},
|
||||
geometry::{Alignment2D, Insets, Rect},
|
||||
geometry::{Alignment, Alignment2D, Insets, Point, Rect},
|
||||
lerp::Lerp,
|
||||
shape,
|
||||
shape::Renderer,
|
||||
@ -12,9 +14,8 @@ use crate::{
|
||||
},
|
||||
};
|
||||
|
||||
use super::theme;
|
||||
|
||||
const TIMEOUT_MS: u32 = 2000;
|
||||
const ANIMATION_TIME_MS: u32 = 1200;
|
||||
const TIMEOUT_MS: u32 = ANIMATION_TIME_MS + 2000;
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
struct StatusAnimation {
|
||||
@ -28,12 +29,12 @@ impl StatusAnimation {
|
||||
}
|
||||
|
||||
self.timer
|
||||
.is_running_within(Duration::from_millis(TIMEOUT_MS))
|
||||
.is_running_within(Duration::from_millis(ANIMATION_TIME_MS))
|
||||
}
|
||||
|
||||
pub fn eval(&self) -> f32 {
|
||||
if animation_disabled() {
|
||||
return TIMEOUT_MS as f32 / 1000.0;
|
||||
return ANIMATION_TIME_MS as f32 / 1000.0;
|
||||
}
|
||||
self.timer.elapsed().to_millis() as f32 / 1000.0
|
||||
}
|
||||
@ -67,14 +68,54 @@ impl StatusAnimation {
|
||||
pareen::constant(1.0),
|
||||
);
|
||||
|
||||
let circle_scale2 = pareen::constant(0.0).seq_ease_out(
|
||||
0.8,
|
||||
easer::functions::Linear,
|
||||
0.2,
|
||||
pareen::constant(1.0),
|
||||
);
|
||||
|
||||
const CIRCLE_DIAMETER_MAX: i16 = 170;
|
||||
const CIRCLE_DIAMETER_MIN: i16 = 80;
|
||||
|
||||
i16::lerp(
|
||||
let a = i16::lerp(
|
||||
CIRCLE_DIAMETER_MAX / 2,
|
||||
CIRCLE_DIAMETER_MIN / 2,
|
||||
circle_scale.eval(t),
|
||||
)
|
||||
);
|
||||
|
||||
let b = i16::lerp(CIRCLE_DIAMETER_MIN / 2, 0, circle_scale2.eval(t));
|
||||
|
||||
if t > 0.8 {
|
||||
b
|
||||
} else {
|
||||
a
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_circle_position(&self, t: f32, start: Point) -> Point {
|
||||
let circle_pos = pareen::constant(0.0).seq_ease_in_out(
|
||||
0.8,
|
||||
easer::functions::Linear,
|
||||
0.2,
|
||||
pareen::constant(1.0),
|
||||
);
|
||||
|
||||
const CIRCLE_DIAMETER_MAX: i16 = 170;
|
||||
const CIRCLE_DIAMETER_MIN: i16 = 80;
|
||||
|
||||
Point::lerp(start, Point::zero(), circle_pos.eval(t))
|
||||
}
|
||||
|
||||
pub fn get_content2_opacity(&self, t: f32) -> u8 {
|
||||
let content_opacity = pareen::constant(0.0).seq_ease_in(
|
||||
1.0,
|
||||
easer::functions::Linear,
|
||||
0.2,
|
||||
pareen::constant(1.0),
|
||||
);
|
||||
|
||||
u8::lerp(0, 255, content_opacity.eval(t))
|
||||
}
|
||||
|
||||
pub fn start(&mut self) {
|
||||
@ -96,6 +137,7 @@ pub struct StatusScreen {
|
||||
circle_color: Color,
|
||||
dismiss_type: DismissType,
|
||||
anim: StatusAnimation,
|
||||
msg: Label<'static>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -105,7 +147,13 @@ enum DismissType {
|
||||
}
|
||||
|
||||
impl StatusScreen {
|
||||
fn new(icon: Icon, icon_color: Color, circle_color: Color, dismiss_style: DismissType) -> Self {
|
||||
fn new(
|
||||
icon: Icon,
|
||||
icon_color: Color,
|
||||
circle_color: Color,
|
||||
dismiss_style: DismissType,
|
||||
msg: TString<'static>,
|
||||
) -> Self {
|
||||
Self {
|
||||
area: Rect::zero(),
|
||||
icon,
|
||||
@ -113,42 +161,47 @@ impl StatusScreen {
|
||||
circle_color,
|
||||
dismiss_type: dismiss_style,
|
||||
anim: StatusAnimation::default(),
|
||||
msg: Label::new(msg, Alignment::Start, theme::TEXT_NORMAL).vertically_centered(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_success() -> Self {
|
||||
pub fn new_success(msg: TString<'static>) -> Self {
|
||||
Self::new(
|
||||
theme::ICON_SIMPLE_CHECKMARK,
|
||||
theme::GREEN_LIME,
|
||||
theme::GREEN_LIGHT,
|
||||
DismissType::SwipeUp,
|
||||
msg,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn new_success_timeout() -> Self {
|
||||
pub fn new_success_timeout(msg: TString<'static>) -> Self {
|
||||
Self::new(
|
||||
theme::ICON_SIMPLE_CHECKMARK,
|
||||
theme::GREEN_LIME,
|
||||
theme::GREEN_LIGHT,
|
||||
DismissType::Timeout(Timeout::new(TIMEOUT_MS)),
|
||||
msg,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn new_neutral() -> Self {
|
||||
pub fn new_neutral(msg: TString<'static>) -> Self {
|
||||
Self::new(
|
||||
theme::ICON_SIMPLE_CHECKMARK,
|
||||
theme::GREY_EXTRA_LIGHT,
|
||||
theme::GREY_DARK,
|
||||
DismissType::SwipeUp,
|
||||
msg,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn new_neutral_timeout() -> Self {
|
||||
pub fn new_neutral_timeout(msg: TString<'static>) -> Self {
|
||||
Self::new(
|
||||
theme::ICON_SIMPLE_CHECKMARK,
|
||||
theme::GREY_EXTRA_LIGHT,
|
||||
theme::GREY_DARK,
|
||||
DismissType::Timeout(Timeout::new(TIMEOUT_MS)),
|
||||
msg,
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -158,6 +211,7 @@ impl Component for StatusScreen {
|
||||
|
||||
fn place(&mut self, bounds: Rect) -> Rect {
|
||||
self.area = bounds;
|
||||
self.msg.place(bounds);
|
||||
bounds
|
||||
}
|
||||
|
||||
@ -190,15 +244,25 @@ impl Component for StatusScreen {
|
||||
fn render<'s>(&'s self, target: &mut impl Renderer<'s>) {
|
||||
let t = self.anim.eval();
|
||||
|
||||
shape::Circle::new(self.area.center(), self.anim.get_circle_radius(t))
|
||||
let pos = self.anim.get_circle_position(t, self.area.center());
|
||||
|
||||
let content_2_alpha = self.anim.get_content2_opacity(t);
|
||||
let content_1_alpha = 255 - content_2_alpha;
|
||||
|
||||
shape::Circle::new(pos, self.anim.get_circle_radius(t))
|
||||
.with_fg(self.circle_color)
|
||||
.with_bg(theme::BLACK)
|
||||
.with_thickness(2)
|
||||
.with_alpha(content_1_alpha)
|
||||
.render(target);
|
||||
shape::ToifImage::new(self.area.center(), self.icon.toif)
|
||||
.with_align(Alignment2D::CENTER)
|
||||
.with_fg(self.icon_color)
|
||||
.render(target);
|
||||
|
||||
if self.anim.get_circle_radius(t) > 20 {
|
||||
shape::ToifImage::new(pos, self.icon.toif)
|
||||
.with_align(Alignment2D::CENTER)
|
||||
.with_fg(self.icon_color)
|
||||
.with_alpha(content_1_alpha)
|
||||
.render(target);
|
||||
}
|
||||
|
||||
//content + header cover
|
||||
shape::Bar::new(self.area.outset(Insets::top(self.area.y0)))
|
||||
@ -213,6 +277,8 @@ impl Component for StatusScreen {
|
||||
.with_bg(theme::BLACK)
|
||||
.with_alpha(255 - self.anim.get_instruction_opacity(t))
|
||||
.render(target);
|
||||
|
||||
self.msg.render_with_alpha(target, content_2_alpha);
|
||||
}
|
||||
}
|
||||
|
||||
@ -220,5 +286,6 @@ impl Component for StatusScreen {
|
||||
impl crate::trace::Trace for StatusScreen {
|
||||
fn trace(&self, t: &mut dyn crate::trace::Tracer) {
|
||||
t.component("StatusScreen");
|
||||
t.child("msg", &self.msg);
|
||||
}
|
||||
}
|
||||
|
@ -148,10 +148,11 @@ impl GetAddress {
|
||||
});
|
||||
|
||||
let content_confirmed = Frame::left_aligned(
|
||||
TR::address__confirmed.into(),
|
||||
StatusScreen::new_success_timeout(),
|
||||
TR::words__title_success.into(),
|
||||
StatusScreen::new_success_timeout(TR::address__confirmed.into()),
|
||||
)
|
||||
.with_footer(TR::instructions__continue_in_app.into(), None)
|
||||
.with_result_icon(theme::ICON_BULLET_CHECKMARK, theme::GREEN_LIGHT)
|
||||
.map(|_| Some(FlowMsg::Confirmed));
|
||||
|
||||
// Menu
|
||||
|
@ -121,8 +121,11 @@ impl SetBrightness {
|
||||
});
|
||||
|
||||
let content_confirmed = Frame::left_aligned(
|
||||
TR::brightness__changed_title.into(),
|
||||
SwipeContent::new(StatusScreen::new_success()).with_no_attach_anim(),
|
||||
TR::words__title_success.into(),
|
||||
SwipeContent::new(StatusScreen::new_success(
|
||||
TR::brightness__changed_title.into(),
|
||||
))
|
||||
.with_no_attach_anim(),
|
||||
)
|
||||
.with_footer(TR::instructions__swipe_up.into(), None)
|
||||
.with_swipe(SwipeDirection::Up, SwipeSettings::default())
|
||||
|
@ -104,10 +104,13 @@ impl WarningHiPrio {
|
||||
});
|
||||
|
||||
// Cancelled
|
||||
let content_cancelled =
|
||||
Frame::left_aligned(done_title, StatusScreen::new_neutral_timeout())
|
||||
.with_footer(TR::instructions__continue_in_app.into(), None)
|
||||
.map(|_| Some(FlowMsg::Cancelled));
|
||||
let content_cancelled = Frame::left_aligned(
|
||||
TR::words__title_done.into(),
|
||||
StatusScreen::new_neutral_timeout(done_title),
|
||||
)
|
||||
.with_footer(TR::instructions__continue_in_app.into(), None)
|
||||
.with_result_icon(theme::ICON_BULLET_CHECKMARK, theme::GREY_DARK)
|
||||
.map(|_| Some(FlowMsg::Cancelled));
|
||||
|
||||
let res = SwipeFlow::new(&WarningHiPrio::Message)?
|
||||
.with_page(&WarningHiPrio::Message, content_message)?
|
||||
|
@ -54,6 +54,7 @@ use crate::{
|
||||
model_mercury::{
|
||||
component::{check_homescreen_format, SwipeContent},
|
||||
flow::new_confirm_action_simple,
|
||||
theme::ICON_BULLET_CHECKMARK,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -799,11 +800,15 @@ extern "C" fn new_show_success(n_args: usize, args: *const Obj, kwargs: *mut Map
|
||||
.try_into_option()?
|
||||
.and_then(|desc: TString| if desc.is_empty() { None } else { Some(desc) });
|
||||
|
||||
let content = StatusScreen::new_success();
|
||||
let content = StatusScreen::new_success(title);
|
||||
let obj = LayoutObj::new(SwipeUpScreen::new(
|
||||
Frame::left_aligned(title, SwipeContent::new(content).with_no_attach_anim())
|
||||
.with_footer(TR::instructions__swipe_up.into(), description)
|
||||
.with_swipe(SwipeDirection::Up, SwipeSettings::default()),
|
||||
Frame::left_aligned(
|
||||
TR::words__title_success.into(),
|
||||
SwipeContent::new(content).with_no_attach_anim(),
|
||||
)
|
||||
.with_footer(TR::instructions__swipe_up.into(), description)
|
||||
.with_result_icon(ICON_BULLET_CHECKMARK, theme::GREEN_LIGHT)
|
||||
.with_swipe(SwipeDirection::Up, SwipeSettings::default()),
|
||||
))?;
|
||||
Ok(obj.into())
|
||||
};
|
||||
|
@ -938,6 +938,7 @@ class TR:
|
||||
words__sign: str = "Sign"
|
||||
words__signer: str = "Signer"
|
||||
words__title_check: str = "Check"
|
||||
words__title_done: str = "Done"
|
||||
words__title_group: str = "Group"
|
||||
words__title_information: str = "Information"
|
||||
words__title_remember: str = "Remember"
|
||||
|
@ -946,6 +946,7 @@
|
||||
"words__title_share": "Share",
|
||||
"words__title_shares": "Shares",
|
||||
"words__title_success": "Success",
|
||||
"words__title_done": "Done",
|
||||
"words__title_summary": "Summary",
|
||||
"words__title_threshold": "Threshold",
|
||||
"words__try_again": "Try again.",
|
||||
|
@ -954,5 +954,6 @@
|
||||
"952": "setting__adjust",
|
||||
"953": "setting__apply",
|
||||
"954": "brightness__changed_title",
|
||||
"955": "brightness__change_title"
|
||||
"955": "brightness__change_title",
|
||||
"956": "words__title_done"
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
{
|
||||
"current": {
|
||||
"merkle_root": "c94efabb9554eea2adb7f312469fa8b366503bbdb57dd7f92fa67b23dc63bb97",
|
||||
"datetime": "2024-07-15T09:41:37.793874",
|
||||
"commit": "5935708ac86d336364e5ab78fc5fd67b19402eaf"
|
||||
"merkle_root": "8c40d9e33f42783293a32e768f155e29aa3650b9bbc5e1ebaabf1ec46a7733b7",
|
||||
"datetime": "2024-07-17T17:20:50.219181",
|
||||
"commit": "ace22197e82214ae18255d48fae68ece0e7a0386"
|
||||
},
|
||||
"history": [
|
||||
{
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user