]> Untitled Git - lemmy.git/blob - crates/api/src/post/like.rs
add enable_federated_downvotes site option
[lemmy.git] / crates / api / src / post / like.rs
1 use activitypub_federation::config::Data;
2 use actix_web::web::Json;
3 use lemmy_api_common::{
4   build_response::build_post_response,
5   context::LemmyContext,
6   post::{CreatePostLike, PostResponse},
7   send_activity::{ActivityChannel, SendActivityData},
8   utils::{
9     check_community_ban,
10     check_community_deleted_or_removed,
11     check_downvotes_enabled,
12     local_user_view_from_jwt,
13     mark_post_as_read,
14   },
15 };
16 use lemmy_db_schema::{
17   source::{
18     community::Community,
19     local_site::LocalSite,
20     post::{Post, PostLike, PostLikeForm},
21   },
22   traits::{Crud, Likeable},
23 };
24 use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType};
25 use std::ops::Deref;
26
27 #[tracing::instrument(skip(context))]
28 pub async fn like_post(
29   data: Json<CreatePostLike>,
30   context: Data<LemmyContext>,
31 ) -> Result<Json<PostResponse>, LemmyError> {
32   let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?;
33   let local_site = LocalSite::read(&mut context.pool()).await?;
34
35   // Don't do a downvote if site has downvotes disabled
36   check_downvotes_enabled(data.score, &local_site)?;
37
38   // Check for a community ban
39   let post_id = data.post_id;
40   let post = Post::read(&mut context.pool(), post_id).await?;
41
42   check_community_ban(
43     local_user_view.person.id,
44     post.community_id,
45     &mut context.pool(),
46   )
47   .await?;
48   check_community_deleted_or_removed(post.community_id, &mut context.pool()).await?;
49
50   let like_form = PostLikeForm {
51     post_id: data.post_id,
52     person_id: local_user_view.person.id,
53     score: data.score,
54   };
55
56   // Remove any likes first
57   let person_id = local_user_view.person.id;
58
59   PostLike::remove(&mut context.pool(), person_id, post_id).await?;
60
61   // Only add the like if the score isnt 0
62   let do_add = like_form.score != 0 && (like_form.score == 1 || like_form.score == -1);
63   if do_add {
64     PostLike::like(&mut context.pool(), &like_form)
65       .await
66       .with_lemmy_type(LemmyErrorType::CouldntLikePost)?;
67   }
68
69   // Mark the post as read
70   mark_post_as_read(person_id, post_id, &mut context.pool()).await?;
71
72   ActivityChannel::submit_activity(
73     SendActivityData::LikePostOrComment(
74       post.ap_id,
75       local_user_view.person.clone(),
76       Community::read(&mut context.pool(), post.community_id).await?,
77       data.score,
78     ),
79     &context,
80   )
81   .await?;
82
83   build_post_response(
84     context.deref(),
85     post.community_id,
86     local_user_view.person.id,
87     post_id,
88   )
89   .await
90 }