// Claude Desktop — Schulungsmodus (Phase 15) // Oeffnet separates Praesentations-Fenster + sendet Slides use serde::{Deserialize, Serialize}; use tauri::{AppHandle, Emitter, Manager, WebviewUrl, WebviewWindowBuilder}; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Slide { pub r#type: String, // "mermaid" | "code" | "text" pub content: String, #[serde(skip_serializing_if = "Option::is_none")] pub language: Option, #[serde(skip_serializing_if = "Option::is_none")] pub title: Option, } #[tauri::command] pub async fn presentation_open(app: AppHandle) -> Result<(), String> { // Falls Fenster bereits existiert, nach vorne holen if let Some(win) = app.get_webview_window("presentation") { let _ = win.show(); let _ = win.set_focus(); return Ok(()); } WebviewWindowBuilder::new(&app, "presentation", WebviewUrl::App("/presentation".into())) .title("Claude — Schulungsmodus") .inner_size(1200.0, 800.0) .center() .build() .map_err(|e| e.to_string())?; Ok(()) } #[tauri::command] pub async fn presentation_close(app: AppHandle) -> Result<(), String> { if let Some(win) = app.get_webview_window("presentation") { let _ = win.close(); } Ok(()) } #[tauri::command] pub async fn presentation_send_slide(app: AppHandle, slide: Slide) -> Result<(), String> { // Fenster oeffnen falls noch nicht offen if app.get_webview_window("presentation").is_none() { let _ = presentation_open(app.clone()).await; tokio::time::sleep(std::time::Duration::from_millis(400)).await; } if let Some(win) = app.get_webview_window("presentation") { win.emit("presentation-slide", &slide).map_err(|e| e.to_string())?; } Ok(()) } #[tauri::command] pub async fn presentation_clear(app: AppHandle) -> Result<(), String> { if let Some(win) = app.get_webview_window("presentation") { win.emit("presentation-clear", ()).map_err(|e| e.to_string())?; } Ok(()) }