mirror of
https://github.com/Govor-team/Govor.git
synced 2026-09-17 16:22:49 +00:00
3ec61fa2c0
was added removing messages many fixes bugs and moving to result pattern from throwing exceptions
110 lines
3.5 KiB
C#
110 lines
3.5 KiB
C#
using Govor.Application.Interfaces;
|
|
using Govor.Domain.Models.Messages;
|
|
using Govor.Domain;
|
|
using Govor.Domain.Common;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using SmartRes;
|
|
|
|
namespace Govor.Application.Messages;
|
|
|
|
public class MessagesLoader : IMessagesLoader
|
|
{
|
|
private readonly GovorDbContext _dbContext;
|
|
|
|
public MessagesLoader(GovorDbContext dbContext)
|
|
{
|
|
_dbContext = dbContext;
|
|
}
|
|
|
|
public async Task<Result<List<Message>,Error>> LoadMessagesInUserChat(
|
|
Guid privateChatId,
|
|
Guid currentUser,
|
|
Guid? startMessageId,
|
|
int before = 20,
|
|
int after = 2)
|
|
{
|
|
if (privateChatId == Guid.Empty)
|
|
return Result.Failure<List<Message>>(Error.Failure(nameof(ArgumentException),"PrivateChatId id cannot be empty."));
|
|
|
|
var chatExists = await _dbContext.PrivateChats.AnyAsync(c => c.Id == privateChatId);
|
|
if (!chatExists)
|
|
return new List<Message>(0);
|
|
|
|
var query = _dbContext.Messages
|
|
.AsNoTracking()
|
|
.Include(m => m.MediaAttachments)
|
|
.ThenInclude(m => m.MediaFile)
|
|
.Where(m => m.RecipientType == RecipientType.User && m.RecipientId == privateChatId);
|
|
|
|
return await FetchPaginatedMessagesAsync(query, startMessageId, before, after);
|
|
}
|
|
|
|
public async Task<Result<List<Message>,Error>> LoadMessagesInChatGroup(
|
|
Guid chatId,
|
|
Guid currentUser,
|
|
Guid? startMessageId,
|
|
int before = 20,
|
|
int after = 2)
|
|
{
|
|
if (chatId == Guid.Empty)
|
|
return Result.Failure<List<Message>>(Error.Failure(nameof(ArgumentException),"Chat id cannot be empty."));
|
|
|
|
var isMember = await _dbContext.GroupMemberships
|
|
.AnyAsync(gm => gm.UserId == currentUser && gm.GroupId == chatId);
|
|
|
|
if (!isMember)
|
|
return new List<Message>(0);
|
|
|
|
var query = _dbContext.Messages
|
|
.AsNoTracking()
|
|
.Include(m => m.MediaAttachments)
|
|
.ThenInclude(m => m.MediaFile)
|
|
.AsSplitQuery()
|
|
.Where(m => m.RecipientType == RecipientType.Group && m.RecipientId == chatId);
|
|
|
|
return await FetchPaginatedMessagesAsync(query, startMessageId, before, after);
|
|
}
|
|
|
|
private static async Task<List<Message>> FetchPaginatedMessagesAsync(
|
|
IQueryable<Message> baseQuery,
|
|
Guid? startMessageId,
|
|
int before,
|
|
int after)
|
|
{
|
|
if (startMessageId is null)
|
|
{
|
|
return await baseQuery
|
|
.OrderByDescending(m => m.SentAt)
|
|
.Take(before)
|
|
.OrderBy(m => m.SentAt)
|
|
.ToListAsync();
|
|
}
|
|
|
|
var startMessage = await baseQuery.FirstOrDefaultAsync(m => m.Id == startMessageId.Value);
|
|
if (startMessage == null)
|
|
return [];
|
|
|
|
var beforeMessages = await baseQuery
|
|
.Where(m => m.SentAt < startMessage.SentAt)
|
|
.OrderByDescending(m => m.SentAt)
|
|
.Take(before)
|
|
.ToListAsync();
|
|
|
|
var afterMessages = await baseQuery
|
|
.Where(m => m.SentAt > startMessage.SentAt)
|
|
.OrderBy(m => m.SentAt)
|
|
.Take(after)
|
|
.ToListAsync();
|
|
|
|
|
|
beforeMessages.Reverse();
|
|
|
|
var result = new List<Message>(beforeMessages.Count + 1 + afterMessages.Count);
|
|
result.AddRange(beforeMessages);
|
|
result.Add(startMessage);
|
|
result.AddRange(afterMessages);
|
|
|
|
return result;
|
|
}
|
|
}
|