]> Untitled Git - lemmy.git/commitdiff
add mod room websocket impl
authoreiknat <eiknat@protonmail.com>
Tue, 27 Oct 2020 00:25:18 +0000 (20:25 -0400)
committereiknat <eiknat@dev.chapo.chat>
Wed, 11 Nov 2020 20:11:52 +0000 (15:11 -0500)
lemmy_api/src/comment.rs
lemmy_api/src/community.rs
lemmy_api/src/lib.rs
lemmy_api/src/post.rs
lemmy_db/src/comment_report.rs
lemmy_structs/src/community.rs
lemmy_websocket/src/chat_server.rs
lemmy_websocket/src/handlers.rs
lemmy_websocket/src/lib.rs
lemmy_websocket/src/messages.rs
src/routes/api.rs

index e9ed0a445db726b95aae2811d8708989010e076c..2b0ee0544459b338cd3e0b1b11744150b411e74d 100644 (file)
@@ -34,6 +34,7 @@ use lemmy_utils::{
 };
 use lemmy_websocket::{messages::{SendComment, SendUserRoomMessage}, LemmyContext, UserOperation};
 use std::str::FromStr;
+use lemmy_websocket::messages::SendModRoomMessage;
 
 #[async_trait::async_trait(?Send)]
 impl Perform for CreateComment {
@@ -693,7 +694,7 @@ impl Perform for CreateCommentReport {
   async fn perform(
     &self,
     context: &Data<LemmyContext>,
-    _websocket_id: Option<ConnectionId>,
+    websocket_id: Option<ConnectionId>,
   ) -> Result<CreateCommentReportResponse, LemmyError> {
     let data: &CreateCommentReport = &self;
     let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@@ -722,24 +723,28 @@ impl Perform for CreateCommentReport {
       reason: data.reason.to_owned(),
     };
 
-    let _report = match blocking(context.pool(), move |conn| {
+    let report = match blocking(context.pool(), move |conn| {
       CommentReport::report(conn, &report_form)
     }).await? {
       Ok(report) => report,
       Err(_e) => return Err(APIError::err("couldnt_create_report").into())
     };
 
-    // to build on this, the user should get a success response, however
-    // mods should get a different response with more details
     let res = CreateCommentReportResponse { success: true };
 
-    // TODO this needs to use a SendModRoomMessage
-    // context.chat_server().do_send(SendUserRoomMessage {
-    //   op: UserOperation::CreateReport,
-    //   response: res.clone(),
-    //   recipient_id: user.id,
-    //   websocket_id,
-    // });
+    context.chat_server().do_send(SendUserRoomMessage {
+      op: UserOperation::CreateCommentReport,
+      response: res.clone(),
+      recipient_id: user.id,
+      websocket_id,
+    });
+
+    context.chat_server().do_send(SendModRoomMessage {
+      op: UserOperation::CreateCommentReport,
+      response: report,
+      community_id: comment.community_id,
+      websocket_id,
+    });
 
     Ok(res)
   }
@@ -752,7 +757,7 @@ impl Perform for ResolveCommentReport {
   async fn perform(
     &self,
     context: &Data<LemmyContext>,
-    _websocket_id: Option<ConnectionId>,
+    websocket_id: Option<ConnectionId>,
   ) -> Result<ResolveCommentReportResponse, LemmyError> {
     let data: &ResolveCommentReport = &self;
     let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@@ -784,13 +789,12 @@ impl Perform for ResolveCommentReport {
       resolved,
     };
 
-    // TODO this needs to use a SendModRoomMessage
-    // context.chat_server().do_send(SendUserRoomMessage {
-    //   op: UserOperation::ResolveCommentReport,
-    //   response: res.clone(),
-    //   recipient_id: user.id,
-    //   websocket_id,
-    // });
+    context.chat_server().do_send(SendModRoomMessage {
+      op: UserOperation::ResolveCommentReport,
+      response: res.clone(),
+      community_id: report.community_id,
+      websocket_id,
+    });
 
     Ok(res)
   }
index a9e130b9b7589751d0f7490cc9e1ffe6dd03b5e4..ae19c5f8f85ebfdfe78d3dd0b4cfed5feff23061 100644 (file)
@@ -41,6 +41,7 @@ use lemmy_websocket::{
   UserOperation,
 };
 use std::str::FromStr;
+use lemmy_websocket::messages::JoinModRoom;
 
 #[async_trait::async_trait(?Send)]
 impl Perform for GetCommunity {
@@ -883,3 +884,26 @@ impl Perform for CommunityJoin {
     Ok(CommunityJoinResponse { joined: true })
   }
 }
+
+// is this the right place for this?
+#[async_trait::async_trait(?Send)]
+impl Perform for ModJoin {
+  type Response = ModJoinResponse;
+
+  async fn perform(
+    &self,
+    context: &Data<LemmyContext>,
+    websocket_id: Option<ConnectionId>,
+  ) -> Result<ModJoinResponse, LemmyError> {
+    let data: &ModJoin = &self;
+
+    if let Some(ws_id) = websocket_id {
+      context.chat_server().do_send(JoinModRoom {
+        community_id: data.community_id,
+        id: ws_id,
+      });
+    }
+
+    Ok(ModJoinResponse { joined: true })
+  }
+}
index 38cf80435309ab40646eac18a996c1842c916b56..96f2b0612666a31d069046c3cfe19f5ad5cefd40 100644 (file)
@@ -195,6 +195,9 @@ pub async fn match_websocket_operation(
     UserOperation::CommunityJoin => {
       do_websocket_operation::<CommunityJoin>(context, id, op, data).await
     }
+    UserOperation::ModJoin => {
+      do_websocket_operation::<ModJoin>(context, id, op, data).await
+    }
     UserOperation::SaveUserSettings => {
       do_websocket_operation::<SaveUserSettings>(context, id, op, data).await
     }
index 0bf76b4d4dcaf44670935633cb82fc4fbf7096a0..0abb879cf81ae9923ddb91aa5b7972ce4cbe0009 100644 (file)
@@ -35,7 +35,13 @@ use lemmy_utils::{
   LemmyError,
 };
 use lemmy_websocket::{
-  messages::{GetPostUsersOnline, JoinPostRoom, SendPost, SendUserRoomMessage},
+  messages::{
+    GetPostUsersOnline,
+    JoinPostRoom,
+    SendModRoomMessage,
+    SendPost,
+    SendUserRoomMessage
+  },
   LemmyContext,
   UserOperation,
 };
@@ -752,7 +758,7 @@ impl Perform for CreatePostReport {
   async fn perform(
     &self,
     context: &Data<LemmyContext>,
-    _websocket_id: Option<ConnectionId>,
+    websocket_id: Option<ConnectionId>,
   ) -> Result<CreatePostReportResponse, LemmyError> {
     let data: &CreatePostReport = &self;
     let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@@ -783,24 +789,28 @@ impl Perform for CreatePostReport {
       reason: data.reason.to_owned(),
     };
 
-    let _report = match blocking(context.pool(), move |conn| {
+    let report = match blocking(context.pool(), move |conn| {
       PostReport::report(conn, &report_form)
     }).await? {
       Ok(report) => report,
       Err(_e) => return Err(APIError::err("couldnt_create_report").into())
     };
 
-    // to build on this, the user should get a success response, however
-    // mods should get a different response with more details
     let res = CreatePostReportResponse { success: true };
 
-    // TODO this needs to use a SendModRoomMessage
-    // context.chat_server().do_send(SendUserRoomMessage {
-    //   op: UserOperation::CreateReport,
-    //   response: res.clone(),
-    //   recipient_id: user.id,
-    //   websocket_id,
-    // });
+    context.chat_server().do_send(SendUserRoomMessage {
+      op: UserOperation::CreatePostReport,
+      response: res.clone(),
+      recipient_id: user.id,
+      websocket_id,
+    });
+
+    context.chat_server().do_send(SendModRoomMessage {
+      op: UserOperation::CreatePostReport,
+      response: report,
+      community_id: post.community_id,
+      websocket_id,
+    });
 
     Ok(res)
   }
@@ -813,7 +823,7 @@ impl Perform for ResolvePostReport {
   async fn perform(
     &self,
     context: &Data<LemmyContext>,
-    _websocket_id: Option<ConnectionId>,
+    websocket_id: Option<ConnectionId>,
   ) -> Result<ResolvePostReportResponse, LemmyError> {
     let data: &ResolvePostReport = &self;
     let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@@ -844,13 +854,12 @@ impl Perform for ResolvePostReport {
       return Err(APIError::err("couldnt_resolve_report").into())
     };
 
-    // TODO this needs to use a SendModRoomMessage
-    // context.chat_server().do_send(SendUserRoomMessage {
-    //   op: UserOperation::ResolvePostReport,
-    //   response: res.clone(),
-    //   recipient_id: user.id,
-    //   websocket_id,
-    // });
+    context.chat_server().do_send(SendModRoomMessage {
+      op: UserOperation::ResolvePostReport,
+      response: res.clone(),
+      community_id: report.community_id,
+      websocket_id,
+    });
 
     Ok(res)
   }
index a2b4e1d30415371eb60f03605c501e5edefb06e1..a5ac701c197b8fdfb26404fd9e3f2cdd231e43af 100644 (file)
@@ -23,7 +23,7 @@ table! {
     }
 }
 
-#[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]
+#[derive(Identifiable, Queryable, Associations, PartialEq, Debug, Serialize)]
 #[belongs_to(Comment)]
 #[table_name = "comment_report"]
 pub struct CommentReport {
index 6c543eac252f28c017c3fe6342286481d4d19d14..3535c05a9fb029a54126dba188b064ee5dc1c884 100644 (file)
@@ -139,3 +139,13 @@ pub struct CommunityJoin {
 pub struct CommunityJoinResponse {
   pub joined: bool,
 }
+
+#[derive(Deserialize, Debug)]
+pub struct ModJoin {
+  pub community_id: i32,
+}
+
+#[derive(Serialize, Clone)]
+pub struct ModJoinResponse {
+  pub joined: bool,
+}
index 8346a32f60450ef8f727fe9e8bb9e65972dd2555..0a524e3db002129bf92323db93c1b780cc9c99fd 100644 (file)
@@ -47,6 +47,8 @@ pub struct ChatServer {
   /// A map from community to set of connectionIDs
   pub community_rooms: HashMap<CommunityId, HashSet<ConnectionId>>,
 
+  pub mod_rooms: HashMap<CommunityId, HashSet<ConnectionId>>,
+
   /// A map from user id to its connection ID for joined users. Remember a user can have multiple
   /// sessions (IE clients)
   pub(super) user_rooms: HashMap<UserId, HashSet<ConnectionId>>,
@@ -90,6 +92,7 @@ impl ChatServer {
       sessions: HashMap::new(),
       post_rooms: HashMap::new(),
       community_rooms: HashMap::new(),
+      mod_rooms: HashMap::new(),
       user_rooms: HashMap::new(),
       rng: rand::thread_rng(),
       pool,
@@ -130,6 +133,29 @@ impl ChatServer {
     Ok(())
   }
 
+  pub fn join_mod_room(
+    &mut self,
+    community_id: CommunityId,
+    id: ConnectionId,
+  ) -> Result<(), LemmyError> {
+    // remove session from all rooms
+    for sessions in self.mod_rooms.values_mut() {
+      sessions.remove(&id);
+    }
+
+    // If the room doesn't exist yet
+    if self.mod_rooms.get_mut(&community_id).is_none() {
+      self.mod_rooms.insert(community_id, HashSet::new());
+    }
+
+    self
+      .mod_rooms
+      .get_mut(&community_id)
+      .context(location_info!())?
+      .insert(id);
+    Ok(())
+  }
+
   pub fn join_post_room(&mut self, post_id: PostId, id: ConnectionId) -> Result<(), LemmyError> {
     // remove session from all rooms
     for sessions in self.post_rooms.values_mut() {
@@ -227,6 +253,30 @@ impl ChatServer {
     Ok(())
   }
 
+  pub fn send_mod_room_message<Response>(
+    &self,
+    op: &UserOperation,
+    response: &Response,
+    community_id: CommunityId,
+    websocket_id: Option<ConnectionId>,
+  ) -> Result<(), LemmyError>
+    where
+      Response: Serialize,
+  {
+    let res_str = &serialize_websocket_message(op, response)?;
+    if let Some(sessions) = self.mod_rooms.get(&community_id) {
+      for id in sessions {
+        if let Some(my_id) = websocket_id {
+          if *id == my_id {
+            continue;
+          }
+        }
+        self.sendit(res_str, *id);
+      }
+    }
+    Ok(())
+  }
+
   pub fn send_all_message<Response>(
     &self,
     op: &UserOperation,
index 258098d6276a298b919cb63b8d6139a265067692..0b5703ab1ea94d29cd4262a0fd926e4958dde760 100644 (file)
@@ -120,6 +120,19 @@ where
   }
 }
 
+impl<Response> Handler<SendModRoomMessage<Response>> for ChatServer
+  where
+    Response: Serialize,
+{
+  type Result = ();
+
+  fn handle(&mut self, msg: SendModRoomMessage<Response>, _: &mut Context<Self>) {
+    self
+      .send_mod_room_message(&msg.op, &msg.response, msg.community_id, msg.websocket_id)
+      .ok();
+  }
+}
+
 impl Handler<SendPost> for ChatServer {
   type Result = ();
 
@@ -154,6 +167,14 @@ impl Handler<JoinCommunityRoom> for ChatServer {
   }
 }
 
+impl Handler<JoinModRoom> for ChatServer {
+  type Result = ();
+
+  fn handle(&mut self, msg: JoinModRoom, _: &mut Context<Self>) {
+    self.join_mod_room(msg.community_id, msg.id).ok();
+  }
+}
+
 impl Handler<JoinPostRoom> for ChatServer {
   type Result = ();
 
index 7673510cd36cb50db0bae4be8b4ef902b87f0fd5..d789efdd1bfe6c98a9b17b1cb27cfd0d542a7cda 100644 (file)
@@ -148,4 +148,5 @@ pub enum UserOperation {
   SaveSiteConfig,
   PostJoin,
   CommunityJoin,
+  ModJoin,
 }
index d9f8320a8dcdc028bc4cfd1d57f841f702275ee7..c678a96ef202d0899497e64ea4104d4c57bf63bd 100644 (file)
@@ -63,6 +63,15 @@ pub struct SendCommunityRoomMessage<Response> {
   pub websocket_id: Option<ConnectionId>,
 }
 
+#[derive(Message)]
+#[rtype(result = "()")]
+pub struct SendModRoomMessage<Response> {
+  pub op: UserOperation,
+  pub response: Response,
+  pub community_id: CommunityId,
+  pub websocket_id: Option<ConnectionId>,
+}
+
 #[derive(Message)]
 #[rtype(result = "()")]
 pub struct SendPost {
@@ -93,6 +102,13 @@ pub struct JoinCommunityRoom {
   pub id: ConnectionId,
 }
 
+#[derive(Message)]
+#[rtype(result = "()")]
+pub struct JoinModRoom {
+  pub community_id: CommunityId,
+  pub id: ConnectionId,
+}
+
 #[derive(Message)]
 #[rtype(result = "()")]
 pub struct JoinPostRoom {
index e6d6b31a958f098adaef3158b371b9783dfc88d9..7b95b4ee4aff32c44c337b45a3a883e71404740f 100644 (file)
@@ -57,7 +57,8 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimit) {
           .route("/transfer", web::post().to(route_post::<TransferCommunity>))
           .route("/ban_user", web::post().to(route_post::<BanFromCommunity>))
           .route("/mod", web::post().to(route_post::<AddModToCommunity>))
-          .route("/join", web::post().to(route_post::<CommunityJoin>)),
+          .route("/join", web::post().to(route_post::<CommunityJoin>))
+          .route("/mod/join", web::post().to(route_post::<ModJoin>)),
       )
       // Post
       .service(