Sped up and reduce storage usage of read receipt

This commit is contained in:
2025-05-18 12:14:23 +08:00
parent fdfdffa382
commit 205ccd66b3
8 changed files with 95 additions and 39 deletions

View File

@ -61,7 +61,7 @@ public class ChatService(AppDatabase db, IServiceScopeFactory scopeFactory)
public async Task MarkMessageAsReadAsync(Guid messageId, Guid roomId, Guid userId)
{
var existingStatus = await db.ChatStatuses
var existingStatus = await db.ChatReadReceipts
.FirstOrDefaultAsync(x => x.MessageId == messageId && x.Sender.AccountId == userId);
var sender = await db.ChatMembers
.Where(m => m.AccountId == userId && m.ChatRoomId == roomId)
@ -70,12 +70,12 @@ public class ChatService(AppDatabase db, IServiceScopeFactory scopeFactory)
if (existingStatus == null)
{
existingStatus = new MessageStatus
existingStatus = new MessageReadReceipt
{
MessageId = messageId,
SenderId = sender.Id,
};
db.ChatStatuses.Add(existingStatus);
db.ChatReadReceipts.Add(existingStatus);
}
await db.SaveChangesAsync();
@ -83,14 +83,16 @@ public class ChatService(AppDatabase db, IServiceScopeFactory scopeFactory)
public async Task<bool> GetMessageReadStatus(Guid messageId, Guid userId)
{
return await db.ChatStatuses
return await db.ChatReadReceipts
.AnyAsync(x => x.MessageId == messageId && x.Sender.AccountId == userId);
}
public async Task<int> CountUnreadMessage(Guid userId, Guid chatRoomId)
{
var cutoff = SystemClock.Instance.GetCurrentInstant().Minus(Duration.FromDays(30));
var messages = await db.ChatMessages
.Where(m => m.ChatRoomId == chatRoomId)
.Where(m => m.CreatedAt < cutoff)
.Select(m => new MessageStatusResponse
{
MessageId = m.Id,
@ -103,12 +105,14 @@ public class ChatService(AppDatabase db, IServiceScopeFactory scopeFactory)
public async Task<Dictionary<Guid, int>> CountUnreadMessagesForJoinedRoomsAsync(Guid userId)
{
var cutoff = SystemClock.Instance.GetCurrentInstant().Minus(Duration.FromDays(30));
var userRooms = await db.ChatMembers
.Where(m => m.AccountId == userId)
.Select(m => m.ChatRoomId)
.ToListAsync();
var messages = await db.ChatMessages
.Where(m => m.CreatedAt < cutoff)
.Where(m => userRooms.Contains(m.ChatRoomId))
.Select(m => new
{

View File

@ -19,7 +19,7 @@ public class Message : ModelBase
public ICollection<CloudFile> Attachments { get; set; } = new List<CloudFile>();
public ICollection<MessageReaction> Reactions { get; set; } = new List<MessageReaction>();
public ICollection<MessageStatus> Statuses { get; set; } = new List<MessageStatus>();
public ICollection<MessageReadReceipt> Statuses { get; set; } = new List<MessageReadReceipt>();
public Guid? RepliedMessageId { get; set; }
public Message? RepliedMessage { get; set; }
@ -43,7 +43,7 @@ public class Message : ModelBase
EditedAt = EditedAt,
Attachments = new List<CloudFile>(Attachments),
Reactions = new List<MessageReaction>(Reactions),
Statuses = new List<MessageStatus>(Statuses),
Statuses = new List<MessageReadReceipt>(Statuses),
RepliedMessageId = RepliedMessageId,
RepliedMessage = RepliedMessage?.Clone() as Message,
ForwardedMessageId = ForwardedMessageId,
@ -78,16 +78,14 @@ public class MessageReaction : ModelBase
public MessageReactionAttitude Attitude { get; set; }
}
/// If the status is exist, means the user has read the message.
/// If the status exists, means the user has read the message.
[Index(nameof(MessageId), nameof(SenderId), IsUnique = true)]
public class MessageStatus : ModelBase
public class MessageReadReceipt : ModelBase
{
public Guid MessageId { get; set; }
public Message Message { get; set; } = null!;
public Guid SenderId { get; set; }
public ChatMember Sender { get; set; } = null!;
public Instant ReadAt { get; set; }
}
[NotMapped]