2 use actix_web::web::Data;
3 use lemmy_api_common::{
5 post::{CreatePostLike, PostResponse},
8 check_community_deleted_or_removed,
9 check_downvotes_enabled,
10 get_local_user_view_from_jwt,
13 websocket::UserOperation,
15 use lemmy_db_schema::{
17 local_site::LocalSite,
18 post::{Post, PostLike, PostLikeForm},
20 traits::{Crud, Likeable},
22 use lemmy_utils::{error::LemmyError, ConnectionId};
24 #[async_trait::async_trait(?Send)]
25 impl Perform for CreatePostLike {
26 type Response = PostResponse;
28 #[tracing::instrument(skip(context, websocket_id))]
31 context: &Data<LemmyContext>,
32 websocket_id: Option<ConnectionId>,
33 ) -> Result<PostResponse, LemmyError> {
34 let data: &CreatePostLike = self;
36 get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
37 let local_site = LocalSite::read(context.pool()).await?;
39 // Don't do a downvote if site has downvotes disabled
40 check_downvotes_enabled(data.score, &local_site)?;
42 // Check for a community ban
43 let post_id = data.post_id;
44 let post = Post::read(context.pool(), post_id).await?;
46 check_community_ban(local_user_view.person.id, post.community_id, context.pool()).await?;
47 check_community_deleted_or_removed(post.community_id, context.pool()).await?;
49 let like_form = PostLikeForm {
50 post_id: data.post_id,
51 person_id: local_user_view.person.id,
55 // Remove any likes first
56 let person_id = local_user_view.person.id;
58 PostLike::remove(context.pool(), person_id, post_id).await?;
60 // Only add the like if the score isnt 0
61 let do_add = like_form.score != 0 && (like_form.score == 1 || like_form.score == -1);
63 PostLike::like(context.pool(), &like_form)
65 .map_err(|e| LemmyError::from_error_message(e, "couldnt_like_post"))?;
68 // Mark the post as read
69 mark_post_as_read(person_id, post_id, context.pool()).await?;
72 .send_post_ws_message(
73 &UserOperation::CreatePostLike,
76 Some(local_user_view.person.id),