Seregon/StratoSDK

StratoSDK is a framework with a declarative approach similar to Flutter/React, written and designed entirely for Rust.

Rust/27.3 KB/No license
crates/strato-ui-core/src/app_focus_telemetry.rs
StratoSDK / crates / strato-ui-core / src / app_focus_telemetry.rs
1use crate::time::get_current_time;
2use chrono::{DateTime, Duration, Utc};
3use serde_json::json;
4 
5// `DailyAppFocusDuration` records the cumulative duration for focus events that end on each day.
6struct DailyAppFocusDuration {
7 duration: Duration,
8 last_synced_time: DateTime<Utc>,
9}
10 
11impl DailyAppFocusDuration {
12 // If calendar date has advanced since the last sync, record the
13 // Daily App Focus event with the current duration.
14 #[allow(deprecated)]
15 fn try_record(&mut self, user_id: Option<String>, anonymous_id: String) {
16 if get_current_time().date_naive() > self.last_synced_time.date_naive() {
17 let daily_app_focus_duration_seconds =
18 json!(self.duration.num_milliseconds() as f64 / 1000.);
19 crate::telemetry::record_event(
20 user_id,
21 anonymous_id,
22 "Daily App Focus Duration (seconds)".into(),
23 Some(daily_app_focus_duration_seconds),
24 false, /* contains_ugc */
25 self.last_synced_time.date().and_hms(0, 0, 0),
26 );
27 self.reset();
28 }
29 }
30 
31 fn reset(&mut self) {
32 self.duration = Duration::seconds(0);
33 self.last_synced_time = get_current_time();
34 }
35 
36 fn add_duration(&mut self, duration: Duration, user_id: Option<String>, anonymous_id: String) {
37 self.try_record(user_id, anonymous_id);
38 if let Some(new_duration) = self.duration.checked_add(&duration) {
39 self.duration = new_duration;
40 } else {
41 log::info!("Unable to increase the running total daily app focus duration.");
42 }
43 }
44}
45 
46pub struct AppFocusInfo {
47 last_time_app_focused: DateTime<Utc>,
48 daily_app_focus_duration: DailyAppFocusDuration,
49}
50 
51impl AppFocusInfo {
52 pub fn new() -> Self {
53 let now = get_current_time();
54 Self {
55 last_time_app_focused: now,
56 daily_app_focus_duration: DailyAppFocusDuration {
57 duration: Duration::seconds(0),
58 last_synced_time: now,
59 },
60 }
61 }
62 
63 pub fn record_app_focus(&mut self, user_id: Option<String>, anonymous_id: String) {
64 self.last_time_app_focused = get_current_time();
65 self.try_record_daily_app_focus_duration(user_id, anonymous_id);
66 }
67 
68 pub fn try_record_daily_app_focus_duration(
69 &mut self,
70 user_id: Option<String>,
71 anonymous_id: String,
72 ) {
73 self.daily_app_focus_duration
74 .try_record(user_id, anonymous_id);
75 }
76 
77 pub fn record_app_blur(&mut self, user_id: Option<String>, anonymous_id: String) {
78 let app_focus_duration =
79 get_current_time().signed_duration_since(self.last_time_app_focused);
80 self.daily_app_focus_duration
81 .add_duration(app_focus_duration, user_id, anonymous_id);
82 }
83}
84 
85#[cfg(test)]
86#[path = "app_focus_telemetry_test.rs"]
87mod tests;
88