]> Untitled Git - lemmy.git/blob - crates/apub/src/activities/voting/mod.rs
739c43051d4904396e9ec5b6db768392fee2317d
[lemmy.git] / crates / apub / src / activities / voting / mod.rs
1 use crate::{
2   activities::{
3     comment::send_websocket_message as send_comment_message,
4     post::send_websocket_message as send_post_message,
5   },
6   fetcher::{
7     objects::get_or_fetch_and_insert_post_or_comment,
8     person::get_or_fetch_and_upsert_person,
9   },
10   PostOrComment,
11 };
12 use lemmy_api_common::blocking;
13 use lemmy_db_queries::Likeable;
14 use lemmy_db_schema::source::{
15   comment::{Comment, CommentLike, CommentLikeForm},
16   post::{Post, PostLike, PostLikeForm},
17 };
18 use lemmy_utils::LemmyError;
19 use lemmy_websocket::{LemmyContext, UserOperation};
20 use std::ops::Deref;
21 use url::Url;
22
23 pub mod dislike;
24 pub mod like;
25 pub mod undo_dislike;
26 pub mod undo_like;
27
28 pub(in crate::activities::voting) async fn receive_like_or_dislike(
29   score: i16,
30   actor: &Url,
31   object: &Url,
32   context: &LemmyContext,
33   request_counter: &mut i32,
34 ) -> Result<(), LemmyError> {
35   match get_or_fetch_and_insert_post_or_comment(object, context, request_counter).await? {
36     PostOrComment::Post(p) => {
37       like_or_dislike_post(score, actor, p.deref(), context, request_counter).await
38     }
39     PostOrComment::Comment(c) => {
40       like_or_dislike_comment(score, actor, c.deref(), context, request_counter).await
41     }
42   }
43 }
44
45 async fn like_or_dislike_comment(
46   score: i16,
47   actor: &Url,
48   comment: &Comment,
49   context: &LemmyContext,
50   request_counter: &mut i32,
51 ) -> Result<(), LemmyError> {
52   let actor = get_or_fetch_and_upsert_person(actor, context, request_counter).await?;
53
54   let comment_id = comment.id;
55   let like_form = CommentLikeForm {
56     comment_id,
57     post_id: comment.post_id,
58     person_id: actor.id,
59     score,
60   };
61   let person_id = actor.id;
62   blocking(context.pool(), move |conn| {
63     CommentLike::remove(conn, person_id, comment_id)?;
64     CommentLike::like(conn, &like_form)
65   })
66   .await??;
67
68   send_comment_message(
69     comment_id,
70     vec![],
71     UserOperation::CreateCommentLike,
72     context,
73   )
74   .await
75 }
76
77 async fn like_or_dislike_post(
78   score: i16,
79   actor: &Url,
80   post: &Post,
81   context: &LemmyContext,
82   request_counter: &mut i32,
83 ) -> Result<(), LemmyError> {
84   let actor = get_or_fetch_and_upsert_person(actor, context, request_counter).await?;
85
86   let post_id = post.id;
87   let like_form = PostLikeForm {
88     post_id: post.id,
89     person_id: actor.id,
90     score,
91   };
92   let person_id = actor.id;
93   blocking(context.pool(), move |conn| {
94     PostLike::remove(conn, person_id, post_id)?;
95     PostLike::like(conn, &like_form)
96   })
97   .await??;
98
99   send_post_message(post.id, UserOperation::CreatePostLike, context).await
100 }
101
102 pub(in crate::activities::voting) async fn receive_undo_like_or_dislike(
103   actor: &Url,
104   object: &Url,
105   context: &LemmyContext,
106   request_counter: &mut i32,
107 ) -> Result<(), LemmyError> {
108   match get_or_fetch_and_insert_post_or_comment(object, context, request_counter).await? {
109     PostOrComment::Post(p) => {
110       undo_like_or_dislike_post(actor, p.deref(), context, request_counter).await
111     }
112     PostOrComment::Comment(c) => {
113       undo_like_or_dislike_comment(actor, c.deref(), context, request_counter).await
114     }
115   }
116 }
117
118 async fn undo_like_or_dislike_comment(
119   actor: &Url,
120   comment: &Comment,
121   context: &LemmyContext,
122   request_counter: &mut i32,
123 ) -> Result<(), LemmyError> {
124   let actor = get_or_fetch_and_upsert_person(actor, context, request_counter).await?;
125
126   let comment_id = comment.id;
127   let person_id = actor.id;
128   blocking(context.pool(), move |conn| {
129     CommentLike::remove(conn, person_id, comment_id)
130   })
131   .await??;
132
133   send_comment_message(
134     comment.id,
135     vec![],
136     UserOperation::CreateCommentLike,
137     context,
138   )
139   .await
140 }
141
142 async fn undo_like_or_dislike_post(
143   actor: &Url,
144   post: &Post,
145   context: &LemmyContext,
146   request_counter: &mut i32,
147 ) -> Result<(), LemmyError> {
148   let actor = get_or_fetch_and_upsert_person(actor, context, request_counter).await?;
149
150   let post_id = post.id;
151   let person_id = actor.id;
152   blocking(context.pool(), move |conn| {
153     PostLike::remove(conn, person_id, post_id)
154   })
155   .await??;
156   send_post_message(post.id, UserOperation::CreatePostLike, context).await
157 }