]> Untitled Git - lemmy.git/blob - crates/api/src/community/block.rs
4f740c916971182931600786dcfcbb24f000a5e2
[lemmy.git] / crates / api / src / community / block.rs
1 use crate::Perform;
2 use actix_web::web::Data;
3 use lemmy_api_common::{
4   community::{BlockCommunity, BlockCommunityResponse},
5   utils::{blocking, get_local_user_view_from_jwt},
6 };
7 use lemmy_apub::protocol::activities::following::undo_follow::UndoFollowCommunity;
8 use lemmy_db_schema::{
9   source::{
10     community::{Community, CommunityFollower, CommunityFollowerForm},
11     community_block::{CommunityBlock, CommunityBlockForm},
12   },
13   traits::{Blockable, Crud, Followable},
14 };
15 use lemmy_db_views_actor::structs::CommunityView;
16 use lemmy_utils::{ConnectionId, LemmyError};
17 use lemmy_websocket::LemmyContext;
18
19 #[async_trait::async_trait(?Send)]
20 impl Perform for BlockCommunity {
21   type Response = BlockCommunityResponse;
22
23   #[tracing::instrument(skip(context, _websocket_id))]
24   async fn perform(
25     &self,
26     context: &Data<LemmyContext>,
27     _websocket_id: Option<ConnectionId>,
28   ) -> Result<BlockCommunityResponse, LemmyError> {
29     let data: &BlockCommunity = self;
30     let local_user_view =
31       get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
32
33     let community_id = data.community_id;
34     let person_id = local_user_view.person.id;
35     let community_block_form = CommunityBlockForm {
36       person_id,
37       community_id,
38     };
39
40     if data.block {
41       let block = move |conn: &'_ _| CommunityBlock::block(conn, &community_block_form);
42       blocking(context.pool(), block)
43         .await?
44         .map_err(|e| LemmyError::from_error_message(e, "community_block_already_exists"))?;
45
46       // Also, unfollow the community, and send a federated unfollow
47       let community_follower_form = CommunityFollowerForm {
48         community_id: data.community_id,
49         person_id,
50         pending: false,
51       };
52       blocking(context.pool(), move |conn: &'_ _| {
53         CommunityFollower::unfollow(conn, &community_follower_form)
54       })
55       .await?
56       .ok();
57       let community = blocking(context.pool(), move |conn| {
58         Community::read(conn, community_id)
59       })
60       .await??;
61       UndoFollowCommunity::send(&local_user_view.person.into(), &community.into(), context).await?;
62     } else {
63       let unblock = move |conn: &'_ _| CommunityBlock::unblock(conn, &community_block_form);
64       blocking(context.pool(), unblock)
65         .await?
66         .map_err(|e| LemmyError::from_error_message(e, "community_block_already_exists"))?;
67     }
68
69     let community_view = blocking(context.pool(), move |conn| {
70       CommunityView::read(conn, community_id, Some(person_id))
71     })
72     .await??;
73
74     Ok(BlockCommunityResponse {
75       blocked: data.block,
76       community_view,
77     })
78   }
79 }