Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions ui/rgb/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ impl Argb {
pub const DIAMOND_CONE_AMBER: Argb = Argb(Some(Self::DIMMING_MAX_VALUE), 25, 18, 1);
/// Error color for outer ring
pub const DIAMOND_RING_ERROR_SALMON: Argb = Argb(Some(8), 127, 20, 0);
/// Error color for inner ring (shroud)
pub const DIAMOND_CENTER_ERROR_SALMON: Argb = Argb(Some(6), 255, 20, 0);

/// QR Phase colors - diamond
pub const DIAMOND_CENTER_WIFI_QR_SCAN: Argb = Self::DIAMOND_CENTER_USER_QR_SCAN;
Expand Down
146 changes: 55 additions & 91 deletions ui/src/engine/diamond.rs
Original file line number Diff line number Diff line change
Expand Up @@ -694,97 +694,6 @@ impl EventHandler for Runner<DIAMOND_RING_LED_COUNT, DIAMOND_CENTER_LED_COUNT> {
}
}
}
Event::BiometricCaptureFakeProgressStart {
timeout,
min_fast_forward_duration,
max_fast_forward_duration,
} => {
self.set_center(
LEVEL_FOREGROUND,
animations::Static::<DIAMOND_CENTER_LED_COUNT>::new(
Argb::DIAMOND_CENTER_BIOMETRIC_CAPTURE_PROGRESS,
None,
),
);
self.set_ring(
LEVEL_NOTICE,
animations::fake_progress_v2::FakeProgress::<DIAMOND_RING_LED_COUNT>::new(
Argb::DIAMOND_RING_BIOMETRIC_CAPTURE_PROGRESS,
*timeout,
*min_fast_forward_duration,
*max_fast_forward_duration,
),
);
}
Event::BiometricCaputreSuccessAndFastForwardFakeProgress => {
let ring_completion_time = self
.ring_animations_stack
.stack
.get_mut(&LEVEL_NOTICE)
.and_then(|RunningAnimation { animation, .. }| {
animation
.as_any_mut()
.downcast_mut::<animations::fake_progress_v2::FakeProgress<
DIAMOND_RING_LED_COUNT,
>>()
})
.map(|fake_progress| fake_progress.set_completed())
.unwrap_or_default()
.as_secs_f64();

let mut total_duration = 0.0;
while let Some(melody) = self.capture_sound.peekable().peek() {
let melody = sound::Type::Melody(*melody);
let melody_duration =
self.sound.get_duration(melody).unwrap().as_secs_f64();
if total_duration + melody_duration < ring_completion_time {
self.sound.queue(melody, Duration::ZERO)?;
self.capture_sound.next();
total_duration += melody_duration;
} else {
break;
}
}

// Sync biometric capture success animation + sounds, with the fake progress.
// Since the ring is ON after the fake progress, we turn it off smoothly in `fade_out_duration`,
// and then we do a double blink after `success_delay`.
let fade_out_duration = 0.3;
let success_delay = 0.4;
self.sound.queue(
sound::Type::Melody(sound::Melody::IrisScanSuccess),
Duration::from_millis(
((ring_completion_time + fade_out_duration + success_delay)
* 1000.0) as u64,
),
)?;
self.set_center(
LEVEL_FOREGROUND,
animations::alert_v2::Alert::<DIAMOND_CENTER_LED_COUNT>::new(
Argb::DIAMOND_CENTER_BIOMETRIC_CAPTURE_PROGRESS,
SquarePulseTrain::from(vec![
(0.0, 0.0),
(fade_out_duration + success_delay + 1.1, 3.4),
]),
)?
.with_delay(ring_completion_time),
);
self.set_ring(
LEVEL_FOREGROUND,
animations::alert_v2::Alert::<DIAMOND_RING_LED_COUNT>::new(
Argb::DIAMOND_RING_BIOMETRIC_CAPTURE_SUCCESS,
SquarePulseTrain::from(vec![
(0.0, 0.0),
(0.0, fade_out_duration),
(fade_out_duration + success_delay, 0.1),
(fade_out_duration + success_delay + 0.5, 0.1),
(fade_out_duration + success_delay + 1.0, 0.1),
(fade_out_duration + success_delay + 1.1, 3.5),
]),
)?
.with_delay(ring_completion_time),
);
}
Event::BiometricCaptureProgressWithNotch { progress } => {
// set progress but wait for wave to finish breathing
let breathing = self
Expand Down Expand Up @@ -934,6 +843,15 @@ impl EventHandler for Runner<DIAMOND_RING_LED_COUNT, DIAMOND_CENTER_LED_COUNT> {
}
}
}
// clears any stale state from PreflightCheckErrorNotification
self.set_center(
LEVEL_NOTICE,
animations::Static::new(
Argb::DIAMOND_CENTER_BIOMETRIC_CAPTURE_PROGRESS,
None,
)
.fade_in(0.5),
);
}
Event::BiometricFlowResult { is_success } => {
if let Some(biometric_flow) = self
Expand Down Expand Up @@ -975,6 +893,52 @@ impl EventHandler for Runner<DIAMOND_RING_LED_COUNT, DIAMOND_CENTER_LED_COUNT> {

}
}
Event::PreflightCheckErrorNotification { set } => {
if self
.center_animations_stack
.stack
.get_mut(&LEVEL_NOTICE)
.and_then(|RunningAnimation { animation, .. }| {
animation
.as_any_mut()
.downcast_mut::<animations::sine_blend::SineBlend<
DIAMOND_CENTER_LED_COUNT,
>>()
})
.is_some()
{
if !*set {
self.set_center(
LEVEL_NOTICE,
animations::Static::new(
Argb::DIAMOND_CENTER_BIOMETRIC_CAPTURE_PROGRESS,
None,
)
.fade_in(0.5),
);
} else if *set {
self.set_center(
LEVEL_NOTICE,
animations::Static::new(
Argb::DIAMOND_CENTER_ERROR_SALMON,
None,
)
.fade_in(0.5),
);
}
} else {
if *set {
self.set_center(
LEVEL_NOTICE,
animations::sine_blend::SineBlend::<DIAMOND_CENTER_LED_COUNT>::new(
Argb::DIAMOND_CENTER_USER_QR_SCAN_SUCCESS_BREATHING_LOW,
Argb::DIAMOND_CENTER_ERROR_SALMON,
2.0,
0.0,
));
}
}
}
Event::BiometricCaptureSuccess => {
self.biometric_capture_success()?;
}
Expand Down
15 changes: 5 additions & 10 deletions ui/src/engine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,13 +275,6 @@ event_enum! {
BiometricCaptureProgress {
progress: f64,
},
/// Biometric capture start fake progress.
#[event_enum(method = biometric_capture_fake_progress_start)]
BiometricCaptureFakeProgressStart {
timeout: Duration,
min_fast_forward_duration: Duration,
max_fast_forward_duration: Duration,
},
/// Biometric flow start.
#[event_enum(method = biometric_flow_start)]
BiometricFlowStart {
Expand All @@ -297,9 +290,11 @@ event_enum! {
BiometricFlowResult {
is_success: bool,
},
/// Biometric capture has finished successfully, command fake-progress to fast-forward
#[event_enum(method = biometric_capture_success_and_fast_forward_fake_progress)]
BiometricCaputreSuccessAndFastForwardFakeProgress,
/// Preflight check error notification.
#[event_enum(method = preflight_check_error_notification)]
PreflightCheckErrorNotification {
set: bool,
},
#[event_enum(method = biometric_capture_progress_with_notch)]
BiometricCaptureProgressWithNotch {
progress: f64,
Expand Down
107 changes: 23 additions & 84 deletions ui/src/engine/pearl/self_serve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -385,21 +385,6 @@ impl Runner<PEARL_RING_LED_COUNT, PEARL_CENTER_LED_COUNT> {
}
}
}
Event::BiometricCaptureFakeProgressStart {
timeout,
min_fast_forward_duration,
max_fast_forward_duration,
} => {
self.set_ring(
LEVEL_NOTICE,
animations::fake_progress_v2::FakeProgress::<PEARL_RING_LED_COUNT>::new(
Argb::PEARL_RING_USER_CAPTURE,
*timeout,
*min_fast_forward_duration,
*max_fast_forward_duration,
),
);
}
Event::BiometricFlowStart {
timeout,
min_fast_forward_duration,
Expand All @@ -420,6 +405,7 @@ impl Runner<PEARL_RING_LED_COUNT, PEARL_CENTER_LED_COUNT> {
);
self.stop_ring(LEVEL_FOREGROUND, Transition::ForceStop);
self.stop_ring(LEVEL_BACKGROUND, Transition::ForceStop);
self.set_center(LEVEL_NOTICE, animations::Static::new(Argb::OFF, None));
}
Event::BiometricFlowProgressFastForward => {
if let Some(biometric_flow) = self
Expand Down Expand Up @@ -447,6 +433,7 @@ impl Runner<PEARL_RING_LED_COUNT, PEARL_CENTER_LED_COUNT> {
}
}
}
self.stop_center(LEVEL_NOTICE, Transition::FadeOut(0.5));
}
Event::BiometricFlowResult { is_success } => {
if let Some(biometric_flow) = self
Expand Down Expand Up @@ -488,83 +475,35 @@ impl Runner<PEARL_RING_LED_COUNT, PEARL_CENTER_LED_COUNT> {

}
}
Event::BiometricCaputreSuccessAndFastForwardFakeProgress => {
let ring_completion_time = self
.ring_animations_stack
Event::PreflightCheckErrorNotification { set } => {
if let Some(animation) = self
.center_animations_stack
.stack
.get_mut(&LEVEL_NOTICE)
.and_then(|RunningAnimation { animation, .. }| {
animation
.as_any_mut()
.downcast_mut::<animations::fake_progress_v2::FakeProgress<
PEARL_RING_LED_COUNT,
>>()
.downcast_mut::<animations::Static<PEARL_CENTER_LED_COUNT>>(
)
})
.map(|fake_progress| fake_progress.set_completed())
.unwrap_or_default()
.as_secs_f64();

let mut total_duration = 0.0;
while let Some(melody) = self.capture_sound.peekable().peek() {
let melody = sound::Type::Melody(*melody);
let melody_duration =
self.sound.get_duration(melody).unwrap().as_secs_f64();
if total_duration + melody_duration < ring_completion_time {
self.sound.queue(melody, Duration::ZERO)?;
self.capture_sound.next();
total_duration += melody_duration;
} else {
break;
{
let is_on = animation.color() != Argb::OFF;
if is_on && !*set {
self.set_center(
LEVEL_NOTICE,
animations::Static::new(Argb::OFF, None).fade_in(0.5),
);
} else if !is_on && *set {
self.set_center(
LEVEL_NOTICE,
animations::Static::new(
Argb::PEARL_RING_ERROR_SALMON,
None,
)
.fade_in(0.5),
);
}
}
// Sync biometric capture success animation + sounds, with the fake progress.
// Since the ring is ON after the fake progress, we turn it off smoothly in `fade_out_duration`,
// and then we do a double blink after `success_delay`.
let fade_out_duration = 0.3;
let success_delay = 0.4;
self.sound.queue(
sound::Type::Melody(sound::Melody::IrisScanSuccess),
Duration::from_millis(
((ring_completion_time + fade_out_duration + success_delay)
* 1000.0) as u64,
),
)?;
self.stop_center(
LEVEL_FOREGROUND,
Transition::FadeOut(ring_completion_time),
);
// in case nothing is running on center, make sure we set the background to off
self.set_center(
LEVEL_BACKGROUND,
animations::Static::<PEARL_CENTER_LED_COUNT>::new(Argb::OFF, None),
);
self.set_center(
LEVEL_FOREGROUND,
animations::alert_v2::Alert::<PEARL_CENTER_LED_COUNT>::new(
Argb::PEARL_CENTER_CAPTURE_SUCCESS,
SquarePulseTrain::from(vec![
(fade_out_duration + success_delay, 1.1),
(fade_out_duration + success_delay + 1.1, 3.4),
]),
)?
.with_delay(ring_completion_time),
);
self.set_ring(
LEVEL_FOREGROUND,
animations::alert_v2::Alert::<PEARL_RING_LED_COUNT>::new(
Argb::PEARL_RING_CAPTURE_SUCCESS,
SquarePulseTrain::from(vec![
(0.0, 0.0),
(0.0, fade_out_duration),
(fade_out_duration + success_delay, 0.1),
(fade_out_duration + success_delay + 0.5, 0.1),
(fade_out_duration + success_delay + 1.0, 0.1),
(fade_out_duration + success_delay + 1.1, 3.5),
]),
)?
.with_delay(ring_completion_time),
);
self.operator_signup_phase.iris_scan_complete();
}
Event::BiometricCaptureProgressWithNotch { progress } => {
// set progress but wait for wave to finish breathing
Expand Down
Loading