Files
forkmessager/backend/src/Modules/Conversations/Infrastructure/Handlers/ChatCreatedDomainEventHandler.cs
T

93 lines
4.0 KiB
C#

using Knot.Shared.Kernel;
using Knot.Contracts.Conversations.Domain;
using Knot.Modules.Conversations.Infrastructure.SignalR;
using MediatR;
using Microsoft.AspNetCore.SignalR;
namespace Knot.Modules.Conversations.Infrastructure.Handlers;
/// <summary>
/// Обработчик доменного события создания чата.
/// </summary>
public sealed class ChatCreatedDomainEventHandler : INotificationHandler<ChatCreatedDomainEvent>, INotificationHandler<ChatMemberAddedDomainEvent>
{
private readonly IHubContext<ChatHub> _hubContext;
private readonly IChatRepository _chatRepository;
private readonly IUserDisplayNameProvider _displayNameProvider;
public ChatCreatedDomainEventHandler(
IHubContext<ChatHub> hubContext,
IChatRepository chatRepository,
IUserDisplayNameProvider displayNameProvider)
{
_hubContext = hubContext;
_chatRepository = chatRepository;
_displayNameProvider = displayNameProvider;
}
public async Task Handle(ChatCreatedDomainEvent notification, CancellationToken cancellationToken)
{
await NotifyNewChatAsync(notification.Chat, cancellationToken);
}
public async Task Handle(ChatMemberAddedDomainEvent notification, CancellationToken cancellationToken)
{
var chat = await _chatRepository.GetByIdAsync(notification.ChatId, cancellationToken);
if (chat != null)
{
// Уведомляем всех участников, что кто-то добавлен (или пользователь сам видит новый чат)
await NotifyNewChatAsync(chat, cancellationToken);
}
}
private async Task NotifyNewChatAsync(Chat chat, CancellationToken cancellationToken, string? targetUserId = null)
{
var members = new List<object>();
foreach (var member in chat.Members)
{
var userInfo = await _displayNameProvider.GetUserInfoAsync(member.UserId, cancellationToken);
members.Add(new
{
member.Id,
member.UserId,
member.Role,
member.JoinedAt,
User = userInfo != null
? new { userInfo.Id, userInfo.Username, userInfo.DisplayName, userInfo.Avatar, isOnline = false }
: new { Id = member.UserId, Username = "unknown", DisplayName = "Unknown", Avatar = (string?)null, isOnline = false }
});
}
var payload = new
{
id = chat.Id,
type = chat.Type.ToString().ToLowerInvariant(),
name = chat.Type == ChatType.Favorites ? "Избранное" : (chat.Type == ChatType.Personal ? null : chat.Name),
avatar = chat.Avatar,
createdAt = chat.CreatedAt,
members = members,
messages = new List<object>(),
unreadCount = 0
};
if (targetUserId != null)
{
// Отправляем конкретному пользователю (по всем его соединениям)
// Мы можем использовать метод Hub или просто отправить в группу UserId (если она есть)
// В нашем ChatHub мы добавляем пользователя в группы чатов при подключении.
// Но для нового чата он еще не в группе.
// Поэтому отправляем через User ID (SignalR поддерживает Clients.User(id))
await _hubContext.Clients.User(targetUserId).SendAsync("new_chat", payload, cancellationToken);
}
else
{
// Уведомляем всех текущих участников
foreach (var member in chat.Members)
{
await _hubContext.Clients.User(member.UserId.ToString()).SendAsync("new_chat", payload, cancellationToken);
}
}
}
}