//! Pin event handlers on `MessageService`. use std::sync::Arc; use uuid::Uuid; use crate::ImksError; use crate::ImksResult; use crate::socket::socket::Socket; use super::message::MessageService; impl MessageService { /// Handle `pin:add` — pin a message, then broadcast to the channel room. pub async fn pin_message( &self, socket: Arc, data: &serde_json::Value, ) -> ImksResult<()> { let user_id = self.user_id(&socket)?; let (channel_id, message_id) = self.parse_pin_payload(data)?; self.ensure_member(&channel_id.to_string(), &user_id.to_string()) .await?; self.repo .pin_message(channel_id, message_id, user_id) .await?; if let Some(ns) = self.namespaces.get_namespace(&socket.namespace) { let ns = ns.clone(); let cid = channel_id.to_string(); let mid = message_id.to_string(); tokio::spawn(async move { ns.emit_to_room( &cid, "pin:added", serde_json::json!({ "channel_id": cid, "message_id": mid, "pinned_by": user_id.to_string(), }), ) .await; }); } tracing::info!(%channel_id, %message_id, %user_id, "Message pinned"); Ok(()) } /// Handle `pin:remove` — unpin a message. pub async fn unpin_message( &self, socket: Arc, data: &serde_json::Value, ) -> ImksResult<()> { let user_id = self.user_id(&socket)?; let (channel_id, message_id) = self.parse_pin_payload(data)?; self.ensure_member(&channel_id.to_string(), &user_id.to_string()) .await?; self.repo.unpin_message(channel_id, message_id).await?; if let Some(ns) = self.namespaces.get_namespace(&socket.namespace) { let ns = ns.clone(); let cid = channel_id.to_string(); let mid = message_id.to_string(); tokio::spawn(async move { ns.emit_to_room( &cid, "pin:removed", serde_json::json!({ "channel_id": cid, "message_id": mid, }), ) .await; }); } tracing::info!(%channel_id, %message_id, %user_id, "Message unpinned"); Ok(()) } fn parse_pin_payload(&self, data: &serde_json::Value) -> ImksResult<(Uuid, Uuid)> { let arr = data .as_array() .and_then(|a| a.first()) .ok_or_else(|| ImksError::InvalidInput("Expected [payload] array".into()))?; Ok(( Self::parse_field(arr, "channel_id")?, Self::parse_field(arr, "message_id")?, )) } }