mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-11-26 11:21:02 +00:00
add mod room websocket impl
This commit is contained in:
parent
070efe72af
commit
30d784c27c
11 changed files with 180 additions and 41 deletions
|
@ -34,6 +34,7 @@ use lemmy_utils::{
|
||||||
};
|
};
|
||||||
use lemmy_websocket::{messages::{SendComment, SendUserRoomMessage}, LemmyContext, UserOperation};
|
use lemmy_websocket::{messages::{SendComment, SendUserRoomMessage}, LemmyContext, UserOperation};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
use lemmy_websocket::messages::SendModRoomMessage;
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl Perform for CreateComment {
|
impl Perform for CreateComment {
|
||||||
|
@ -693,7 +694,7 @@ impl Perform for CreateCommentReport {
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
_websocket_id: Option<ConnectionId>,
|
websocket_id: Option<ConnectionId>,
|
||||||
) -> Result<CreateCommentReportResponse, LemmyError> {
|
) -> Result<CreateCommentReportResponse, LemmyError> {
|
||||||
let data: &CreateCommentReport = &self;
|
let data: &CreateCommentReport = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
@ -722,24 +723,28 @@ impl Perform for CreateCommentReport {
|
||||||
reason: data.reason.to_owned(),
|
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)
|
CommentReport::report(conn, &report_form)
|
||||||
}).await? {
|
}).await? {
|
||||||
Ok(report) => report,
|
Ok(report) => report,
|
||||||
Err(_e) => return Err(APIError::err("couldnt_create_report").into())
|
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 };
|
let res = CreateCommentReportResponse { success: true };
|
||||||
|
|
||||||
// TODO this needs to use a SendModRoomMessage
|
context.chat_server().do_send(SendUserRoomMessage {
|
||||||
// context.chat_server().do_send(SendUserRoomMessage {
|
op: UserOperation::CreateCommentReport,
|
||||||
// op: UserOperation::CreateReport,
|
response: res.clone(),
|
||||||
// response: res.clone(),
|
recipient_id: user.id,
|
||||||
// recipient_id: user.id,
|
websocket_id,
|
||||||
// websocket_id,
|
});
|
||||||
// });
|
|
||||||
|
context.chat_server().do_send(SendModRoomMessage {
|
||||||
|
op: UserOperation::CreateCommentReport,
|
||||||
|
response: report,
|
||||||
|
community_id: comment.community_id,
|
||||||
|
websocket_id,
|
||||||
|
});
|
||||||
|
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
@ -752,7 +757,7 @@ impl Perform for ResolveCommentReport {
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
_websocket_id: Option<ConnectionId>,
|
websocket_id: Option<ConnectionId>,
|
||||||
) -> Result<ResolveCommentReportResponse, LemmyError> {
|
) -> Result<ResolveCommentReportResponse, LemmyError> {
|
||||||
let data: &ResolveCommentReport = &self;
|
let data: &ResolveCommentReport = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
@ -784,13 +789,12 @@ impl Perform for ResolveCommentReport {
|
||||||
resolved,
|
resolved,
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO this needs to use a SendModRoomMessage
|
context.chat_server().do_send(SendModRoomMessage {
|
||||||
// context.chat_server().do_send(SendUserRoomMessage {
|
op: UserOperation::ResolveCommentReport,
|
||||||
// op: UserOperation::ResolveCommentReport,
|
response: res.clone(),
|
||||||
// response: res.clone(),
|
community_id: report.community_id,
|
||||||
// recipient_id: user.id,
|
websocket_id,
|
||||||
// websocket_id,
|
});
|
||||||
// });
|
|
||||||
|
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ use lemmy_websocket::{
|
||||||
UserOperation,
|
UserOperation,
|
||||||
};
|
};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
use lemmy_websocket::messages::JoinModRoom;
|
||||||
|
|
||||||
#[async_trait::async_trait(?Send)]
|
#[async_trait::async_trait(?Send)]
|
||||||
impl Perform for GetCommunity {
|
impl Perform for GetCommunity {
|
||||||
|
@ -883,3 +884,26 @@ impl Perform for CommunityJoin {
|
||||||
Ok(CommunityJoinResponse { joined: true })
|
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 })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -195,6 +195,9 @@ pub async fn match_websocket_operation(
|
||||||
UserOperation::CommunityJoin => {
|
UserOperation::CommunityJoin => {
|
||||||
do_websocket_operation::<CommunityJoin>(context, id, op, data).await
|
do_websocket_operation::<CommunityJoin>(context, id, op, data).await
|
||||||
}
|
}
|
||||||
|
UserOperation::ModJoin => {
|
||||||
|
do_websocket_operation::<ModJoin>(context, id, op, data).await
|
||||||
|
}
|
||||||
UserOperation::SaveUserSettings => {
|
UserOperation::SaveUserSettings => {
|
||||||
do_websocket_operation::<SaveUserSettings>(context, id, op, data).await
|
do_websocket_operation::<SaveUserSettings>(context, id, op, data).await
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,13 @@ use lemmy_utils::{
|
||||||
LemmyError,
|
LemmyError,
|
||||||
};
|
};
|
||||||
use lemmy_websocket::{
|
use lemmy_websocket::{
|
||||||
messages::{GetPostUsersOnline, JoinPostRoom, SendPost, SendUserRoomMessage},
|
messages::{
|
||||||
|
GetPostUsersOnline,
|
||||||
|
JoinPostRoom,
|
||||||
|
SendModRoomMessage,
|
||||||
|
SendPost,
|
||||||
|
SendUserRoomMessage
|
||||||
|
},
|
||||||
LemmyContext,
|
LemmyContext,
|
||||||
UserOperation,
|
UserOperation,
|
||||||
};
|
};
|
||||||
|
@ -752,7 +758,7 @@ impl Perform for CreatePostReport {
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
_websocket_id: Option<ConnectionId>,
|
websocket_id: Option<ConnectionId>,
|
||||||
) -> Result<CreatePostReportResponse, LemmyError> {
|
) -> Result<CreatePostReportResponse, LemmyError> {
|
||||||
let data: &CreatePostReport = &self;
|
let data: &CreatePostReport = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
||||||
|
@ -783,24 +789,28 @@ impl Perform for CreatePostReport {
|
||||||
reason: data.reason.to_owned(),
|
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)
|
PostReport::report(conn, &report_form)
|
||||||
}).await? {
|
}).await? {
|
||||||
Ok(report) => report,
|
Ok(report) => report,
|
||||||
Err(_e) => return Err(APIError::err("couldnt_create_report").into())
|
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 };
|
let res = CreatePostReportResponse { success: true };
|
||||||
|
|
||||||
// TODO this needs to use a SendModRoomMessage
|
context.chat_server().do_send(SendUserRoomMessage {
|
||||||
// context.chat_server().do_send(SendUserRoomMessage {
|
op: UserOperation::CreatePostReport,
|
||||||
// op: UserOperation::CreateReport,
|
response: res.clone(),
|
||||||
// response: res.clone(),
|
recipient_id: user.id,
|
||||||
// recipient_id: user.id,
|
websocket_id,
|
||||||
// websocket_id,
|
});
|
||||||
// });
|
|
||||||
|
context.chat_server().do_send(SendModRoomMessage {
|
||||||
|
op: UserOperation::CreatePostReport,
|
||||||
|
response: report,
|
||||||
|
community_id: post.community_id,
|
||||||
|
websocket_id,
|
||||||
|
});
|
||||||
|
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
@ -813,7 +823,7 @@ impl Perform for ResolvePostReport {
|
||||||
async fn perform(
|
async fn perform(
|
||||||
&self,
|
&self,
|
||||||
context: &Data<LemmyContext>,
|
context: &Data<LemmyContext>,
|
||||||
_websocket_id: Option<ConnectionId>,
|
websocket_id: Option<ConnectionId>,
|
||||||
) -> Result<ResolvePostReportResponse, LemmyError> {
|
) -> Result<ResolvePostReportResponse, LemmyError> {
|
||||||
let data: &ResolvePostReport = &self;
|
let data: &ResolvePostReport = &self;
|
||||||
let user = get_user_from_jwt(&data.auth, context.pool()).await?;
|
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())
|
return Err(APIError::err("couldnt_resolve_report").into())
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO this needs to use a SendModRoomMessage
|
context.chat_server().do_send(SendModRoomMessage {
|
||||||
// context.chat_server().do_send(SendUserRoomMessage {
|
op: UserOperation::ResolvePostReport,
|
||||||
// op: UserOperation::ResolvePostReport,
|
response: res.clone(),
|
||||||
// response: res.clone(),
|
community_id: report.community_id,
|
||||||
// recipient_id: user.id,
|
websocket_id,
|
||||||
// websocket_id,
|
});
|
||||||
// });
|
|
||||||
|
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ table! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]
|
#[derive(Identifiable, Queryable, Associations, PartialEq, Debug, Serialize)]
|
||||||
#[belongs_to(Comment)]
|
#[belongs_to(Comment)]
|
||||||
#[table_name = "comment_report"]
|
#[table_name = "comment_report"]
|
||||||
pub struct CommentReport {
|
pub struct CommentReport {
|
||||||
|
|
|
@ -139,3 +139,13 @@ pub struct CommunityJoin {
|
||||||
pub struct CommunityJoinResponse {
|
pub struct CommunityJoinResponse {
|
||||||
pub joined: bool,
|
pub joined: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
pub struct ModJoin {
|
||||||
|
pub community_id: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Clone)]
|
||||||
|
pub struct ModJoinResponse {
|
||||||
|
pub joined: bool,
|
||||||
|
}
|
||||||
|
|
|
@ -47,6 +47,8 @@ pub struct ChatServer {
|
||||||
/// A map from community to set of connectionIDs
|
/// A map from community to set of connectionIDs
|
||||||
pub community_rooms: HashMap<CommunityId, HashSet<ConnectionId>>,
|
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
|
/// A map from user id to its connection ID for joined users. Remember a user can have multiple
|
||||||
/// sessions (IE clients)
|
/// sessions (IE clients)
|
||||||
pub(super) user_rooms: HashMap<UserId, HashSet<ConnectionId>>,
|
pub(super) user_rooms: HashMap<UserId, HashSet<ConnectionId>>,
|
||||||
|
@ -90,6 +92,7 @@ impl ChatServer {
|
||||||
sessions: HashMap::new(),
|
sessions: HashMap::new(),
|
||||||
post_rooms: HashMap::new(),
|
post_rooms: HashMap::new(),
|
||||||
community_rooms: HashMap::new(),
|
community_rooms: HashMap::new(),
|
||||||
|
mod_rooms: HashMap::new(),
|
||||||
user_rooms: HashMap::new(),
|
user_rooms: HashMap::new(),
|
||||||
rng: rand::thread_rng(),
|
rng: rand::thread_rng(),
|
||||||
pool,
|
pool,
|
||||||
|
@ -130,6 +133,29 @@ impl ChatServer {
|
||||||
Ok(())
|
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> {
|
pub fn join_post_room(&mut self, post_id: PostId, id: ConnectionId) -> Result<(), LemmyError> {
|
||||||
// remove session from all rooms
|
// remove session from all rooms
|
||||||
for sessions in self.post_rooms.values_mut() {
|
for sessions in self.post_rooms.values_mut() {
|
||||||
|
@ -227,6 +253,30 @@ impl ChatServer {
|
||||||
Ok(())
|
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>(
|
pub fn send_all_message<Response>(
|
||||||
&self,
|
&self,
|
||||||
op: &UserOperation,
|
op: &UserOperation,
|
||||||
|
|
|
@ -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 {
|
impl Handler<SendPost> for ChatServer {
|
||||||
type Result = ();
|
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 {
|
impl Handler<JoinPostRoom> for ChatServer {
|
||||||
type Result = ();
|
type Result = ();
|
||||||
|
|
||||||
|
|
|
@ -148,4 +148,5 @@ pub enum UserOperation {
|
||||||
SaveSiteConfig,
|
SaveSiteConfig,
|
||||||
PostJoin,
|
PostJoin,
|
||||||
CommunityJoin,
|
CommunityJoin,
|
||||||
|
ModJoin,
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,15 @@ pub struct SendCommunityRoomMessage<Response> {
|
||||||
pub websocket_id: Option<ConnectionId>,
|
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)]
|
#[derive(Message)]
|
||||||
#[rtype(result = "()")]
|
#[rtype(result = "()")]
|
||||||
pub struct SendPost {
|
pub struct SendPost {
|
||||||
|
@ -93,6 +102,13 @@ pub struct JoinCommunityRoom {
|
||||||
pub id: ConnectionId,
|
pub id: ConnectionId,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Message)]
|
||||||
|
#[rtype(result = "()")]
|
||||||
|
pub struct JoinModRoom {
|
||||||
|
pub community_id: CommunityId,
|
||||||
|
pub id: ConnectionId,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Message)]
|
#[derive(Message)]
|
||||||
#[rtype(result = "()")]
|
#[rtype(result = "()")]
|
||||||
pub struct JoinPostRoom {
|
pub struct JoinPostRoom {
|
||||||
|
|
|
@ -57,7 +57,8 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimit) {
|
||||||
.route("/transfer", web::post().to(route_post::<TransferCommunity>))
|
.route("/transfer", web::post().to(route_post::<TransferCommunity>))
|
||||||
.route("/ban_user", web::post().to(route_post::<BanFromCommunity>))
|
.route("/ban_user", web::post().to(route_post::<BanFromCommunity>))
|
||||||
.route("/mod", web::post().to(route_post::<AddModToCommunity>))
|
.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
|
// Post
|
||||||
.service(
|
.service(
|
||||||
|
|
Loading…
Reference in a new issue