use axum::response::Json; use std::sync::Mutex; use crate::audio; static CMD_QUEUE: Mutex)>> = Mutex::new(Vec::new()); pub async fn post_command( Json(body): Json, ) -> impl axum::response::IntoResponse { let cmd = body["cmd"].as_str().unwrap_or("").to_string(); let val = body["val"].as_str().map(|s| s.to_string()); let out = body["out"].as_str().map(|s| s.to_string()); if cmd == "test_voice" { let lang = val.as_deref().unwrap_or("zh_TW"); let voice_name = audio::voice_for_lang(lang); let phrase = audio::phrase_for_lang(lang); if let Some(d) = out.as_deref() { if !d.is_empty() { std::process::Command::new("SwitchAudioSource") .args(["-t", "output", "-s", d]) .output() .ok(); } } std::process::Command::new("say") .args(["-v", &voice_name, &phrase]) .spawn() .ok(); } else if cmd == "vol_up" { std::process::Command::new("osascript") .args([ "-e", "set volume output volume (output volume of (get volume settings)) + 10", ]) .output() .ok(); } else if cmd == "vol_down" { std::process::Command::new("osascript") .args([ "-e", "set volume output volume (output volume of (get volume settings)) - 10", ]) .output() .ok(); } else { CMD_QUEUE.lock().unwrap().push((cmd, val)); } Json(serde_json::json!({"ok": true})) } pub async fn get_commands() -> Json { let mut queue = CMD_QUEUE.lock().unwrap(); let cmds: Vec<_> = queue .drain(..) .map(|(c, v)| serde_json::json!({"cmd": c, "val": v})) .collect(); Json(serde_json::json!(cmds)) }