✨ Post reactions and replies counting
🎨 Improve the styles of post service
This commit is contained in:
parent
abc89dc782
commit
27276c66c5
@ -24,8 +24,7 @@ public class ActivityService(AppDatabase db, PublisherService pub, RelationshipS
|
|||||||
.FilterWithVisibility(null, [], [], isListing: true)
|
.FilterWithVisibility(null, [], [], isListing: true)
|
||||||
.Take(take)
|
.Take(take)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
posts = PostService.TruncatePostContent(posts);
|
posts = await ps.LoadPostInfo(posts, null, true);
|
||||||
posts = await ps.LoadPublishers(posts);
|
|
||||||
|
|
||||||
var postsId = posts.Select(e => e.Id).ToList();
|
var postsId = posts.Select(e => e.Id).ToList();
|
||||||
var reactionMaps = await ps.GetPostReactionMapBatch(postsId);
|
var reactionMaps = await ps.GetPostReactionMapBatch(postsId);
|
||||||
@ -63,8 +62,7 @@ public class ActivityService(AppDatabase db, PublisherService pub, RelationshipS
|
|||||||
.FilterWithVisibility(currentUser, userFriends, userPublishers, isListing: true)
|
.FilterWithVisibility(currentUser, userFriends, userPublishers, isListing: true)
|
||||||
.Take(take)
|
.Take(take)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
posts = PostService.TruncatePostContent(posts);
|
posts = await ps.LoadPostInfo(posts, currentUser, true);
|
||||||
posts = await ps.LoadPublishers(posts);
|
|
||||||
|
|
||||||
var postsId = posts.Select(e => e.Id).ToList();
|
var postsId = posts.Select(e => e.Id).ToList();
|
||||||
var reactionMaps = await ps.GetPostReactionMapBatch(postsId);
|
var reactionMaps = await ps.GetPostReactionMapBatch(postsId);
|
||||||
|
@ -44,6 +44,7 @@ public class Post : ModelBase, IIdentifiedResource, IActivity
|
|||||||
public int Upvotes { get; set; }
|
public int Upvotes { get; set; }
|
||||||
public int Downvotes { get; set; }
|
public int Downvotes { get; set; }
|
||||||
[NotMapped] public Dictionary<string, int> ReactionsCount { get; set; } = new();
|
[NotMapped] public Dictionary<string, int> ReactionsCount { get; set; } = new();
|
||||||
|
[NotMapped] public int RepliesCount { get; set; }
|
||||||
|
|
||||||
public Guid? RepliedPostId { get; set; }
|
public Guid? RepliedPostId { get; set; }
|
||||||
public Post? RepliedPost { get; set; }
|
public Post? RepliedPost { get; set; }
|
||||||
|
@ -52,26 +52,7 @@ public class PostController(
|
|||||||
.Skip(offset)
|
.Skip(offset)
|
||||||
.Take(take)
|
.Take(take)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
posts = PostService.TruncatePostContent(posts);
|
posts = await ps.LoadPostInfo(posts, currentUser, true);
|
||||||
posts = await ps.LoadPublishers(posts);
|
|
||||||
|
|
||||||
var postsId = posts.Select(e => e.Id).ToList();
|
|
||||||
var reactionMaps = await ps.GetPostReactionMapBatch(postsId);
|
|
||||||
foreach (var post in posts)
|
|
||||||
{
|
|
||||||
post.ReactionsCount =
|
|
||||||
reactionMaps.TryGetValue(post.Id, out var count) ? count : new Dictionary<string, int>();
|
|
||||||
|
|
||||||
// Track view for each post in the list
|
|
||||||
if (currentUser != null)
|
|
||||||
{
|
|
||||||
await ps.IncreaseViewCount(post.Id, currentUser.Id.ToString());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
await ps.IncreaseViewCount(post.Id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Response.Headers["X-Total"] = totalCount.ToString();
|
Response.Headers["X-Total"] = totalCount.ToString();
|
||||||
|
|
||||||
@ -94,8 +75,7 @@ public class PostController(
|
|||||||
.FilterWithVisibility(currentUser, userFriends, userPublishers)
|
.FilterWithVisibility(currentUser, userFriends, userPublishers)
|
||||||
.FirstOrDefaultAsync();
|
.FirstOrDefaultAsync();
|
||||||
if (post is null) return NotFound();
|
if (post is null) return NotFound();
|
||||||
|
post = await ps.LoadPostInfo(post, currentUser);
|
||||||
post.ReactionsCount = await ps.GetPostReactionMap(post.Id);
|
|
||||||
|
|
||||||
// Track view - use the account ID as viewer ID if user is logged in
|
// Track view - use the account ID as viewer ID if user is logged in
|
||||||
await ps.IncreaseViewCount(post.Id, currentUser?.Id.ToString());
|
await ps.IncreaseViewCount(post.Id, currentUser?.Id.ToString());
|
||||||
@ -131,8 +111,7 @@ public class PostController(
|
|||||||
.Skip(offset)
|
.Skip(offset)
|
||||||
.Take(take)
|
.Take(take)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
posts = PostService.TruncatePostContent(posts);
|
posts = await ps.LoadPostInfo(posts, currentUser, true);
|
||||||
posts = await ps.LoadPublishers(posts);
|
|
||||||
|
|
||||||
var postsId = posts.Select(e => e.Id).ToList();
|
var postsId = posts.Select(e => e.Id).ToList();
|
||||||
var reactionMaps = await ps.GetPostReactionMapBatch(postsId);
|
var reactionMaps = await ps.GetPostReactionMapBatch(postsId);
|
||||||
|
@ -435,6 +435,68 @@ public class PostService(
|
|||||||
|
|
||||||
return posts;
|
return posts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<List<Post>> LoadInteractive(List<Post> posts, Account.Account? currentUser = null)
|
||||||
|
{
|
||||||
|
if (posts.Count == 0) return posts;
|
||||||
|
|
||||||
|
var postsId = posts.Select(e => e.Id).ToList();
|
||||||
|
|
||||||
|
var reactionMaps = await GetPostReactionMapBatch(postsId);
|
||||||
|
var repliesCountMap = await GetPostRepliesCountBatch(postsId);
|
||||||
|
|
||||||
|
foreach (var post in posts)
|
||||||
|
{
|
||||||
|
// Set reactions count
|
||||||
|
post.ReactionsCount = reactionMaps.TryGetValue(post.Id, out var count)
|
||||||
|
? count
|
||||||
|
: new Dictionary<string, int>();
|
||||||
|
|
||||||
|
// Set replies count
|
||||||
|
post.RepliesCount = repliesCountMap.TryGetValue(post.Id, out var repliesCount)
|
||||||
|
? repliesCount
|
||||||
|
: 0;
|
||||||
|
|
||||||
|
// Track view for each post in the list
|
||||||
|
if (currentUser != null)
|
||||||
|
await IncreaseViewCount(post.Id, currentUser.Id.ToString());
|
||||||
|
else
|
||||||
|
await IncreaseViewCount(post.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return posts;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<Dictionary<Guid, int>> GetPostRepliesCountBatch(List<Guid> postIds)
|
||||||
|
{
|
||||||
|
return await db.Posts
|
||||||
|
.Where(p => p.RepliedPostId != null && postIds.Contains(p.RepliedPostId.Value))
|
||||||
|
.GroupBy(p => p.RepliedPostId!.Value)
|
||||||
|
.ToDictionaryAsync(
|
||||||
|
g => g.Key,
|
||||||
|
g => g.Count()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<List<Post>> LoadPostInfo(List<Post> posts, Account.Account? currentUser = null, bool truncate = false)
|
||||||
|
{
|
||||||
|
if (posts.Count == 0) return posts;
|
||||||
|
|
||||||
|
posts = await LoadPublishers(posts);
|
||||||
|
posts = await LoadInteractive(posts, currentUser);
|
||||||
|
|
||||||
|
if (truncate)
|
||||||
|
posts = TruncatePostContent(posts);
|
||||||
|
|
||||||
|
return posts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Post> LoadPostInfo(Post post, Account.Account? currentUser = null, bool truncate = false)
|
||||||
|
{
|
||||||
|
// Convert single post to list, process it, then return the single post
|
||||||
|
var posts = await LoadPostInfo([post], currentUser, truncate);
|
||||||
|
return posts.First();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class PostQueryExtensions
|
public static class PostQueryExtensions
|
||||||
|
Loading…
x
Reference in New Issue
Block a user