diff --git a/Iceshrimp.Backend/Controllers/Mastodon/AccountController.cs b/Iceshrimp.Backend/Controllers/Mastodon/AccountController.cs index ba639f77..f04a71d9 100644 --- a/Iceshrimp.Backend/Controllers/Mastodon/AccountController.cs +++ b/Iceshrimp.Backend/Controllers/Mastodon/AccountController.cs @@ -106,6 +106,12 @@ public class AccountController( await db.AddAsync(following); } + // If user is local, we need to increment following/follower counts here, otherwise we'll do it when receiving the Accept activity + if (followee.Host == null) { + followee.FollowersCount++; + user.FollowingCount++; + } + await db.SaveChangesAsync(); if (followee.IsLocked) @@ -158,7 +164,12 @@ public class AccountController( } if (followee.PrecomputedIsFollowedBy ?? false) { - await db.Followings.Where(p => p.Follower == user && p.Followee == followee).ExecuteDeleteAsync(); + var followings = await db.Followings.Where(p => p.Follower == user && p.Followee == followee).ToListAsync(); + user.FollowingCount -= followings.Count; + followee.FollowersCount -= followings.Count; + db.RemoveRange(followings); + await db.SaveChangesAsync(); + followee.PrecomputedIsFollowedBy = false; } diff --git a/Iceshrimp.Backend/Core/Federation/ActivityPub/ActivityHandlerService.cs b/Iceshrimp.Backend/Core/Federation/ActivityPub/ActivityHandlerService.cs index 167d4327..5bf286c5 100644 --- a/Iceshrimp.Backend/Core/Federation/ActivityPub/ActivityHandlerService.cs +++ b/Iceshrimp.Backend/Core/Federation/ActivityPub/ActivityHandlerService.cs @@ -155,6 +155,9 @@ public class ActivityHandlerService( FollowerSharedInbox = follower.SharedInbox }; + follower.FollowingCount++; + followee.FollowersCount++; + await db.AddAsync(following); await db.SaveChangesAsync(); } @@ -166,7 +169,15 @@ public class ActivityHandlerService( var followee = await userResolver.ResolveAsync(followeeActor.Id); await db.FollowRequests.Where(p => p.Follower == follower && p.Followee == followee).ExecuteDeleteAsync(); - await db.Followings.Where(p => p.Follower == follower && p.Followee == followee).ExecuteDeleteAsync(); + + // We don't want to use ExecuteDelete for this one to ensure consistency with following counters + var followings = await db.Followings.Where(p => p.Follower == follower && p.Followee == followee).ToListAsync(); + if (followings.Count > 0) { + followee.FollowersCount -= followings.Count; + follower.FollowingCount -= followings.Count; + db.RemoveRange(followings); + await db.SaveChangesAsync(); + } } private async Task AcceptAsync(ASObject obj, ASObject actor) { @@ -200,6 +211,10 @@ public class ActivityHandlerService( FollowerSharedInbox = request.FollowerSharedInbox, FolloweeSharedInbox = request.FolloweeSharedInbox }; + + resolvedActor.FollowersCount++; + request.Follower.FollowingCount++; + db.Remove(request); await db.AddAsync(following); await db.SaveChangesAsync();