//! Draft event handlers on `MessageService`. //! //! Drafts are per-user private data — no permission checks beyond auth needed. use std::sync::Arc; use uuid::Uuid; use crate::ImksError; use crate::socket::socket::Socket; use super::message::MessageService; impl MessageService { /// Handle `draft:save` — upsert a draft. pub async fn save_draft( &self, socket: Arc, data: &serde_json::Value, ) -> crate::ImksResult<()> { let user_id = self.user_id(&socket)?; let arr = data .as_array() .and_then(|a| a.first()) .ok_or_else(|| ImksError::InvalidInput("Expected [payload] array".into()))?; let channel_id: Uuid = Self::parse_field(arr, "channel_id")?; let body: String = Self::parse_field(arr, "body")?; let thread_id: Option = Self::parse_optional(arr, "thread_id")?; let reply_to_message_id: Option = Self::parse_optional(arr, "reply_to_message_id")?; let metadata: Option = Self::parse_optional(arr, "metadata")?; let channel_id_str = channel_id.to_string(); let user_id_str = user_id.to_string(); self.validate_channel_write(&channel_id_str, &user_id_str) .await?; self.repo .upsert_draft( channel_id, user_id, thread_id, &body, reply_to_message_id, metadata, ) .await?; Ok(()) } /// Handle `draft:get` — retrieve a draft and send it back to the requesting socket. pub async fn get_draft( &self, socket: Arc, data: &serde_json::Value, ) -> crate::ImksResult<()> { let user_id = self.user_id(&socket)?; let arr = data .as_array() .and_then(|a| a.first()) .ok_or_else(|| ImksError::InvalidInput("Expected [payload] array".into()))?; let channel_id: Uuid = Self::parse_field(arr, "channel_id")?; let thread_id: Option = Self::parse_optional(arr, "thread_id")?; let channel_id_str = channel_id.to_string(); let user_id_str = user_id.to_string(); self.ensure_readable(&channel_id_str, &user_id_str).await?; self.ensure_member(&channel_id_str, &user_id_str).await?; let draft = self.repo.get_draft(channel_id, user_id, thread_id).await?; if let Some(d) = draft { let _ = socket.emit("draft:loaded", serde_json::to_value(&d).unwrap_or_default()); } else { let _ = socket.emit("draft:loaded", serde_json::json!(null)); } Ok(()) } /// Handle `draft:delete` — delete a draft after sending. pub async fn delete_draft( &self, socket: Arc, data: &serde_json::Value, ) -> crate::ImksResult<()> { let user_id = self.user_id(&socket)?; let arr = data .as_array() .and_then(|a| a.first()) .ok_or_else(|| ImksError::InvalidInput("Expected [payload] array".into()))?; let channel_id: Uuid = Self::parse_field(arr, "channel_id")?; let thread_id: Option = Self::parse_optional(arr, "thread_id")?; let channel_id_str = channel_id.to_string(); let user_id_str = user_id.to_string(); self.ensure_readable(&channel_id_str, &user_id_str).await?; self.ensure_member(&channel_id_str, &user_id_str).await?; self.repo .delete_draft(channel_id, user_id, thread_id) .await?; Ok(()) } }