]> Untitled Git - lemmy.git/blob - crates/api_crud/src/comment/update.rs
5d4d75a37207cef383e7e7e1e0f44d851ec959fb
[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   build_response::{build_comment_response, send_local_notifs},
5   comment::{CommentResponse, EditComment},
6   context::LemmyContext,
7   utils::{
8     check_community_ban,
9     local_site_to_slur_regex,
10     local_user_view_from_jwt,
11     sanitize_html_opt,
12   },
13 };
14 use lemmy_db_schema::{
15   source::{
16     actor_language::CommunityLanguage,
17     comment::{Comment, CommentUpdateForm},
18     local_site::LocalSite,
19   },
20   traits::Crud,
21   utils::naive_now,
22 };
23 use lemmy_db_views::structs::CommentView;
24 use lemmy_utils::{
25   error::{LemmyError, LemmyErrorExt, LemmyErrorType},
26   utils::{
27     mention::scrape_text_for_mentions,
28     slurs::remove_slurs,
29     validation::is_valid_body_field,
30   },
31 };
32 use std::ops::Deref;
33
34 #[async_trait::async_trait(?Send)]
35 impl PerformCrud for EditComment {
36   type Response = CommentResponse;
37
38   #[tracing::instrument(skip(context))]
39   async fn perform(&self, context: &Data<LemmyContext>) -> Result<CommentResponse, LemmyError> {
40     let data: &EditComment = self;
41     let local_user_view = local_user_view_from_jwt(&data.auth, context).await?;
42     let local_site = LocalSite::read(&mut context.pool()).await?;
43
44     let comment_id = data.comment_id;
45     let orig_comment = CommentView::read(&mut context.pool(), comment_id, None).await?;
46
47     check_community_ban(
48       local_user_view.person.id,
49       orig_comment.community.id,
50       &mut context.pool(),
51     )
52     .await?;
53
54     // Verify that only the creator can edit
55     if local_user_view.person.id != orig_comment.creator.id {
56       return Err(LemmyErrorType::NoCommentEditAllowed)?;
57     }
58
59     let language_id = self.language_id;
60     CommunityLanguage::is_allowed_community_language(
61       &mut context.pool(),
62       language_id,
63       orig_comment.community.id,
64     )
65     .await?;
66
67     // Update the Content
68     let content = data
69       .content
70       .as_ref()
71       .map(|c| remove_slurs(c, &local_site_to_slur_regex(&local_site)));
72     is_valid_body_field(&content, false)?;
73     let content = sanitize_html_opt(&content);
74
75     let comment_id = data.comment_id;
76     let form = CommentUpdateForm::builder()
77       .content(content)
78       .language_id(data.language_id)
79       .updated(Some(Some(naive_now())))
80       .build();
81     let updated_comment = Comment::update(&mut context.pool(), comment_id, &form)
82       .await
83       .with_lemmy_type(LemmyErrorType::CouldntUpdateComment)?;
84
85     // Do the mentions / recipients
86     let updated_comment_content = updated_comment.content.clone();
87     let mentions = scrape_text_for_mentions(&updated_comment_content);
88     let recipient_ids = send_local_notifs(
89       mentions,
90       &updated_comment,
91       &local_user_view.person,
92       &orig_comment.post,
93       false,
94       context,
95     )
96     .await?;
97
98     build_comment_response(
99       context.deref(),
100       updated_comment.id,
101       Some(local_user_view),
102       self.form_id.clone(),
103       recipient_ids,
104     )
105     .await
106   }
107 }