]> Untitled Git - lemmy.git/blob - crates/api_crud/src/comment/update.rs
Rewrite apub comment (de)serialization using structs (ref #1657)
[lemmy.git] / crates / api_crud / src / comment / update.rs
1 use crate::PerformCrud;
2 use actix_web::web::Data;
3 use lemmy_api_common::{
4   blocking,
5   check_community_ban,
6   comment::*,
7   get_local_user_view_from_jwt,
8   send_local_notifs,
9 };
10 use lemmy_apub::activities::comment::update::UpdateComment;
11 use lemmy_db_queries::{source::comment::Comment_, DeleteableOrRemoveable};
12 use lemmy_db_schema::source::comment::*;
13 use lemmy_db_views::comment_view::CommentView;
14 use lemmy_utils::{
15   utils::{remove_slurs, scrape_text_for_mentions},
16   ApiError,
17   ConnectionId,
18   LemmyError,
19 };
20 use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperationCrud};
21
22 #[async_trait::async_trait(?Send)]
23 impl PerformCrud for EditComment {
24   type Response = CommentResponse;
25
26   async fn perform(
27     &self,
28     context: &Data<LemmyContext>,
29     websocket_id: Option<ConnectionId>,
30   ) -> Result<CommentResponse, LemmyError> {
31     let data: &EditComment = self;
32     let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
33
34     let comment_id = data.comment_id;
35     let orig_comment = blocking(context.pool(), move |conn| {
36       CommentView::read(conn, comment_id, None)
37     })
38     .await??;
39
40     check_community_ban(
41       local_user_view.person.id,
42       orig_comment.community.id,
43       context.pool(),
44     )
45     .await?;
46
47     // Verify that only the creator can edit
48     if local_user_view.person.id != orig_comment.creator.id {
49       return Err(ApiError::err("no_comment_edit_allowed").into());
50     }
51
52     // Do the update
53     let content_slurs_removed = remove_slurs(&data.content.to_owned());
54     let comment_id = data.comment_id;
55     let updated_comment = blocking(context.pool(), move |conn| {
56       Comment::update_content(conn, comment_id, &content_slurs_removed)
57     })
58     .await?
59     .map_err(|_| ApiError::err("couldnt_update_comment"))?;
60
61     // Send the apub update
62     UpdateComment::send(&updated_comment, &local_user_view.person, context).await?;
63
64     // Do the mentions / recipients
65     let updated_comment_content = updated_comment.content.to_owned();
66     let mentions = scrape_text_for_mentions(&updated_comment_content);
67     let recipient_ids = send_local_notifs(
68       mentions,
69       updated_comment,
70       local_user_view.person.clone(),
71       orig_comment.post,
72       context.pool(),
73       false,
74     )
75     .await?;
76
77     let comment_id = data.comment_id;
78     let person_id = local_user_view.person.id;
79     let mut comment_view = blocking(context.pool(), move |conn| {
80       CommentView::read(conn, comment_id, Some(person_id))
81     })
82     .await??;
83
84     // Blank out deleted or removed info
85     if comment_view.comment.deleted || comment_view.comment.removed {
86       comment_view.comment = comment_view.comment.blank_out_deleted_or_removed_info();
87     }
88
89     let res = CommentResponse {
90       comment_view,
91       recipient_ids,
92       form_id: data.form_id.to_owned(),
93     };
94
95     context.chat_server().do_send(SendComment {
96       op: UserOperationCrud::EditComment,
97       comment: res.clone(),
98       websocket_id,
99     });
100
101     Ok(res)
102   }
103 }