]> Untitled Git - lemmy.git/blob - crates/api_crud/src/comment/update.rs
Merge remote-tracking branch 'yerba/split-api-crate' into test_merge_api_crates_reorg
[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::ApubObjectType;
11 use lemmy_db_queries::source::comment::Comment_;
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 = match blocking(context.pool(), move |conn| {
56       Comment::update_content(conn, comment_id, &content_slurs_removed)
57     })
58     .await?
59     {
60       Ok(comment) => comment,
61       Err(_e) => return Err(ApiError::err("couldnt_update_comment").into()),
62     };
63
64     // Send the apub update
65     updated_comment
66       .send_update(&local_user_view.person, context)
67       .await?;
68
69     // Do the mentions / recipients
70     let updated_comment_content = updated_comment.content.to_owned();
71     let mentions = scrape_text_for_mentions(&updated_comment_content);
72     let recipient_ids = send_local_notifs(
73       mentions,
74       updated_comment,
75       local_user_view.person.clone(),
76       orig_comment.post,
77       context.pool(),
78       false,
79     )
80     .await?;
81
82     let comment_id = data.comment_id;
83     let person_id = local_user_view.person.id;
84     let comment_view = blocking(context.pool(), move |conn| {
85       CommentView::read(conn, comment_id, Some(person_id))
86     })
87     .await??;
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 }