From d268625f19a301e121d1c7c2e3744bb0599ec547 Mon Sep 17 00:00:00 2001 From: Jonathan Bourdon Date: Fri, 19 Jul 2024 00:44:03 -0400 Subject: [PATCH] Adds Messaging streaming --- src/Web/Features/Contents/Data/Content.cs | 2 +- .../{GetContents.cs => GetContent.cs} | 8 ++-- .../Contents/Handlers/GetContentsByUser.cs | 12 ++--- src/Web/Features/Messages/Data/Message.cs | 2 +- .../{PostMessage.cs => AddMessage.cs} | 8 ++-- .../{PostReplyMessage.cs => AddReply.cs} | 8 ++-- .../Features/Messages/Handlers/GetMessages.cs | 18 ++++++-- .../Messages/Handlers/GetMessagesByParent.cs | 34 -------------- .../Features/Messages/Handlers/GetReplies.cs | 46 +++++++++++++++++++ 9 files changed, 80 insertions(+), 58 deletions(-) rename src/Web/Features/Contents/Handlers/{GetContents.cs => GetContent.cs} (85%) rename src/Web/Features/Messages/Handlers/{PostMessage.cs => AddMessage.cs} (86%) rename src/Web/Features/Messages/Handlers/{PostReplyMessage.cs => AddReply.cs} (84%) delete mode 100644 src/Web/Features/Messages/Handlers/GetMessagesByParent.cs create mode 100644 src/Web/Features/Messages/Handlers/GetReplies.cs diff --git a/src/Web/Features/Contents/Data/Content.cs b/src/Web/Features/Contents/Data/Content.cs index c4bdea1..c5c3dec 100644 --- a/src/Web/Features/Contents/Data/Content.cs +++ b/src/Web/Features/Contents/Data/Content.cs @@ -4,7 +4,7 @@ public class Content { public Guid Id { get; init; } public Guid CreatedBy { get; init; } - public DateTimeOffset CreatedAt { get; } + public DateTimeOffset CreatedAt { get; init; } public string? Title { get; init; } public string? Description { get; init; } diff --git a/src/Web/Features/Contents/Handlers/GetContents.cs b/src/Web/Features/Contents/Handlers/GetContent.cs similarity index 85% rename from src/Web/Features/Contents/Handlers/GetContents.cs rename to src/Web/Features/Contents/Handlers/GetContent.cs index 6fe1674..95dd16a 100644 --- a/src/Web/Features/Contents/Handlers/GetContents.cs +++ b/src/Web/Features/Contents/Handlers/GetContent.cs @@ -4,14 +4,14 @@ using Microsoft.EntityFrameworkCore; namespace Hutopy.Web.Features.Contents.Handlers; -public sealed class GetContentsRequest +public sealed class GetContentRequest { public Guid ContentId { get; set; } } -public class GetContents( +public class GetContent( ContentDbContext context) - : Endpoint + : Endpoint { public override void Configure() { @@ -21,7 +21,7 @@ public class GetContents( } public override async Task HandleAsync( - GetContentsRequest req, + GetContentRequest req, CancellationToken ct) { var content = await context diff --git a/src/Web/Features/Contents/Handlers/GetContentsByUser.cs b/src/Web/Features/Contents/Handlers/GetContentsByUser.cs index 34c085f..f17214e 100644 --- a/src/Web/Features/Contents/Handlers/GetContentsByUser.cs +++ b/src/Web/Features/Contents/Handlers/GetContentsByUser.cs @@ -7,7 +7,7 @@ namespace Hutopy.Web.Features.Contents.Handlers; public sealed class GetContentsByUserRequest { public Guid UserId { get; set; } - [BindFrom("max_items")] public int MaxItems { get; set; } = 10; + [BindFrom("page_size")] public int PageSize { get; set; } = 10; [BindFrom("last_id")] public Guid? LastId { get; set; } } @@ -30,12 +30,12 @@ public class GetContentsByUser( .Contents .Where(c => c.CreatedBy == req.UserId); - if (req.LastId is not null) - query = query.OrderByDescending(c => c.Id).Where(c => c.Id < req.LastId.Value); - else - query = query.OrderByDescending(c => c.Id); + query = query.OrderByDescending(c => c.CreatedAt); - query = query.Take(req.MaxItems); + if (req.LastId is not null) + query = query.Where(c => c.Id < req.LastId.Value); + + query = query.Take(req.PageSize); var posts = await query.ToListAsync(cancellationToken: ct); diff --git a/src/Web/Features/Messages/Data/Message.cs b/src/Web/Features/Messages/Data/Message.cs index 8bcd258..9368718 100644 --- a/src/Web/Features/Messages/Data/Message.cs +++ b/src/Web/Features/Messages/Data/Message.cs @@ -5,7 +5,7 @@ public class Message public Guid Id { get; init; } public Guid SubjectId { get; init; } public Guid CreatedBy { get; init; } - public DateTimeOffset CreatedAt { get; } + public DateTimeOffset CreatedAt { get; init; } public Guid? ParentId { get; init; } public string Value { get; init; } } diff --git a/src/Web/Features/Messages/Handlers/PostMessage.cs b/src/Web/Features/Messages/Handlers/AddMessage.cs similarity index 86% rename from src/Web/Features/Messages/Handlers/PostMessage.cs rename to src/Web/Features/Messages/Handlers/AddMessage.cs index 401f0c7..222b781 100644 --- a/src/Web/Features/Messages/Handlers/PostMessage.cs +++ b/src/Web/Features/Messages/Handlers/AddMessage.cs @@ -4,15 +4,15 @@ using Hutopy.Web.Features.Messages.Data; namespace Hutopy.Web.Features.Messages.Handlers; -public class PostMessageRequest +public class AddMessageRequest { public Guid SubjectId { get; set; } public string Message { get; set; } } -public class PostMessage( +public class AddMessage( MessagingDbContext context) - : Endpoint + : Endpoint { public override void Configure() { @@ -21,7 +21,7 @@ public class PostMessage( } public override async Task HandleAsync( - PostMessageRequest req, + AddMessageRequest req, CancellationToken ct) { var message = new Message diff --git a/src/Web/Features/Messages/Handlers/PostReplyMessage.cs b/src/Web/Features/Messages/Handlers/AddReply.cs similarity index 84% rename from src/Web/Features/Messages/Handlers/PostReplyMessage.cs rename to src/Web/Features/Messages/Handlers/AddReply.cs index 9b3d905..1ab824d 100644 --- a/src/Web/Features/Messages/Handlers/PostReplyMessage.cs +++ b/src/Web/Features/Messages/Handlers/AddReply.cs @@ -4,16 +4,16 @@ using Hutopy.Web.Features.Messages.Data; namespace Hutopy.Web.Features.Messages.Handlers; -internal sealed class PostReplyMessageRequest +internal sealed class AddReplyRequest { public required Guid SubjectId { get; set; } public required Guid ParentId { get; set; } public required string Message { get; set; } } -internal sealed class PostReplyMessage( +internal sealed class AddReply( MessagingDbContext context) - : Endpoint + : Endpoint { public override void Configure() { @@ -22,7 +22,7 @@ internal sealed class PostReplyMessage( } public override async Task HandleAsync( - PostReplyMessageRequest req, + AddReplyRequest req, CancellationToken ct) { var message = new Message diff --git a/src/Web/Features/Messages/Handlers/GetMessages.cs b/src/Web/Features/Messages/Handlers/GetMessages.cs index c14c11f..188dd7e 100644 --- a/src/Web/Features/Messages/Handlers/GetMessages.cs +++ b/src/Web/Features/Messages/Handlers/GetMessages.cs @@ -7,6 +7,8 @@ namespace Hutopy.Web.Features.Messages.Handlers; public class GetMessagesRequest { public Guid SubjectId { get; set; } + [BindFrom("page_size")] public int PageSize { get; set; } = 10; + [BindFrom("last_id")] public Guid? LastId { get; set; } } public class GetMessages( @@ -24,12 +26,20 @@ public class GetMessages( GetMessagesRequest req, CancellationToken ct) { - var comments = await context + var query = context .Messages .Where(c => c.SubjectId == req.SubjectId) - .Where(c => c.ParentId == null) - .ToListAsync(cancellationToken: ct); + .Where(c => c.ParentId == null); - await SendAsync(comments, cancellation: ct); + query = query.OrderByDescending(c => c.CreatedAt); + + if (req.LastId is not null) + query = query.Where(c => c.Id < req.LastId.Value); + + query = query.Take(req.PageSize); + + var messages = await query.ToListAsync(cancellationToken: ct); + + await SendAsync(messages, cancellation: ct); } } diff --git a/src/Web/Features/Messages/Handlers/GetMessagesByParent.cs b/src/Web/Features/Messages/Handlers/GetMessagesByParent.cs deleted file mode 100644 index ab05d51..0000000 --- a/src/Web/Features/Messages/Handlers/GetMessagesByParent.cs +++ /dev/null @@ -1,34 +0,0 @@ -using FastEndpoints; -using Hutopy.Web.Features.Messages.Data; -using Microsoft.EntityFrameworkCore; - -namespace Hutopy.Web.Features.Messages.Handlers; - -public class GetMessagesRepliesRequest -{ - public Guid ParentId { get; set; } -} - -public class GetMessagesByParent( - MessagingDbContext context) - : Endpoint> -{ - public override void Configure() - { - Get("/api/messages/{ParentId:guid}/replies"); - Options(o => o.WithTags("Messages")); - AllowAnonymous(); - } - - public override async Task HandleAsync( - GetMessagesRepliesRequest req, - CancellationToken ct) - { - var posts = await context - .Messages - .Where(c => c.ParentId == req.ParentId) - .ToListAsync(cancellationToken: ct); - - await SendAsync(posts, cancellation: ct); - } -} diff --git a/src/Web/Features/Messages/Handlers/GetReplies.cs b/src/Web/Features/Messages/Handlers/GetReplies.cs new file mode 100644 index 0000000..891dbb3 --- /dev/null +++ b/src/Web/Features/Messages/Handlers/GetReplies.cs @@ -0,0 +1,46 @@ +using FastEndpoints; +using Hutopy.Web.Features.Messages.Data; +using Microsoft.EntityFrameworkCore; + +namespace Hutopy.Web.Features.Messages.Handlers; + +public class GetRepliesRequest +{ + public Guid SubjectId { get; set; } + public Guid ParentId { get; set; } + [BindFrom("page_size")] public int PageSize { get; set; } = 10; + [BindFrom("last_id")] public Guid? LastId { get; set; } +} + +public class GetReplies( + MessagingDbContext context) + : Endpoint> +{ + public override void Configure() + { + Get("/api/messages/{ParentId:guid}/replies"); + Options(o => o.WithTags("Messages")); + AllowAnonymous(); + } + + public override async Task HandleAsync( + GetRepliesRequest req, + CancellationToken ct) + { + var query = context + .Messages + .Where(c => c.SubjectId == req.SubjectId) + .Where(c => c.ParentId == req.ParentId); + + query = query.OrderByDescending(c => c.CreatedAt); + + if (req.LastId is not null) + query = query.Where(c => c.Id < req.LastId.Value); + + query = query.Take(req.PageSize); + + var replies = await query.ToListAsync(cancellationToken: ct); + + await SendAsync(replies, cancellation: ct); + } +}