Compare commits

...

2 Commits

Author SHA1 Message Date
5757526ea5 Get user blocked users infra 2025-07-03 21:57:16 +08:00
6a9cd0905d Unblock user 2025-07-03 21:47:17 +08:00
3 changed files with 67 additions and 11 deletions

View File

@ -230,4 +230,24 @@ public class RelationshipController(AppDatabase db, RelationshipService rels) :
return BadRequest(err.Message);
}
}
[HttpDelete("{userId:guid}/block")]
[Authorize]
public async Task<ActionResult<Relationship>> UnblockUser(Guid userId)
{
if (HttpContext.Items["CurrentUser"] is not Account currentUser) return Unauthorized();
var relatedUser = await db.Accounts.FindAsync(userId);
if (relatedUser is null) return NotFound("Account was not found.");
try
{
var relationship = await rels.UnblockAccount(currentUser, relatedUser);
return relationship;
}
catch (InvalidOperationException err)
{
return BadRequest(err.Message);
}
}
}

View File

@ -7,6 +7,7 @@ namespace DysonNetwork.Sphere.Account;
public class RelationshipService(AppDatabase db, ICacheService cache)
{
private const string UserFriendsCacheKeyPrefix = "accounts:friends:";
private const string UserBlockedCacheKeyPrefix = "accounts:blocked:";
public async Task<bool> HasExistingRelationship(Guid accountId, Guid relatedId)
{
@ -50,9 +51,8 @@ public class RelationshipService(AppDatabase db, ICacheService cache)
db.AccountRelationships.Add(relationship);
await db.SaveChangesAsync();
await cache.RemoveAsync($"{UserFriendsCacheKeyPrefix}{relationship.AccountId}");
await cache.RemoveAsync($"{UserFriendsCacheKeyPrefix}{relationship.RelatedId}");
await PurgeRelationshipCache(sender.Id, target.Id);
return relationship;
}
@ -63,6 +63,18 @@ public class RelationshipService(AppDatabase db, ICacheService cache)
return await UpdateRelationship(sender.Id, target.Id, RelationshipStatus.Blocked);
return await CreateRelationship(sender, target, RelationshipStatus.Blocked);
}
public async Task<Relationship> UnblockAccount(Account sender, Account target)
{
var relationship = await GetRelationship(sender.Id, target.Id, RelationshipStatus.Blocked);
if (relationship is null) throw new ArgumentException("There is no relationship between you and the user.");
db.Remove(relationship);
await db.SaveChangesAsync();
await PurgeRelationshipCache(sender.Id, target.Id);
return relationship;
}
public async Task<Relationship> SendFriendRequest(Account sender, Account target)
{
@ -92,8 +104,7 @@ public class RelationshipService(AppDatabase db, ICacheService cache)
.Where(r => r.AccountId == accountId && r.RelatedId == relatedId && r.Status == RelationshipStatus.Pending)
.ExecuteDeleteAsync();
await cache.RemoveAsync($"{UserFriendsCacheKeyPrefix}{accountId}");
await cache.RemoveAsync($"{UserFriendsCacheKeyPrefix}{relatedId}");
await PurgeRelationshipCache(relationship.AccountId, relationship.RelatedId);
}
public async Task<Relationship> AcceptFriendRelationship(
@ -122,8 +133,7 @@ public class RelationshipService(AppDatabase db, ICacheService cache)
await db.SaveChangesAsync();
await cache.RemoveAsync($"{UserFriendsCacheKeyPrefix}{relationship.AccountId}");
await cache.RemoveAsync($"{UserFriendsCacheKeyPrefix}{relationship.RelatedId}");
await PurgeRelationshipCache(relationship.AccountId, relationship.RelatedId);
return relationshipBackward;
}
@ -137,15 +147,14 @@ public class RelationshipService(AppDatabase db, ICacheService cache)
db.Update(relationship);
await db.SaveChangesAsync();
await cache.RemoveAsync($"{UserFriendsCacheKeyPrefix}{accountId}");
await cache.RemoveAsync($"{UserFriendsCacheKeyPrefix}{relatedId}");
await PurgeRelationshipCache(accountId, relatedId);
return relationship;
}
public async Task<List<Guid>> ListAccountFriends(Account account)
{
string cacheKey = $"{UserFriendsCacheKeyPrefix}{account.Id}";
var cacheKey = $"{UserFriendsCacheKeyPrefix}{account.Id}";
var friends = await cache.GetAsync<List<Guid>>(cacheKey);
if (friends == null)
@ -161,6 +170,25 @@ public class RelationshipService(AppDatabase db, ICacheService cache)
return friends ?? [];
}
public async Task<List<Guid>> ListAccountBlocked(Account account)
{
var cacheKey = $"{UserBlockedCacheKeyPrefix}{account.Id}";
var blocked = await cache.GetAsync<List<Guid>>(cacheKey);
if (blocked == null)
{
blocked = await db.AccountRelationships
.Where(r => r.RelatedId == account.Id)
.Where(r => r.Status == RelationshipStatus.Blocked)
.Select(r => r.AccountId)
.ToListAsync();
await cache.SetAsync(cacheKey, blocked, TimeSpan.FromHours(1));
}
return blocked ?? [];
}
public async Task<bool> HasRelationshipWithStatus(Guid accountId, Guid relatedId,
RelationshipStatus status = RelationshipStatus.Friends)
@ -168,4 +196,12 @@ public class RelationshipService(AppDatabase db, ICacheService cache)
var relationship = await GetRelationship(accountId, relatedId, status);
return relationship is not null;
}
private async Task PurgeRelationshipCache(Guid accountId, Guid relatedId)
{
await cache.RemoveAsync($"{UserFriendsCacheKeyPrefix}{accountId}");
await cache.RemoveAsync($"{UserFriendsCacheKeyPrefix}{relatedId}");
await cache.RemoveAsync($"{UserBlockedCacheKeyPrefix}{accountId}");
await cache.RemoveAsync($"{UserBlockedCacheKeyPrefix}{relatedId}");
}
}

View File

@ -126,7 +126,7 @@ public class ActivityService(
var activities = new List<Activity>();
var userFriends = await rels.ListAccountFriends(currentUser);
var userPublishers = await pub.GetUserPublishers(currentUser.Id);
debugInclude ??= new HashSet<string>();
debugInclude ??= [];
if (string.IsNullOrEmpty(filter))
{