]> Untitled Git - lemmy.git/blob - crates/api/src/comment/like.rs
13122b4be0823d943e9dbcf981f321906131c032
[lemmy.git] / crates / api / src / comment / like.rs
1 use activitypub_federation::config::Data;
2 use actix_web::web::Json;
3 use lemmy_api_common::{
4   build_response::build_comment_response,
5   comment::{CommentResponse, CreateCommentLike},
6   context::LemmyContext,
7   send_activity::{ActivityChannel, SendActivityData},
8   utils::{check_community_ban, check_downvotes_enabled, local_user_view_from_jwt},
9 };
10 use lemmy_db_schema::{
11   newtypes::LocalUserId,
12   source::{
13     comment::{CommentLike, CommentLikeForm},
14     comment_reply::CommentReply,
15     local_site::LocalSite,
16   },
17   traits::Likeable,
18 };
19 use lemmy_db_views::structs::{CommentView, LocalUserView};
20 use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType};
21 use std::ops::Deref;
22
23 #[tracing::instrument(skip(context))]
24 pub async fn like_comment(
25   data: Json<CreateCommentLike>,
26   context: Data<LemmyContext>,
27 ) -> Result<Json<CommentResponse>, LemmyError> {
28   let local_site = LocalSite::read(&mut context.pool()).await?;
29   let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?;
30
31   let mut recipient_ids = Vec::<LocalUserId>::new();
32
33   // Don't do a downvote if site has downvotes disabled
34   check_downvotes_enabled(data.score, &local_site)?;
35
36   let comment_id = data.comment_id;
37   let orig_comment = CommentView::read(&mut context.pool(), comment_id, None).await?;
38
39   check_community_ban(
40     local_user_view.person.id,
41     orig_comment.community.id,
42     &mut context.pool(),
43   )
44   .await?;
45
46   // Add parent poster or commenter to recipients
47   let comment_reply = CommentReply::read_by_comment(&mut context.pool(), comment_id).await;
48   if let Ok(reply) = comment_reply {
49     let recipient_id = reply.recipient_id;
50     if let Ok(local_recipient) = LocalUserView::read_person(&mut context.pool(), recipient_id).await
51     {
52       recipient_ids.push(local_recipient.local_user.id);
53     }
54   }
55
56   let like_form = CommentLikeForm {
57     comment_id: data.comment_id,
58     post_id: orig_comment.post.id,
59     person_id: local_user_view.person.id,
60     score: data.score,
61   };
62
63   // Remove any likes first
64   let person_id = local_user_view.person.id;
65
66   CommentLike::remove(&mut context.pool(), person_id, comment_id).await?;
67
68   // Only add the like if the score isnt 0
69   let do_add = like_form.score != 0 && (like_form.score == 1 || like_form.score == -1);
70   if do_add {
71     CommentLike::like(&mut context.pool(), &like_form)
72       .await
73       .with_lemmy_type(LemmyErrorType::CouldntLikeComment)?;
74   }
75
76   ActivityChannel::submit_activity(
77     SendActivityData::LikePostOrComment(
78       orig_comment.comment.ap_id,
79       local_user_view.person.clone(),
80       orig_comment.community,
81       data.score,
82     ),
83     &context,
84   )
85   .await?;
86
87   Ok(Json(
88     build_comment_response(
89       context.deref(),
90       comment_id,
91       Some(local_user_view),
92       None,
93       recipient_ids,
94     )
95     .await?,
96   ))
97 }