diff --git a/core/embed/rust/src/ui/model_tr/component/coinjoin_progress.rs b/core/embed/rust/src/ui/model_tr/component/coinjoin_progress.rs index 905c5bf87d..eb67ee5ed1 100644 --- a/core/embed/rust/src/ui/model_tr/component/coinjoin_progress.rs +++ b/core/embed/rust/src/ui/model_tr/component/coinjoin_progress.rs @@ -1,3 +1,5 @@ +use core::mem; + use crate::{ strutil::StringType, ui::{ @@ -6,8 +8,9 @@ use crate::{ text::util::{text_multiline, text_multiline_bottom}, Component, Event, EventCtx, }, - display::Font, + display::{self, Font}, geometry::{Alignment, Insets, Rect}, + util::animation_disabled, }, }; @@ -16,8 +19,12 @@ use super::theme; const HEADER: &str = "COINJOIN IN PROGRESS"; const FOOTER: &str = "Do not disconnect your Trezor!"; const FOOTER_TEXT_MARGIN: i16 = 8; +const LOADER_OFFSET: i16 = -15; +const LOADER_SPEED: u16 = 10; pub struct CoinJoinProgress { + value: u16, + loader_y_offset: i16, text: T, area: Rect, indeterminate: bool, @@ -29,6 +36,8 @@ where { pub fn new(text: T, indeterminate: bool) -> Self { Self { + value: 0, + loader_y_offset: LOADER_OFFSET, text, area: Rect::zero(), indeterminate, @@ -47,7 +56,31 @@ where bounds } - fn event(&mut self, _ctx: &mut EventCtx, _event: Event) -> Option { + fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option { + if animation_disabled() { + return None; + } + + // Indeterminate needs to request frames to animate. + // Determinate ones are receiving Event::Progress events. + if self.indeterminate { + match event { + Event::Attach => { + ctx.request_anim_frame(); + } + Event::Timer(EventCtx::ANIM_FRAME_TIMER) => { + self.value = (self.value + LOADER_SPEED) % 1000; + ctx.request_anim_frame(); + ctx.request_paint(); + } + _ => {} + } + } else if let Event::Progress(new_value, _new_description) = event { + if mem::replace(&mut self.value, new_value) != new_value { + ctx.request_paint(); + } + } + None } @@ -62,10 +95,22 @@ where theme::BG, Alignment::Center, ); + display::loader::loader_small_indeterminate( + self.value, + self.loader_y_offset, + theme::FG, + theme::BG, + ); + } else { + display::loader( + self.value, + self.loader_y_offset, + theme::FG, + theme::BG, + Some((theme::ICON_TICK_FAT, theme::FG)), + ); } - // CENTER - // BOTTOM let top_rest = text_multiline_bottom( self.area,