use crate::error::RoomError; use crate::service::RoomService; use crate::ws_context::WsUserContext; use chrono::Utc; use models::rooms::room_message_reaction; use queue::ReactionGroup; use sea_orm::*; use uuid::Uuid; impl RoomService { pub async fn message_reaction_add( &self, message_id: Uuid, emoji: String, ctx: &WsUserContext, ) -> Result { let user_id = ctx.user_id; let message = self.find_message_or_404(message_id).await?; self.require_room_access(message.room, user_id).await?; Self::validate_emoji(&emoji)?; let txn = self.db.begin().await?; let existing = room_message_reaction::Entity::find() .filter(room_message_reaction::Column::Message.eq(message_id)) .filter(room_message_reaction::Column::User.eq(user_id)) .filter(room_message_reaction::Column::Emoji.eq(&emoji)) .one(&txn) .await?; if existing.is_some() { txn.commit().await?; return self.get_message_reactions(message_id, Some(user_id)).await; } let reaction = room_message_reaction::ActiveModel { id: Set(Uuid::now_v7()), room: Set(message.room), message: Set(message_id), user: Set(user_id), emoji: Set(emoji.clone()), created_at: Set(Utc::now()), }; room_message_reaction::Entity::insert(reaction) .exec(&txn) .await?; txn.commit().await?; let reactions = self .get_message_reactions(message_id, Some(user_id)) .await?; let groups = reactions .reactions .iter() .map(|g| ReactionGroup { emoji: g.emoji.clone(), count: g.count as i32, reacted_by_me: g.reacted_by_me, users: g.users.iter().filter_map(|u| u.parse().ok()).collect(), }) .collect(); self.queue .publish_reaction_event(message.room, message_id, groups) .await; self.get_message_reactions(message_id, Some(user_id)).await } pub async fn message_reaction_remove( &self, message_id: Uuid, emoji: String, ctx: &WsUserContext, ) -> Result { let user_id = ctx.user_id; let message = self.find_message_or_404(message_id).await?; self.require_room_access(message.room, user_id).await?; room_message_reaction::Entity::delete_many() .filter(room_message_reaction::Column::Message.eq(message_id)) .filter(room_message_reaction::Column::User.eq(user_id)) .filter(room_message_reaction::Column::Emoji.eq(&emoji)) .exec(&self.db) .await?; let reactions = self .get_message_reactions(message_id, Some(user_id)) .await?; let groups = reactions .reactions .iter() .map(|g| ReactionGroup { emoji: g.emoji.clone(), count: g.count as i32, reacted_by_me: g.reacted_by_me, users: g.users.iter().filter_map(|u| u.parse().ok()).collect(), }) .collect(); self.queue .publish_reaction_event(message.room, message_id, groups) .await; self.get_message_reactions(message_id, Some(user_id)).await } }