Files
forkmessager/backend/src/Modules/Chats/Application/Messages/SearchMessages/SearchMessagesQuery.cs
Халимов Рустам 5da1a2f45d Архитектура
2026-03-21 02:19:38 +03:00

69 lines
3.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MediatR;
using Knot.Shared.Kernel;
using Knot.Modules.Chats.Application.DTOs;
using Knot.Modules.Chats.Domain;
namespace Knot.Modules.Chats.Application.Messages.SearchMessages;
public record SearchMessagesQuery(Guid UserId, string Query, Guid? ChatId) : IQuery<List<SearchMessageDto>>;
internal sealed class SearchMessagesQueryHandler : IQueryHandler<SearchMessagesQuery, List<SearchMessageDto>>
{
private readonly IMessageRepository _messageRepository;
private readonly IUserDisplayNameProvider _userProvider;
private readonly IMessageReactionRepository _reactionRepository;
public SearchMessagesQueryHandler(IMessageRepository messageRepository, IUserDisplayNameProvider userProvider, IMessageReactionRepository reactionRepository)
{
_messageRepository = messageRepository;
_userProvider = userProvider;
_reactionRepository = reactionRepository;
}
public async Task<Result<List<SearchMessageDto>>> Handle(SearchMessagesQuery request, CancellationToken cancellationToken)
{
var messages = await _messageRepository.SearchMessagesAsync(request.Query, request.ChatId, request.UserId, cancellationToken);
messages = messages.Where(message => !message.IsDeletedForUser(request.UserId)).ToList();
var userIds = messages.Select(message => message.SenderId).ToList();
userIds.AddRange(messages.Where(message => message.ForwardedFromId.HasValue).Select(message => message.ForwardedFromId!.Value));
var senders = await _userProvider.GetUsersInfoAsync(userIds.Distinct(), cancellationToken);
var messageIds = messages.Select(m => m.Id).ToList();
var allReactions = await _reactionRepository.GetReactionsForMessagesAsync(messageIds, cancellationToken);
var reactionsByMessage = allReactions.GroupBy(r => r.MessageId).ToDictionary(g => g.Key, g => g.ToList());
var result = messages.Select(message => new SearchMessageDto(
message.Id,
message.ChatId,
message.SenderId,
message.Content,
message.Type,
message.ReplyToId,
message.Quote,
message.IsEdited,
message.IsDeleted,
message.CreatedAt,
message.SequenceId,
message.ForwardedFromId,
null,
message.StoryId,
message.StoryMediaUrl,
message.StoryMediaType,
message.Media.Select(media => new MediaDto(media.Id, media.Type, media.Url, media.Filename, media.Size)).ToList(),
senders.TryGetValue(message.SenderId, out var senderUser) ? new MessageSenderDto(senderUser.Id, senderUser.Username, senderUser.DisplayName, senderUser.Avatar) : new MessageSenderDto(message.SenderId, "unknown", "Unknown", null),
reactionsByMessage.TryGetValue(message.Id, out var mr) ? mr.Select(reaction => new SimpleReactionDto(reaction.UserId, reaction.Emoji)).ToList() : new List<SimpleReactionDto>(),
new List<ReadByDto>()
)).ToList();
return Result.Success(result);
}
}