X-Git-Url: http://these/git/?a=blobdiff_plain;f=crates%2Fapi%2Fsrc%2Fcommunity%2Ffollow.rs;h=2a50a94edcc982192692ddfed681909b6d23dc34;hb=c8063f3267cf2b3622f1fdc69128c6b55feefbbc;hp=df9fae3cfaa5d2cd04b51fdae2862f13440a09dd;hpb=48f5a2ee5e44f381e86b11f148f2e2a99ac94ef6;p=lemmy.git diff --git a/crates/api/src/community/follow.rs b/crates/api/src/community/follow.rs index df9fae3c..2a50a94e 100644 --- a/crates/api/src/community/follow.rs +++ b/crates/api/src/community/follow.rs @@ -1,94 +1,71 @@ -use crate::Perform; -use actix_web::web::Data; +use activitypub_federation::config::Data; +use actix_web::web::Json; use lemmy_api_common::{ - community::{FollowCommunity, FollowCommunityResponse}, - utils::{ - blocking, - check_community_ban, - check_community_deleted_or_removed, - get_local_user_view_from_jwt, - }, -}; -use lemmy_apub::{ - objects::community::ApubCommunity, - protocol::activities::following::{ - follow::FollowCommunity as FollowCommunityApub, - undo_follow::UndoFollowCommunity, - }, + community::{CommunityResponse, FollowCommunity}, + context::LemmyContext, + send_activity::{ActivityChannel, SendActivityData}, + utils::{check_community_ban, check_community_deleted_or_removed, local_user_view_from_jwt}, }; use lemmy_db_schema::{ - source::community::{Community, CommunityFollower, CommunityFollowerForm}, + source::{ + actor_language::CommunityLanguage, + community::{Community, CommunityFollower, CommunityFollowerForm}, + }, traits::{Crud, Followable}, }; -use lemmy_db_views_actor::structs::CommunityFollowerView; -use lemmy_utils::{ConnectionId, LemmyError}; -use lemmy_websocket::LemmyContext; - -#[async_trait::async_trait(?Send)] -impl Perform for FollowCommunity { - type Response = FollowCommunityResponse; +use lemmy_db_views_actor::structs::CommunityView; +use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType}; - #[tracing::instrument(skip(context, _websocket_id))] - async fn perform( - &self, - context: &Data, - _websocket_id: Option, - ) -> Result { - let data: &FollowCommunity = self; - let local_user_view = - get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?; +#[tracing::instrument(skip(context))] +pub async fn follow_community( + data: Json, + context: Data, +) -> Result, LemmyError> { + let local_user_view = local_user_view_from_jwt(&data.auth, &context).await?; - let community_id = data.community_id; - let community: ApubCommunity = blocking(context.pool(), move |conn| { - Community::read(conn, community_id) - }) - .await?? - .into(); - let community_follower_form = CommunityFollowerForm { - community_id: data.community_id, - person_id: local_user_view.person.id, - pending: false, // Don't worry, this form isn't used for remote follows - }; + let community = Community::read(&mut context.pool(), data.community_id).await?; + let mut community_follower_form = CommunityFollowerForm { + community_id: community.id, + person_id: local_user_view.person.id, + pending: false, + }; + if data.follow { if community.local { - if data.follow { - check_community_ban(local_user_view.person.id, community_id, context.pool()).await?; - check_community_deleted_or_removed(community_id, context.pool()).await?; + check_community_ban(local_user_view.person.id, community.id, &mut context.pool()).await?; + check_community_deleted_or_removed(community.id, &mut context.pool()).await?; - let follow = move |conn: &'_ _| CommunityFollower::follow(conn, &community_follower_form); - blocking(context.pool(), follow) - .await? - .map_err(|e| LemmyError::from_error_message(e, "community_follower_already_exists"))?; - } else { - let unfollow = - move |conn: &'_ _| CommunityFollower::unfollow(conn, &community_follower_form); - blocking(context.pool(), unfollow) - .await? - .map_err(|e| LemmyError::from_error_message(e, "community_follower_already_exists"))?; - } - } else if data.follow { - // Dont actually add to the community followers here, because you need - // to wait for the accept - FollowCommunityApub::send(&local_user_view.person.clone().into(), &community, context) - .await?; + CommunityFollower::follow(&mut context.pool(), &community_follower_form) + .await + .with_lemmy_type(LemmyErrorType::CommunityFollowerAlreadyExists)?; } else { - UndoFollowCommunity::send(&local_user_view.person.clone().into(), &community, context) - .await?; - let unfollow = move |conn: &'_ _| CommunityFollower::unfollow(conn, &community_follower_form); - blocking(context.pool(), unfollow) - .await? - .map_err(|e| LemmyError::from_error_message(e, "community_follower_already_exists"))?; + // Mark as pending, the actual federation activity is sent via `SendActivity` handler + community_follower_form.pending = true; + CommunityFollower::follow(&mut context.pool(), &community_follower_form) + .await + .with_lemmy_type(LemmyErrorType::CommunityFollowerAlreadyExists)?; } + } + if !data.follow { + CommunityFollower::unfollow(&mut context.pool(), &community_follower_form) + .await + .with_lemmy_type(LemmyErrorType::CommunityFollowerAlreadyExists)?; + } - let community_id = data.community_id; - let person_id = local_user_view.person.id; - let community_follower_view = blocking(context.pool(), move |conn| { - CommunityFollowerView::read(conn, community_id, person_id) - }) - .await??; + ActivityChannel::submit_activity( + SendActivityData::FollowCommunity(community, local_user_view.person.clone(), data.follow), + &context, + ) + .await?; - Ok(Self::Response { - community_follower_view, - }) - } + let community_id = data.community_id; + let person_id = local_user_view.person.id; + let community_view = + CommunityView::read(&mut context.pool(), community_id, Some(person_id), false).await?; + let discussion_languages = CommunityLanguage::read(&mut context.pool(), community_id).await?; + + Ok(Json(CommunityResponse { + community_view, + discussion_languages, + })) }