shoko_screen_timer/
lib.rs1use std::{fs, thread};
2use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
3use std::path::{ PathBuf};
4
5pub fn get_path() -> PathBuf {
6 if cfg!(target_os = "linux") {
7 let p = "/dev/shm/active_time.text";
8 p.split('/').collect::<PathBuf>()
9 } else {
10 let mut p = std::env::temp_dir();
11 p.push("active_time.text");
12 p
13 }
14}
15pub fn get_active() -> u128 {
16 SystemTime::now().duration_since(UNIX_EPOCH).map(|d| d.as_millis()).unwrap_or(0)
17}
18pub fn format_screen_time(active_millis: u64) -> String {
20 let active_seconds = active_millis / 1000;
21 let hours = active_seconds / 3600;
22 let minutes = (active_seconds % 3600) / 60;
23 let seconds = active_seconds % 60;
24 let ms = active_millis % 1000;
25
26 format!(
27 "{{\"text\": \"{:02}:{:02}:{:02}.{:03}\", \"tooltip\": \"Screen Time\" }}",
28 hours, minutes, seconds, ms)
29}
30
31pub fn active_timer(callback: fn(u64)) {
32 let path = get_path();
33 let now_ms = get_active();
34
35 let uptime_ms = Instant::now().elapsed().as_millis();
36 let boot_time_ms = now_ms - uptime_ms;
37 let mut active_start = match fs::read_to_string(&path) {
38 Ok(val) => {
39 let active_saved = val.as_str().trim().parse::<u128>().unwrap_or_else(|_| now_ms);
40 if active_saved < boot_time_ms {
41 let _ = fs::remove_file(&path);
42 now_ms
43 } else {
44 active_saved
45 }
46 },
47 Err(_) => {
48 let _ = fs::write(&path, now_ms.to_string());
49 now_ms
50 }
51 };
52
53 let mut last_active = get_active();
54
55 loop {
56 let active = get_active();
57 if active > last_active + 5000 {
58 let eepy_nix = active - last_active - 1000;
59 active_start += eepy_nix;
60 let _ = fs::write(&path, active_start.to_string());
61 }
62 last_active = active;
63 if active_start > active {
64 active_start = active;
65 let _ = fs::write(&path, active_start.to_string());
66 }
67 let active_millis = active - active_start;
68 callback(active_millis.try_into().unwrap_or(0));
69 thread::sleep(Duration::from_millis(8));
70 }
71
72}