using MediatR; using Microsoft.AspNetCore.SignalR; using global::Knot.Modules.Chats.Domain; using global::Knot.Modules.Chats.Infrastructure.SignalR; using global::Knot.Shared.Kernel; using global::Knot.Modules.Chats.Application.Abstractions; namespace Knot.Modules.Chats.Application.Messages.Delete; public sealed record DeleteMessagesCommand( Guid ChatId, Guid UserId, List MessageIds, bool DeleteForAll) : ICommand; public sealed class DeleteMessagesCommandHandler : ICommandHandler { private readonly IMessageRepository _messageRepository; private readonly IChatsUnitOfWork _unitOfWork; private readonly IHubContext _hubContext; public DeleteMessagesCommandHandler( IMessageRepository messageRepository, IChatsUnitOfWork unitOfWork, IHubContext hubContext) { _messageRepository = messageRepository; _unitOfWork = unitOfWork; _hubContext = hubContext; } public async Task Handle(DeleteMessagesCommand request, CancellationToken cancellationToken) { foreach (var id in request.MessageIds) { var message = await _messageRepository.GetByIdAsync(id, cancellationToken); if (message is null || message.ChatId != request.ChatId) { continue; } if (request.DeleteForAll) { if (message.SenderId == request.UserId) { message.Delete(); } } else { message.DeleteForUser(request.UserId); } await _messageRepository.UpdateAsync(message, cancellationToken); } if (request.DeleteForAll) { await _hubContext.Clients.Group(request.ChatId.ToString()).SendAsync("messages_deleted", new { chatId = request.ChatId, messageIds = request.MessageIds, deleteForAll = true }); } else { // Уведомляем только самого пользователя (все его текущие сессии) await _hubContext.Clients.User(request.UserId.ToString()).SendAsync("messages_deleted", new { chatId = request.ChatId, messageIds = request.MessageIds, deleteForAll = false }); } return global::Knot.Shared.Kernel.Result.Success(); } }