2 activities::community::send_activity_in_community,
3 activity_lists::AnnouncableActivities,
4 fetcher::post_or_comment::PostOrComment,
5 objects::{comment::ApubComment, person::ApubPerson, post::ApubPost},
6 protocol::activities::voting::{
8 vote::{Vote, VoteType},
12 use activitypub_federation::{config::Data, fetch::object_id::ObjectId};
13 use lemmy_api_common::{
14 comment::{CommentResponse, CreateCommentLike},
15 context::LemmyContext,
16 post::{CreatePostLike, PostResponse},
18 utils::local_user_view_from_jwt,
20 use lemmy_db_schema::{
21 newtypes::CommunityId,
23 comment::{CommentLike, CommentLikeForm},
26 post::{PostLike, PostLikeForm},
28 traits::{Crud, Likeable},
30 use lemmy_utils::error::LemmyError;
35 #[async_trait::async_trait]
36 impl SendActivity for CreatePostLike {
37 type Response = PostResponse;
39 async fn send_activity(
41 response: &Self::Response,
42 context: &Data<LemmyContext>,
43 ) -> Result<(), LemmyError> {
44 let object_id = ObjectId::from(response.post_view.post.ap_id.clone());
45 let community_id = response.post_view.community.id;
57 #[async_trait::async_trait]
58 impl SendActivity for CreateCommentLike {
59 type Response = CommentResponse;
61 async fn send_activity(
63 response: &Self::Response,
64 context: &Data<LemmyContext>,
65 ) -> Result<(), LemmyError> {
66 let object_id = ObjectId::from(response.comment_view.comment.ap_id.clone());
67 let community_id = response.comment_view.community.id;
79 async fn send_activity(
80 object_id: ObjectId<PostOrComment>,
81 community_id: CommunityId,
83 jwt: &Sensitive<String>,
84 context: &Data<LemmyContext>,
85 ) -> Result<(), LemmyError> {
86 let community = Community::read(&mut context.pool(), community_id)
89 let local_user_view = local_user_view_from_jwt(jwt, context).await?;
90 let actor = Person::read(&mut context.pool(), local_user_view.person.id)
94 // score of 1 means upvote, -1 downvote, 0 undo a previous vote
96 let vote = Vote::new(object_id, &actor, &community, score.try_into()?, context)?;
97 let activity = AnnouncableActivities::Vote(vote);
98 send_activity_in_community(activity, &actor, &community, vec![], false, context).await
100 // Lemmy API doesnt distinguish between Undo/Like and Undo/Dislike, so we hardcode it here.
101 let vote = Vote::new(object_id, &actor, &community, VoteType::Like, context)?;
102 let undo_vote = UndoVote::new(vote, &actor, &community, context)?;
103 let activity = AnnouncableActivities::UndoVote(undo_vote);
104 send_activity_in_community(activity, &actor, &community, vec![], false, context).await
108 #[tracing::instrument(skip_all)]
109 async fn vote_comment(
110 vote_type: &VoteType,
112 comment: &ApubComment,
113 context: &Data<LemmyContext>,
114 ) -> Result<(), LemmyError> {
115 let comment_id = comment.id;
116 let like_form = CommentLikeForm {
118 post_id: comment.post_id,
120 score: vote_type.into(),
122 let person_id = actor.id;
123 CommentLike::remove(&mut context.pool(), person_id, comment_id).await?;
124 CommentLike::like(&mut context.pool(), &like_form).await?;
128 #[tracing::instrument(skip_all)]
130 vote_type: &VoteType,
133 context: &Data<LemmyContext>,
134 ) -> Result<(), LemmyError> {
135 let post_id = post.id;
136 let like_form = PostLikeForm {
139 score: vote_type.into(),
141 let person_id = actor.id;
142 PostLike::remove(&mut context.pool(), person_id, post_id).await?;
143 PostLike::like(&mut context.pool(), &like_form).await?;
147 #[tracing::instrument(skip_all)]
148 async fn undo_vote_comment(
150 comment: &ApubComment,
151 context: &Data<LemmyContext>,
152 ) -> Result<(), LemmyError> {
153 let comment_id = comment.id;
154 let person_id = actor.id;
155 CommentLike::remove(&mut context.pool(), person_id, comment_id).await?;
159 #[tracing::instrument(skip_all)]
160 async fn undo_vote_post(
163 context: &Data<LemmyContext>,
164 ) -> Result<(), LemmyError> {
165 let post_id = post.id;
166 let person_id = actor.id;
167 PostLike::remove(&mut context.pool(), person_id, post_id).await?;