use room::ws_context::WsUserContext; use crate::error::AppTransportError; use crate::event::{message, reaction}; use crate::handler::session::TransportSession; use crate::handler::types::WsOutEvent; pub(crate) async fn message_list( session: &TransportSession, room: models::RoomId, before_seq: Option, after_seq: Option, limit: Option, ) -> Result, AppTransportError> { let ctx = WsUserContext::new(session.user.user_id); let list = session .service .room .room_message_list(room, before_seq, after_seq, limit, &ctx) .await .map_err(|e| { tracing::warn!(error = %e, "room_message_list failed"); AppTransportError::Internal })?; let resp = message::MessageListService { room, messages: list .messages .iter() .map(|m| message::MessageNewService { id: m.id, seq: m.seq, room: m.room, sender_type: m.sender_type.clone(), sender_id: m.sender_id, display_name: m.display_name.clone(), thread: m.thread, in_reply_to: m.in_reply_to, content: m.content.clone(), content_type: m.content_type.clone(), thinking_content: m.thinking_content.clone(), thinking_is_chunked: m.thinking_is_chunked, send_at: m.send_at, reactions: Some( m.reactions .iter() .map(|r| reaction::ReactionGroup { emoji: r.emoji.clone(), count: r.count as i64, reacted_by_me: r.reacted_by_me, users: r .users .iter() .filter_map(|u| uuid::Uuid::parse_str(u).ok()) .collect(), }) .collect(), ), }) .collect(), total: list.total, }; Ok(Some(WsOutEvent::MessageList { room_id: room, data: resp, })) } pub(crate) async fn message_create( session: &TransportSession, room: models::RoomId, content: String, content_type: Option, thread: Option, in_reply_to: Option, ) -> Result, AppTransportError> { let ctx = WsUserContext::new(session.user.user_id); let msg = session .service .room .room_message_create( room, room::RoomMessageCreateRequest { content, content_type, thread, in_reply_to, attachment_ids: vec![], }, &ctx, ) .await .map_err(|e| { tracing::warn!(error = %e, "room_message_create failed"); AppTransportError::Internal })?; Ok(Some(WsOutEvent::MessageNew { room_id: room, data: message::MessageNewService { id: msg.id, seq: msg.seq, room: msg.room, sender_type: msg.sender_type, sender_id: msg.sender_id, display_name: msg.display_name, thread: msg.thread, in_reply_to: msg.in_reply_to, content: msg.content, content_type: msg.content_type, thinking_content: msg.thinking_content, thinking_is_chunked: false, send_at: msg.send_at, reactions: None, }, })) } pub(crate) async fn message_update( session: &TransportSession, message: uuid::Uuid, content: String, ) -> Result, AppTransportError> { let ctx = WsUserContext::new(session.user.user_id); session .service .room .room_message_update(message, room::RoomMessageUpdateRequest { content }, &ctx) .await .map_err(|e| { tracing::warn!(error = %e, "room_message_update failed"); AppTransportError::Internal })?; Ok(None) } pub(crate) async fn message_revoke( session: &TransportSession, message: uuid::Uuid, ) -> Result, AppTransportError> { let ctx = WsUserContext::new(session.user.user_id); session .service .room .room_message_revoke(message, &ctx) .await .map_err(|e| { tracing::warn!(error = %e, "room_message_revoke failed"); AppTransportError::Internal })?; Ok(None) }