};
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 {
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?;
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)
}
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?;
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)
}
UserOperation,
};
use std::str::FromStr;
+use lemmy_websocket::messages::JoinModRoom;
#[async_trait::async_trait(?Send)]
impl Perform for GetCommunity {
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 })
+ }
+}
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
}
LemmyError,
};
use lemmy_websocket::{
- messages::{GetPostUsersOnline, JoinPostRoom, SendPost, SendUserRoomMessage},
+ messages::{
+ GetPostUsersOnline,
+ JoinPostRoom,
+ SendModRoomMessage,
+ SendPost,
+ SendUserRoomMessage
+ },
LemmyContext,
UserOperation,
};
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?;
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)
}
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?;
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)
}
}
}
-#[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]
+#[derive(Identifiable, Queryable, Associations, PartialEq, Debug, Serialize)]
#[belongs_to(Comment)]
#[table_name = "comment_report"]
pub struct CommentReport {
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,
+}
/// 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>>,
sessions: HashMap::new(),
post_rooms: HashMap::new(),
community_rooms: HashMap::new(),
+ mod_rooms: HashMap::new(),
user_rooms: HashMap::new(),
rng: rand::thread_rng(),
pool,
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() {
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,
}
}
+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 = ();
}
}
+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 = ();
SaveSiteConfig,
PostJoin,
CommunityJoin,
+ ModJoin,
}
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 {
pub id: ConnectionId,
}
+#[derive(Message)]
+#[rtype(result = "()")]
+pub struct JoinModRoom {
+ pub community_id: CommunityId,
+ pub id: ConnectionId,
+}
+
#[derive(Message)]
#[rtype(result = "()")]
pub struct JoinPostRoom {
.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(