use std::sync::Mutex;
use serde_json::json;
use tauri::{AppHandle, Emitter, EventTarget, Manager, Runtime, WindowEvent};
use crate::config::Mode;
use crate::session::Session;
use crate::storage::{append_lifecycle, now_ms};
type SessionState = Mutex<Session>;
pub fn handle_window_event<R: Runtime>(
app: &AppHandle<R>,
label: &str,
event: &WindowEvent,
) {
match event {
WindowEvent::CloseRequested { api, .. } => on_close_requested(app, label, api),
WindowEvent::Focused(focused) => {
if *focused {
on_focused(app, label);
}
}
_ => {}
}
}
fn on_close_requested<R: Runtime>(app: &AppHandle<R>, label: &str, api: &tauri::CloseRequestApi) {
let Some(state) = app.try_state::<SessionState>() else {
return;
};
let (mode, seg, dir, should_intercept) = {
let Ok(mut s) = state.lock() else {
return;
};
if !s.active {
return;
}
let is_main = label == s.config.main_label;
let skip = !s.config.skip_focus_prefix.is_empty()
&& label.starts_with(&s.config.skip_focus_prefix);
if is_main || skip {
return; }
match s.config.mode {
Mode::Local => {
let seg = s.current.remove(label);
let should = seg.is_some();
(Mode::Local, seg, s.dir.clone(), should)
}
Mode::Remote => {
(Mode::Remote, None, None, true)
}
}
};
if !should_intercept {
return;
}
api.prevent_close();
if let Some(w) = app.get_webview_window(label) {
let _ = w.hide();
}
let t = now_ms();
if mode == Mode::Local {
if let (Some(seg), Some(dir)) = (seg, dir) {
let _ = append_lifecycle(
&dir,
json!({ "type": "hidden", "label": label, "segmentId": seg, "t": t }),
);
}
}
let _ = app.emit_to(
EventTarget::labeled(label),
"segment",
json!({ "action": "stop" }),
);
}
fn on_focused<R: Runtime>(app: &AppHandle<R>, label: &str) {
let Some(state) = app.try_state::<SessionState>() else {
return;
};
let (active, mode, skip_prefix, dir) = {
let Ok(s) = state.lock() else {
return;
};
(
s.active,
s.config.mode,
s.config.skip_focus_prefix.clone(),
s.dir.clone(),
)
};
if !active {
return;
}
if !skip_prefix.is_empty() && label.starts_with(&skip_prefix) {
return; }
let t = now_ms();
match mode {
Mode::Local => {
if let Some(dir) = dir {
let _ = append_lifecycle(
&dir,
json!({ "type": "focus", "label": label, "t": t }),
);
}
}
Mode::Remote => {
let _ = app.emit_to(
EventTarget::labeled(label),
"observer-lifecycle",
json!({ "type": "focus", "label": label, "t": t }),
);
}
}
}