[backend/api] Add remove from followers endpoint

This commit is contained in:
pancakes 2024-10-31 11:22:47 +10:00 committed by Iceshrimp development
parent f2853d2d40
commit ea5408c182
2 changed files with 74 additions and 0 deletions

View file

@ -141,6 +141,25 @@ public class UserController(
await userSvc.FollowUserAsync(user, followee); await userSvc.FollowUserAsync(user, followee);
} }
[HttpPost("{id}/remove_from_followers")]
[ProducesResults(HttpStatusCode.OK)]
[ProducesErrors(HttpStatusCode.BadRequest, HttpStatusCode.NotFound)]
public async Task RemoveFromFollowers(string id)
{
var user = HttpContext.GetUserOrFail();
if (user.Id == id)
throw GracefulException.BadRequest("You cannot unfollow yourself");
var follower = await db.Users
.Where(p => p.Id == id)
.IncludeCommonProperties()
.PrecomputeRelationshipData(user)
.FirstOrDefaultAsync() ??
throw GracefulException.RecordNotFound();
await userSvc.RemoveFromFollowersAsync(user, follower);
}
[HttpPost("{id}/unfollow")] [HttpPost("{id}/unfollow")]
[ProducesErrors(HttpStatusCode.BadRequest, HttpStatusCode.NotFound)] [ProducesErrors(HttpStatusCode.BadRequest, HttpStatusCode.NotFound)]
public async Task UnfollowUser(string id) public async Task UnfollowUser(string id)

View file

@ -874,6 +874,61 @@ public class UserService(
} }
} }
/// <remarks>
/// Make sure to call .PrecomputeRelationshipData(user) on the database query for the followee
/// </remarks>
public async Task RemoveFromFollowersAsync(User user, User follower)
{
if ((follower.PrecomputedIsFollowing ?? false) && follower.IsRemoteUser)
{
var followingId = await db.Followings
.Where(p => p.Followee == user && p.Follower == follower)
.Select(p => p.Id)
.FirstAsync();
var accept = activityRenderer.RenderAccept(user, follower, followingId);
var activity = activityRenderer.RenderUndo(userRenderer.RenderLite(user), accept);
await deliverSvc.DeliverToAsync(activity, user, follower);
}
if (follower.PrecomputedIsFollowing ?? false)
{
var followers = await db.Followings
.Where(p => p.Followee == user && p.Follower == follower)
.ToListAsync();
await db.Users
.Where(p => p.Id == user.Id)
.ExecuteUpdateAsync(p => p.SetProperty(i => i.FollowersCount,
i => i.FollowersCount - followers.Count));
await db.Users
.Where(p => p.Id == follower.Id)
.ExecuteUpdateAsync(p => p.SetProperty(i => i.FollowingCount,
i => i.FollowingCount - followers.Count));
db.RemoveRange(followers);
await db.SaveChangesAsync();
if (follower.IsRemoteUser)
{
_ = followupTaskSvc.ExecuteTask("DecrementInstanceIncomingFollowsCounter", async provider =>
{
var bgDb = provider.GetRequiredService<DatabaseContext>();
var bgInstanceSvc = provider.GetRequiredService<InstanceService>();
var dbInstance =
await bgInstanceSvc.GetUpdatedInstanceMetadataAsync(follower);
await bgDb.Instances.Where(p => p.Id == dbInstance.Id)
.ExecuteUpdateAsync(p => p.SetProperty(i => i.IncomingFollows,
i => i.IncomingFollows - 1));
});
}
follower.PrecomputedIsFollowedBy = false;
eventSvc.RaiseUserUnfollowed(this, follower, user);
}
}
/// <remarks> /// <remarks>
/// Make sure to call .PrecomputeRelationshipData(user) on the database query for the followee /// Make sure to call .PrecomputeRelationshipData(user) on the database query for the followee
/// </remarks> /// </remarks>