]> Untitled Git - lemmy.git/blob - lemmy_apub/src/activities/receive/comment.rs
700a2653c130a4f617e830d3b664b0c097d8fa01
[lemmy.git] / lemmy_apub / src / activities / receive / comment.rs
1 use crate::{activities::receive::get_actor_as_user, objects::FromApub, ActorType, NoteExt};
2 use activitystreams::{
3   activity::{ActorAndObjectRefExt, Create, Dislike, Like, Remove, Update},
4   base::ExtendsExt,
5 };
6 use anyhow::Context;
7 use lemmy_db::{
8   source::{
9     comment::{Comment, CommentLike, CommentLikeForm},
10     post::Post,
11   },
12   views::comment_view::CommentView,
13   Likeable,
14 };
15 use lemmy_structs::{blocking, comment::CommentResponse, send_local_notifs};
16 use lemmy_utils::{location_info, utils::scrape_text_for_mentions, LemmyError};
17 use lemmy_websocket::{messages::SendComment, LemmyContext, UserOperation};
18
19 pub(crate) async fn receive_create_comment(
20   create: Create,
21   context: &LemmyContext,
22   request_counter: &mut i32,
23 ) -> Result<(), LemmyError> {
24   let user = get_actor_as_user(&create, context, request_counter).await?;
25   let note = NoteExt::from_any_base(create.object().to_owned().one().context(location_info!())?)?
26     .context(location_info!())?;
27
28   let comment = Comment::from_apub(&note, context, user.actor_id()?, request_counter).await?;
29
30   let post_id = comment.post_id;
31   let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
32
33   // Note:
34   // Although mentions could be gotten from the post tags (they are included there), or the ccs,
35   // Its much easier to scrape them from the comment body, since the API has to do that
36   // anyway.
37   let mentions = scrape_text_for_mentions(&comment.content);
38   let recipient_ids =
39     send_local_notifs(mentions, comment.clone(), &user, post, context.pool(), true).await?;
40
41   // Refetch the view
42   let comment_view = blocking(context.pool(), move |conn| {
43     CommentView::read(conn, comment.id, None)
44   })
45   .await??;
46
47   let res = CommentResponse {
48     comment_view,
49     recipient_ids,
50     form_id: None,
51   };
52
53   context.chat_server().do_send(SendComment {
54     op: UserOperation::CreateComment,
55     comment: res,
56     websocket_id: None,
57   });
58
59   Ok(())
60 }
61
62 pub(crate) async fn receive_update_comment(
63   update: Update,
64   context: &LemmyContext,
65   request_counter: &mut i32,
66 ) -> Result<(), LemmyError> {
67   let note = NoteExt::from_any_base(update.object().to_owned().one().context(location_info!())?)?
68     .context(location_info!())?;
69   let user = get_actor_as_user(&update, context, request_counter).await?;
70
71   let comment = Comment::from_apub(&note, context, user.actor_id()?, request_counter).await?;
72
73   let comment_id = comment.id;
74   let post_id = comment.post_id;
75   let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??;
76
77   let mentions = scrape_text_for_mentions(&comment.content);
78   let recipient_ids =
79     send_local_notifs(mentions, comment, &user, post, context.pool(), false).await?;
80
81   // Refetch the view
82   let comment_view = blocking(context.pool(), move |conn| {
83     CommentView::read(conn, comment_id, None)
84   })
85   .await??;
86
87   let res = CommentResponse {
88     comment_view,
89     recipient_ids,
90     form_id: None,
91   };
92
93   context.chat_server().do_send(SendComment {
94     op: UserOperation::EditComment,
95     comment: res,
96     websocket_id: None,
97   });
98
99   Ok(())
100 }
101
102 pub(crate) async fn receive_like_comment(
103   like: Like,
104   comment: Comment,
105   context: &LemmyContext,
106   request_counter: &mut i32,
107 ) -> Result<(), LemmyError> {
108   let user = get_actor_as_user(&like, context, request_counter).await?;
109
110   let comment_id = comment.id;
111   let like_form = CommentLikeForm {
112     comment_id,
113     post_id: comment.post_id,
114     user_id: user.id,
115     score: 1,
116   };
117   let user_id = user.id;
118   blocking(context.pool(), move |conn| {
119     CommentLike::remove(conn, user_id, comment_id)?;
120     CommentLike::like(conn, &like_form)
121   })
122   .await??;
123
124   // Refetch the view
125   let comment_view = blocking(context.pool(), move |conn| {
126     CommentView::read(conn, comment_id, None)
127   })
128   .await??;
129
130   // TODO get those recipient actor ids from somewhere
131   let recipient_ids = vec![];
132   let res = CommentResponse {
133     comment_view,
134     recipient_ids,
135     form_id: None,
136   };
137
138   context.chat_server().do_send(SendComment {
139     op: UserOperation::CreateCommentLike,
140     comment: res,
141     websocket_id: None,
142   });
143
144   Ok(())
145 }
146
147 pub(crate) async fn receive_dislike_comment(
148   dislike: Dislike,
149   comment: Comment,
150   context: &LemmyContext,
151   request_counter: &mut i32,
152 ) -> Result<(), LemmyError> {
153   let user = get_actor_as_user(&dislike, context, request_counter).await?;
154
155   let comment_id = comment.id;
156   let like_form = CommentLikeForm {
157     comment_id,
158     post_id: comment.post_id,
159     user_id: user.id,
160     score: -1,
161   };
162   let user_id = user.id;
163   blocking(context.pool(), move |conn| {
164     CommentLike::remove(conn, user_id, comment_id)?;
165     CommentLike::like(conn, &like_form)
166   })
167   .await??;
168
169   // Refetch the view
170   let comment_view = blocking(context.pool(), move |conn| {
171     CommentView::read(conn, comment_id, None)
172   })
173   .await??;
174
175   // TODO get those recipient actor ids from somewhere
176   let recipient_ids = vec![];
177   let res = CommentResponse {
178     comment_view,
179     recipient_ids,
180     form_id: None,
181   };
182
183   context.chat_server().do_send(SendComment {
184     op: UserOperation::CreateCommentLike,
185     comment: res,
186     websocket_id: None,
187   });
188
189   Ok(())
190 }
191
192 pub(crate) async fn receive_delete_comment(
193   context: &LemmyContext,
194   comment: Comment,
195 ) -> Result<(), LemmyError> {
196   let deleted_comment = blocking(context.pool(), move |conn| {
197     Comment::update_deleted(conn, comment.id, true)
198   })
199   .await??;
200
201   // Refetch the view
202   let comment_id = deleted_comment.id;
203   let comment_view = blocking(context.pool(), move |conn| {
204     CommentView::read(conn, comment_id, None)
205   })
206   .await??;
207
208   // TODO get those recipient actor ids from somewhere
209   let recipient_ids = vec![];
210   let res = CommentResponse {
211     comment_view,
212     recipient_ids,
213     form_id: None,
214   };
215   context.chat_server().do_send(SendComment {
216     op: UserOperation::EditComment,
217     comment: res,
218     websocket_id: None,
219   });
220
221   Ok(())
222 }
223
224 pub(crate) async fn receive_remove_comment(
225   context: &LemmyContext,
226   _remove: Remove,
227   comment: Comment,
228 ) -> Result<(), LemmyError> {
229   let removed_comment = blocking(context.pool(), move |conn| {
230     Comment::update_removed(conn, comment.id, true)
231   })
232   .await??;
233
234   // Refetch the view
235   let comment_id = removed_comment.id;
236   let comment_view = blocking(context.pool(), move |conn| {
237     CommentView::read(conn, comment_id, None)
238   })
239   .await??;
240
241   // TODO get those recipient actor ids from somewhere
242   let recipient_ids = vec![];
243   let res = CommentResponse {
244     comment_view,
245     recipient_ids,
246     form_id: None,
247   };
248   context.chat_server().do_send(SendComment {
249     op: UserOperation::EditComment,
250     comment: res,
251     websocket_id: None,
252   });
253
254   Ok(())
255 }