mirror of
https://github.com/Govor-team/Govor.git
synced 2026-07-21 11:44:56 +00:00
142 lines
4.5 KiB
C#
142 lines
4.5 KiB
C#
using Govor.Application.Interfaces;
|
|
using Govor.Core.Models.Messages;
|
|
using Govor.Core.Repositories.Groups;
|
|
using Govor.Core.Repositories.PrivateChats;
|
|
using Govor.Data;
|
|
using Govor.Data.Repositories.Exceptions;
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
namespace Govor.Application.Services.Messages;
|
|
|
|
public class MessagesLoader : IMessagesLoader
|
|
{
|
|
private IGroupsRepository _groupsRepository;
|
|
private IPrivateChatsRepository _privateChatsRepository;
|
|
private GovorDbContext _dbContext;
|
|
|
|
public MessagesLoader(
|
|
IGroupsRepository groupsRepository,
|
|
IPrivateChatsRepository privateChatsRepository,
|
|
GovorDbContext dbContext)
|
|
{
|
|
_groupsRepository = groupsRepository;
|
|
_privateChatsRepository = privateChatsRepository;
|
|
_dbContext = dbContext;
|
|
}
|
|
|
|
public async Task<List<Message>> LoadMessagesInUserChat(
|
|
Guid privateChatId,
|
|
Guid currentUser,
|
|
Guid? startMessageId,
|
|
int before = 20,
|
|
int after = 2)
|
|
{
|
|
if (privateChatId == Guid.Empty)
|
|
throw new ArgumentException("PrivateChatId id cannot be empty");
|
|
|
|
if (!_privateChatsRepository.Exist(privateChatId))
|
|
throw new InvalidOperationException("Private chat not found");
|
|
|
|
var query = _dbContext.Messages
|
|
.AsNoTracking()
|
|
.Include(m => m.MediaAttachments)
|
|
.ThenInclude(m => m.MediaFile)
|
|
.Where(m => m.RecipientType == RecipientType.User &&
|
|
m.RecipientId == privateChatId);
|
|
|
|
if (startMessageId is null)
|
|
{
|
|
return await query
|
|
.OrderByDescending(m => m.SentAt)
|
|
.Take(before)
|
|
.ToListAsync();
|
|
}
|
|
|
|
var startMessage = await _dbContext.Messages.FindAsync(startMessageId.Value);
|
|
if (startMessage == null)
|
|
throw new NotFoundException("Start message not found");
|
|
|
|
var beforeMessages = await query
|
|
.Where(m => m.SentAt < startMessage.SentAt)
|
|
.OrderByDescending(m => m.SentAt)
|
|
.Take(before)
|
|
.ToListAsync();
|
|
|
|
var afterMessages = await query
|
|
.Where(m => m.SentAt > startMessage.SentAt)
|
|
.OrderBy(m => m.SentAt)
|
|
.Take(after)
|
|
.ToListAsync();
|
|
|
|
// older -> start -> newer
|
|
var result = beforeMessages
|
|
.OrderBy(m => m.SentAt)
|
|
.Concat(new[] { startMessage })
|
|
.Concat(afterMessages)
|
|
.ToList();
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
public async Task<List<Message>> LoadMessagesInChatGroup(
|
|
Guid chatId,
|
|
Guid currentUser,
|
|
Guid? startMessageId,
|
|
int before = 20,
|
|
int after = 2)
|
|
{
|
|
if (chatId == Guid.Empty)
|
|
throw new ArgumentException("Chat id cannot be empty");
|
|
|
|
var isMember = await _groupsRepository.IsUserMemberOfGroupAsync(currentUser, chatId);
|
|
if (!isMember)
|
|
throw new UnauthorizedAccessException("You are not a member of this group.");
|
|
|
|
var baseQuery = _dbContext.Messages
|
|
.AsNoTracking()
|
|
.Include(m => m.MediaAttachments)
|
|
.ThenInclude(m => m.MediaFile)
|
|
.AsSplitQuery()
|
|
.Where(m => m.RecipientType == RecipientType.Group && m.RecipientId == chatId);
|
|
|
|
if (startMessageId is null)
|
|
{
|
|
return await baseQuery
|
|
.OrderByDescending(m => m.SentAt)
|
|
.Take(before)
|
|
.OrderBy(m => m.SentAt)
|
|
.ToListAsync();
|
|
}
|
|
|
|
var startMessage = await _dbContext.Messages
|
|
.AsNoTracking()
|
|
.FirstOrDefaultAsync(m => m.Id == startMessageId.Value &&
|
|
m.RecipientType == RecipientType.Group &&
|
|
m.RecipientId == chatId);
|
|
|
|
if (startMessage == null)
|
|
throw new NotFoundException("Start message not found in this group.");
|
|
|
|
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();
|
|
|
|
var result = beforeMessages
|
|
.OrderBy(m => m.SentAt)
|
|
.Concat(new[] { startMessage })
|
|
.Concat(afterMessages)
|
|
.ToList();
|
|
|
|
return result;
|
|
}
|
|
|
|
} |