2 use actix_web::web::Data;
3 use lemmy_api_common::{
6 check_community_deleted_or_removed,
7 check_downvotes_enabled,
8 get_local_user_view_from_jwt,
10 post::{CreatePostLike, PostResponse},
13 fetcher::post_or_comment::PostOrComment,
14 objects::post::ApubPost,
15 protocol::activities::voting::{
17 vote::{Vote, VoteType},
20 use lemmy_db_schema::{
21 source::post::{Post, PostLike, PostLikeForm},
22 traits::{Crud, Likeable},
24 use lemmy_utils::{ConnectionId, LemmyError};
25 use lemmy_websocket::{send::send_post_ws_message, LemmyContext, UserOperation};
27 #[async_trait::async_trait(?Send)]
28 impl Perform for CreatePostLike {
29 type Response = PostResponse;
31 #[tracing::instrument(skip(context, websocket_id))]
34 context: &Data<LemmyContext>,
35 websocket_id: Option<ConnectionId>,
36 ) -> Result<PostResponse, LemmyError> {
37 let data: &CreatePostLike = self;
39 get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
41 // Don't do a downvote if site has downvotes disabled
42 check_downvotes_enabled(data.score, context.pool()).await?;
44 // Check for a community ban
45 let post_id = data.post_id;
46 let post: ApubPost = blocking(context.pool(), move |conn| Post::read(conn, post_id))
50 check_community_ban(local_user_view.person.id, post.community_id, context.pool()).await?;
51 check_community_deleted_or_removed(post.community_id, context.pool()).await?;
53 let like_form = PostLikeForm {
54 post_id: data.post_id,
55 person_id: local_user_view.person.id,
59 // Remove any likes first
60 let person_id = local_user_view.person.id;
61 blocking(context.pool(), move |conn| {
62 PostLike::remove(conn, person_id, post_id)
66 let community_id = post.community_id;
67 let object = PostOrComment::Post(Box::new(post));
69 // Only add the like if the score isnt 0
70 let do_add = like_form.score != 0 && (like_form.score == 1 || like_form.score == -1);
72 let like_form2 = like_form.clone();
73 let like = move |conn: &'_ _| PostLike::like(conn, &like_form2);
74 blocking(context.pool(), like)
76 .map_err(|e| LemmyError::from_error_message(e, "couldnt_like_post"))?;
80 &local_user_view.person.clone().into(),
82 like_form.score.try_into()?,
87 // API doesn't distinguish between Undo/Like and Undo/Dislike
90 &local_user_view.person.clone().into(),
98 // Mark the post as read
99 mark_post_as_read(person_id, post_id, context.pool()).await?;
101 send_post_ws_message(
103 UserOperation::CreatePostLike,
105 Some(local_user_view.person.id),