diff --git a/DysonNetwork.Sphere/Account/NotificationService.cs b/DysonNetwork.Sphere/Account/NotificationService.cs index 3b43cc0..8b0d90d 100644 --- a/DysonNetwork.Sphere/Account/NotificationService.cs +++ b/DysonNetwork.Sphere/Account/NotificationService.cs @@ -215,7 +215,7 @@ public class NotificationService( var notifications = subDict.Select(value => { - int platformCode = value.Key switch + var platformCode = value.Key switch { NotificationPushProvider.Apple => 1, NotificationPushProvider.Google => 2, diff --git a/DysonNetwork.Sphere/Chat/ChatRoomController.cs b/DysonNetwork.Sphere/Chat/ChatRoomController.cs index 1d5be21..6961590 100644 --- a/DysonNetwork.Sphere/Chat/ChatRoomController.cs +++ b/DysonNetwork.Sphere/Chat/ChatRoomController.cs @@ -262,26 +262,19 @@ public class ChatRoomController( chatRoom.RealmId = member.RealmId; } - var chatRoomResourceId = $"chatroom:{chatRoom.Id}"; - if (request.PictureId is not null) { var picture = await db.Files.FindAsync(request.PictureId); if (picture is null) return BadRequest("Invalid picture id, unable to find the file on cloud."); // Remove old references for pictures - var oldPictureRefs = - await fileRefService.GetResourceReferencesAsync(chatRoomResourceId, "chat.room.picture"); - foreach (var oldRef in oldPictureRefs) - { - await fileRefService.DeleteReferenceAsync(oldRef.Id); - } + await fileRefService.DeleteResourceReferencesAsync(chatRoom.ResourceIdentifier, "chat.room.picture"); // Add a new reference await fileRefService.CreateReferenceAsync( picture.Id, "chat.room.picture", - chatRoomResourceId + chatRoom.ResourceIdentifier ); chatRoom.Picture = picture.ToReferenceObject(); @@ -293,18 +286,13 @@ public class ChatRoomController( if (background is null) return BadRequest("Invalid background id, unable to find the file on cloud."); // Remove old references for backgrounds - var oldBackgroundRefs = - await fileRefService.GetResourceReferencesAsync(chatRoomResourceId, "chat.room.background"); - foreach (var oldRef in oldBackgroundRefs) - { - await fileRefService.DeleteReferenceAsync(oldRef.Id); - } + await fileRefService.DeleteResourceReferencesAsync(chatRoom.ResourceIdentifier, "chat.room.background"); // Add a new reference await fileRefService.CreateReferenceAsync( background.Id, "chat.room.background", - chatRoomResourceId + chatRoom.ResourceIdentifier ); chatRoom.Background = background.ToReferenceObject(); diff --git a/DysonNetwork.Sphere/Publisher/PublisherController.cs b/DysonNetwork.Sphere/Publisher/PublisherController.cs index 76c49a9..e35f151 100644 --- a/DysonNetwork.Sphere/Publisher/PublisherController.cs +++ b/DysonNetwork.Sphere/Publisher/PublisherController.cs @@ -355,12 +355,7 @@ public class PublisherController( // Remove old references for the publisher picture if (publisher.Picture is not null) { - var oldPictureRefs = await fileRefService.GetResourceReferencesAsync( - publisher.ResourceIdentifier, - "publisher.picture" - ); - foreach (var oldRef in oldPictureRefs) - await fileRefService.DeleteReferenceAsync(oldRef.Id); + await fileRefService.DeleteResourceReferencesAsync(publisher.ResourceIdentifier, "publisher.picture"); } publisher.Picture = picture.ToReferenceObject(); @@ -378,17 +373,10 @@ public class PublisherController( var background = await db.Files.Where(f => f.Id == request.BackgroundId).FirstOrDefaultAsync(); if (background is null) return BadRequest("Invalid background id."); - var publisherResourceId = $"publisher:{publisher.Id}"; - // Remove old references for the publisher background if (publisher.Background is not null) { - var oldBackgroundRefs = - await fileRefService.GetResourceReferencesAsync(publisherResourceId, "publisher.background"); - foreach (var oldRef in oldBackgroundRefs) - { - await fileRefService.DeleteReferenceAsync(oldRef.Id); - } + await fileRefService.DeleteResourceReferencesAsync(publisher.ResourceIdentifier, "publisher.background"); } publisher.Background = background.ToReferenceObject(); @@ -397,7 +385,7 @@ public class PublisherController( await fileRefService.CreateReferenceAsync( background.Id, "publisher.background", - publisherResourceId + publisher.ResourceIdentifier ); } diff --git a/DysonNetwork.Sphere/Publisher/PublisherSubscriptionService.cs b/DysonNetwork.Sphere/Publisher/PublisherSubscriptionService.cs index 9475d16..c48dfbb 100644 --- a/DysonNetwork.Sphere/Publisher/PublisherSubscriptionService.cs +++ b/DysonNetwork.Sphere/Publisher/PublisherSubscriptionService.cs @@ -69,7 +69,7 @@ public class PublisherSubscriptionService( // Notify each subscriber var notifiedCount = 0; - foreach (var subscription in subscribers) + foreach (var subscription in subscribers.GroupBy(s => s.AccountId).Select(g => g.First())) { try { diff --git a/DysonNetwork.Sphere/Realm/RealmController.cs b/DysonNetwork.Sphere/Realm/RealmController.cs index ebbc2bf..2b12311 100644 --- a/DysonNetwork.Sphere/Realm/RealmController.cs +++ b/DysonNetwork.Sphere/Realm/RealmController.cs @@ -409,8 +409,6 @@ public class RealmController( if (request.IsPublic is not null) realm.IsPublic = request.IsPublic.Value; - var realmResourceId = $"realm:{realm.Id}"; - if (request.PictureId is not null) { var picture = await db.Files.FindAsync(request.PictureId); @@ -419,11 +417,7 @@ public class RealmController( // Remove old references for the realm picture if (realm.Picture is not null) { - var oldPictureRefs = await fileRefService.GetResourceReferencesAsync(realmResourceId, "realm.picture"); - foreach (var oldRef in oldPictureRefs) - { - await fileRefService.DeleteReferenceAsync(oldRef.Id); - } + await fileRefService.DeleteResourceReferencesAsync(realm.ResourceIdentifier, "realm.picture"); } realm.Picture = picture.ToReferenceObject(); @@ -432,7 +426,7 @@ public class RealmController( await fileRefService.CreateReferenceAsync( picture.Id, "realm.picture", - realmResourceId + realm.ResourceIdentifier ); } @@ -444,12 +438,7 @@ public class RealmController( // Remove old references for the realm background if (realm.Background is not null) { - var oldBackgroundRefs = - await fileRefService.GetResourceReferencesAsync(realmResourceId, "realm.background"); - foreach (var oldRef in oldBackgroundRefs) - { - await fileRefService.DeleteReferenceAsync(oldRef.Id); - } + await fileRefService.DeleteResourceReferencesAsync(realm.ResourceIdentifier, "realm.background"); } realm.Background = background.ToReferenceObject(); @@ -458,7 +447,7 @@ public class RealmController( await fileRefService.CreateReferenceAsync( background.Id, "realm.background", - realmResourceId + realm.ResourceIdentifier ); } diff --git a/DysonNetwork.Sphere/Storage/FileReferenceService.cs b/DysonNetwork.Sphere/Storage/FileReferenceService.cs index 4353ecc..6c92682 100644 --- a/DysonNetwork.Sphere/Storage/FileReferenceService.cs +++ b/DysonNetwork.Sphere/Storage/FileReferenceService.cs @@ -156,6 +156,36 @@ public class FileReferenceService(AppDatabase db, FileService fileService, ICach return deletedCount; } + /// + /// Deletes references for a specific resource and usage + /// + /// The ID of the resource + /// The usage context + /// The number of deleted references + public async Task DeleteResourceReferencesAsync(string resourceId, string usage) + { + var references = await db.FileReferences + .Where(r => r.ResourceId == resourceId && r.Usage == usage) + .ToListAsync(); + + if (!references.Any()) + { + return 0; + } + + var fileIds = references.Select(r => r.FileId).Distinct().ToList(); + + db.FileReferences.RemoveRange(references); + var deletedCount = await db.SaveChangesAsync(); + + // Purge caches + var tasks = fileIds.Select(fileService._PurgeCacheAsync).ToList(); + tasks.Add(PurgeCacheForResourceAsync(resourceId)); + await Task.WhenAll(tasks); + + return deletedCount; + } + /// /// Deletes a specific file reference ///