Skip to content

Commit 86a8627

Browse files
committed
feat(reactions): omit zero-value reaction counters
1 parent 9bdb461 commit 86a8627

8 files changed

Lines changed: 31 additions & 25 deletions

File tree

src/CrowdParlay.Social.Application/Services/SubjectsService.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@ public async Task SetReactionsAsync(string subjectId, Guid authorId, ISet<string
1919
throw new ForbiddenException("Such reaction set is not allowed.");
2020

2121
await subjectsRepository.SetReactionsAsync(subjectId, authorId, newReactions);
22-
23-
var reactionsToAdd = newReactions.Except(oldReactions).ToArray();
24-
var reactionsToRemove = oldReactions.Except(newReactions).ToArray();
25-
await subjectsRepository.UpdateReactionCountersAsync(subjectId, reactionsToAdd, reactionsToRemove);
22+
23+
var addedReactionsDiff = newReactions.Except(oldReactions).Select(reaction => new KeyValuePair<string, int>(reaction, 1));
24+
var removedReactionsDiff = oldReactions.Except(newReactions).Select(reaction => new KeyValuePair<string, int>(reaction, -1));
25+
var reactionsDiff = addedReactionsDiff.Concat(removedReactionsDiff).ToDictionary();
26+
await subjectsRepository.UpdateReactionCountersAsync(subjectId, reactionsDiff);
2627
}
2728
}

src/CrowdParlay.Social.Domain/Abstractions/ISubjectsRepository.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ public interface ISubjectsRepository
44
{
55
public Task<ISet<string>> GetReactionsAsync(string subjectId, Guid authorId);
66
public Task SetReactionsAsync(string subjectId, Guid authorId, ISet<string> reactions);
7-
public Task UpdateReactionCountersAsync(string subjectId, IEnumerable<string> reactionsToAdd, IEnumerable<string> reactionsToRemove);
7+
public Task UpdateReactionCountersAsync(string subjectId, IDictionary<string, int> reactionsDiff);
88
public Task IncludeCommentInMetadataAsync(string discussionId, Guid authorId);
99
public Task ExcludeCommentFromMetadataAsync(string discussionId);
1010

src/CrowdParlay.Social.Domain/Entities/Comment.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
namespace CrowdParlay.Social.Domain.Entities;
44

5-
65
[DebuggerDisplay("{Id} by {AuthorId} in reply to {SubjectId}")]
76
public class Comment
87
{
@@ -13,6 +12,12 @@ public class Comment
1312
public required DateTimeOffset CreatedAt { get; set; }
1413
public required int CommentCount { get; set; }
1514
public required IList<Guid> LastCommentsAuthorIds { get; set; }
16-
public required IDictionary<string, int> ReactionCounters { get; set; }
1715
public required IList<string> ViewerReactions { get; set; }
16+
17+
private IDictionary<string, int> _reactionCounters = null!;
18+
public required IDictionary<string, int> ReactionCounters
19+
{
20+
get => _reactionCounters;
21+
set => _reactionCounters = value.Where(kv => kv.Value > 0).ToDictionary();
22+
}
1823
}

src/CrowdParlay.Social.Domain/Entities/Discussion.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
namespace CrowdParlay.Social.Domain.Entities;
44

5-
65
[DebuggerDisplay("{Id} by {AuthorId}")]
76
public class Discussion
87
{
@@ -13,6 +12,12 @@ public class Discussion
1312
public required DateTimeOffset CreatedAt { get; set; }
1413
public required int CommentCount { get; set; }
1514
public required IList<Guid> LastCommentsAuthorIds { get; set; }
16-
public required IDictionary<string, int> ReactionCounters { get; set; }
1715
public required IList<string> ViewerReactions { get; set; }
16+
17+
private IDictionary<string, int> _reactionCounters = null!;
18+
public required IDictionary<string, int> ReactionCounters
19+
{
20+
get => _reactionCounters;
21+
set => _reactionCounters = value.Where(kv => kv.Value > 0).ToDictionary();
22+
}
1823
}

src/CrowdParlay.Social.Infrastructure.Persistence/Services/CommentsRepository.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,8 @@ public async Task<ISet<string>> GetReactionsAsync(string commentId, Guid authorI
160160
public async Task SetReactionsAsync(string commentId, Guid authorId, ISet<string> reactions) =>
161161
await _subjectsRepository.SetReactionsAsync(commentId, authorId, reactions);
162162

163-
public async Task UpdateReactionCountersAsync(string commentId, IEnumerable<string> reactionsToAdd, IEnumerable<string> reactionsToRemove) =>
164-
await _subjectsRepository.UpdateReactionCountersAsync(commentId, reactionsToAdd, reactionsToRemove);
163+
public async Task UpdateReactionCountersAsync(string commentId, IDictionary<string, int> reactionsDiff) =>
164+
await _subjectsRepository.UpdateReactionCountersAsync(commentId, reactionsDiff);
165165

166166
private static Expression<Func<CommentDocument, Comment>> CreateCommentProjectionExpression(Guid? viewerId) => comment => new Comment
167167
{

src/CrowdParlay.Social.Infrastructure.Persistence/Services/DiscussionsRepository.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,8 @@ public async Task<ISet<string>> GetReactionsAsync(string discussionId, Guid auth
105105
public async Task SetReactionsAsync(string discussionId, Guid authorId, ISet<string> reactions) =>
106106
await _subjectsRepository.SetReactionsAsync(discussionId, authorId, reactions);
107107

108-
public async Task UpdateReactionCountersAsync(string subjectId, IEnumerable<string> reactionsToAdd, IEnumerable<string> reactionsToRemove) =>
109-
await _subjectsRepository.UpdateReactionCountersAsync(subjectId, reactionsToAdd, reactionsToRemove);
108+
public async Task UpdateReactionCountersAsync(string subjectId, IDictionary<string, int> reactionsDiff) =>
109+
await _subjectsRepository.UpdateReactionCountersAsync(subjectId, reactionsDiff);
110110

111111
public async Task IncludeCommentInMetadataAsync(string discussionId, Guid authorId) =>
112112
await _subjectsRepository.IncludeCommentInMetadataAsync(discussionId, authorId);

src/CrowdParlay.Social.Infrastructure.Persistence/Services/GenericSubjectsRepository.cs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ public async Task<ISet<string>> GetReactionsAsync(string subjectId, Guid authorI
1616
var pipeline = _subjects
1717
.Find(session, subject => subject.Id == ObjectId.Parse(subjectId))
1818
.Project(subject => subject.ReactionsByAuthorId.ContainsKey(authorId.ToString())
19-
? subject.ReactionsByAuthorId[authorId.ToString()]
20-
: new string[] { });
19+
? subject.ReactionsByAuthorId[authorId.ToString()]
20+
: new string[] { });
2121

2222
var reactions = await pipeline.FirstOrDefaultAsync() ?? throw new NotFoundException();
2323
return reactions.ToHashSet();
@@ -38,16 +38,13 @@ public async Task SetReactionsAsync(string subjectId, Guid authorId, ISet<string
3838
throw new NotFoundException();
3939
}
4040

41-
public async Task UpdateReactionCountersAsync(string subjectId, IEnumerable<string> reactionsToAdd, IEnumerable<string> reactionsToRemove)
41+
public async Task UpdateReactionCountersAsync(string subjectId, IDictionary<string, int> reactionsDiff)
4242
{
43-
var increments = reactionsToAdd.Select(reaction =>
44-
Builders<TDocument>.Update.Inc(subject => subject.ReactionCounters[reaction], 1));
45-
46-
var decrements = reactionsToRemove.Select(reaction =>
47-
Builders<TDocument>.Update.Inc(subject => subject.ReactionCounters[reaction], -1));
43+
var updates = reactionsDiff.Select(kv =>
44+
Builders<TDocument>.Update.Inc(subject => subject.ReactionCounters[kv.Key], kv.Value));
4845

4946
var filter = Builders<TDocument>.Filter.Eq(subject => subject.Id, ObjectId.Parse(subjectId));
50-
var update = Builders<TDocument>.Update.Combine(increments.Union(decrements));
47+
var update = Builders<TDocument>.Update.Combine(updates);
5148
var result = await _subjects.UpdateOneAsync(session, filter, update);
5249

5350
if (result.MatchedCount == 0)
@@ -76,7 +73,7 @@ await _subjects
7673

7774
await _subjects.UpdateOneAsync(session, filter, update);
7875
}
79-
76+
8077
public async Task ExcludeCommentFromMetadataAsync(string subjectId)
8178
{
8279
var filter = Builders<TDocument>.Filter.Eq(subject => subject.Id, ObjectId.Parse(subjectId));

tests/CrowdParlay.Social.IntegrationTests/Tests/ReactionsTests.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,7 @@ public async Task SetReactions_OverwritesExistingReactions()
6666
discussion.ViewerReactions.Should().BeEquivalentTo(woozyFace, redHeart);
6767
discussion.ReactionCounters.Should().BeEquivalentTo(new Dictionary<string, int>
6868
{
69-
{ eggplant, 0 },
7069
{ woozyFace, 1 },
71-
{ nailPolish, 0 },
7270
{ redHeart, 1 }
7371
});
7472
}

0 commit comments

Comments
 (0)