From 19174de8738bf4aa4a961533ea51430ecea41317 Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Fri, 23 May 2025 00:04:31 +0800 Subject: [PATCH] :sparkle: Chat room summary api --- DysonNetwork.Sphere/Chat/ChatController.cs | 30 ++++++++++++++++++++++ DysonNetwork.Sphere/Chat/ChatService.cs | 25 +++++++++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/DysonNetwork.Sphere/Chat/ChatController.cs b/DysonNetwork.Sphere/Chat/ChatController.cs index ee4949e..d411962 100644 --- a/DysonNetwork.Sphere/Chat/ChatController.cs +++ b/DysonNetwork.Sphere/Chat/ChatController.cs @@ -24,6 +24,36 @@ public partial class ChatController(AppDatabase db, ChatService cs) : Controller public Guid ChatRoomId { get; set; } } + public class ChatSummaryResponse + { + public int UnreadCount { get; set; } + public Message? LastMessage { get; set; } + } + + [HttpGet("summary")] + [Authorize] + public async Task>> GetChatSummary() + { + if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser) return Unauthorized(); + + var unreadMessages = await cs.CountUnreadMessageForUser(currentUser.Id); + var lastMessages = await cs.ListLastMessageForUser(currentUser.Id); + + var result = unreadMessages.Keys + .Union(lastMessages.Keys) + .ToDictionary( + roomId => roomId, + roomId => new ChatSummaryResponse + { + UnreadCount = unreadMessages.GetValueOrDefault(roomId), + LastMessage = lastMessages.GetValueOrDefault(roomId) + } + ); + + return Ok(result); + + } + public class SendMessageRequest { [MaxLength(4096)] public string? Content { get; set; } diff --git a/DysonNetwork.Sphere/Chat/ChatService.cs b/DysonNetwork.Sphere/Chat/ChatService.cs index 0e597b1..9108446 100644 --- a/DysonNetwork.Sphere/Chat/ChatService.cs +++ b/DysonNetwork.Sphere/Chat/ChatService.cs @@ -107,7 +107,7 @@ public class ChatService(AppDatabase db, FileService fs, IServiceScopeFactory sc return messages.Count(m => !m.IsRead); } - public async Task> CountUnreadMessagesForJoinedRoomsAsync(Guid userId) + public async Task> CountUnreadMessageForUser(Guid userId) { var cutoff = SystemClock.Instance.GetCurrentInstant().Minus(Duration.FromDays(30)); var userRooms = await db.ChatMembers @@ -133,6 +133,29 @@ public class ChatService(AppDatabase db, FileService fs, IServiceScopeFactory sc ); } + public async Task> ListLastMessageForUser(Guid userId) + { + var userRooms = await db.ChatMembers + .Where(m => m.AccountId == userId) + .Select(m => m.ChatRoomId) + .ToListAsync(); + + var messages = await db.ChatMessages + .IgnoreQueryFilters() + .Include(m => m.Sender) + .Include(m => m.Sender.Account) + .Include(m => m.Sender.Account.Profile) + .Where(m => userRooms.Contains(m.ChatRoomId)) + .GroupBy(m => m.ChatRoomId) + .Select(g => g.OrderByDescending(m => m.CreatedAt).FirstOrDefault()) + .ToDictionaryAsync( + m => m!.ChatRoomId, + m => m + ); + + return messages; + } + public async Task CreateCallAsync(ChatRoom room, ChatMember sender) { var call = new RealtimeCall