1use serde::{Deserialize, Serialize};
2use std::sync::Mutex;
3
4#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
5pub enum Platform {
6 Mac,
7 Windows,
8 Linux,
9}
10
11#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
12pub enum MouseEventType {
13 Move,
14 LeftDown,
15 LeftUp,
16 RightDown,
17 RightUp,
18 MiddleDown,
19 MiddleUp,
20 Scroll,
21}
22
23impl TryFrom<i32> for MouseEventType {
24 type Error = &'static str;
25
26 fn try_from(value: i32) -> Result<Self, Self::Error> {
27 match value {
28 0 => Ok(MouseEventType::Move),
29 1 => Ok(MouseEventType::LeftDown),
30 2 => Ok(MouseEventType::LeftUp),
31 3 => Ok(MouseEventType::RightDown),
32 4 => Ok(MouseEventType::RightUp),
33 5 => Ok(MouseEventType::MiddleDown),
34 6 => Ok(MouseEventType::MiddleUp),
35 7 => Ok(MouseEventType::Scroll),
36 _ => Err("Invalid mouse event type"),
37 }
38 }
39}
40
41#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
42pub enum WindowEventType {
43 Focused,
44 TitleChanged,
45}
46
47#[derive(Debug, Clone, Serialize, Deserialize)]
48pub struct MouseEvent {}
49
50#[derive(Debug, Clone, Serialize, Deserialize)]
51pub struct KeyboardEvent {}
52
53#[derive(Debug, Clone, Serialize, Deserialize)]
54pub struct WindowEvent {
55 pub app_name: String,
56 pub window_title: String,
57 pub bundle_id: Option<String>,
58 pub url: Option<String>,
59 pub platform: Platform,
60}
61
62#[derive(Debug, Clone, Serialize, Deserialize)]
63pub struct BlockedApp {
64 pub app_name: String,
65 pub app_external_id: String,
66 pub is_site: bool,
67}
68
69#[derive(Debug, Clone, Serialize, Deserialize)]
70pub struct BlockedAppEvent {
71 pub blocked_apps: Vec<BlockedApp>,
72}
73
74pub trait EventCallback: Send + Sync {
75 fn on_mouse_events(&self, has_activity: bool);
76 fn on_keyboard_events(&self, has_activity: bool);
77 fn on_window_event(&self, event: WindowEvent);
78 fn on_app_blocked(&self, event: BlockedAppEvent);
79}
80
81pub struct Monitor {
82 mouse_callbacks: Mutex<Vec<Box<dyn Fn(bool) + Send + Sync>>>,
83 keyboard_callbacks: Mutex<Vec<Box<dyn Fn(bool) + Send + Sync>>>,
84 window_callbacks: Mutex<Vec<Box<dyn Fn(WindowEvent) + Send + Sync>>>,
85 app_blocked_callbacks: Mutex<Vec<Box<dyn Fn(BlockedAppEvent) + Send + Sync>>>,
86}
87
88impl Monitor {
89 pub fn new() -> Self {
90 Self {
91 mouse_callbacks: Mutex::new(Vec::new()),
92 keyboard_callbacks: Mutex::new(Vec::new()),
93 window_callbacks: Mutex::new(Vec::new()),
94 app_blocked_callbacks: Mutex::new(Vec::new()),
95 }
96 }
97
98 pub fn register_keyboard_callback(&self, callback: Box<dyn Fn(bool) + Send + Sync>) {
99 self.keyboard_callbacks.lock().unwrap().push(callback);
100 }
101
102 pub fn register_mouse_callback(&self, callback: Box<dyn Fn(bool) + Send + Sync>) {
103 self.mouse_callbacks.lock().unwrap().push(callback);
104 }
105
106 pub fn register_window_callback(&self, callback: Box<dyn Fn(WindowEvent) + Send + Sync>) {
107 self.window_callbacks.lock().unwrap().push(callback);
108 }
109
110 pub fn register_app_blocked_callback(
111 &self,
112 callback: Box<dyn Fn(BlockedAppEvent) + Send + Sync>,
113 ) {
114 self.app_blocked_callbacks.lock().unwrap().push(callback);
115 }
116}
117
118impl EventCallback for Monitor {
119 fn on_mouse_events(&self, has_activity: bool) {
120 let mut callbacks = self.mouse_callbacks.lock().unwrap();
121 for callback in callbacks.iter_mut() {
122 callback(has_activity);
123 }
124 }
125
126 fn on_keyboard_events(&self, has_activity: bool) {
127 let mut callbacks = self.keyboard_callbacks.lock().unwrap();
128 for callback in callbacks.iter_mut() {
129 callback(has_activity);
130 }
131 }
132
133 fn on_window_event(&self, event: WindowEvent) {
134 let mut callbacks = self.window_callbacks.lock().unwrap();
135 for callback in callbacks.iter_mut() {
136 callback(event.clone());
137 }
138 }
139
140 fn on_app_blocked(&self, event: BlockedAppEvent) {
141 let callbacks = self.app_blocked_callbacks.lock().unwrap();
142 for callback in callbacks.iter() {
143 callback(event.clone());
144 }
145 }
146}