From fab3d6b67bc24a8841930baec233709eec5c3fde Mon Sep 17 00:00:00 2001 From: Artemy <109195690+stalcker2288969@users.noreply.github.com> Date: Fri, 4 Jul 2025 12:43:12 +0700 Subject: [PATCH] ChatGroup work --- Govor.API/Hubs/ChatsHub.cs | 52 +++++++++++++------ Govor.Application/Interfaces/IGroupService.cs | 3 +- .../Interfaces/Messages/Parameters/Result.cs | 2 +- .../Services/PrivateChatService.cs | 5 +- .../Requests/SignalR/GroupMessageRequest.cs | 9 ++++ .../Requests/SignalR/MessageRequest.cs | 1 - .../Responses/SignalR/UserMessageResponse.cs | 12 +++++ Govor.Data/Repositories/MessagesRepository.cs | 2 +- 8 files changed, 65 insertions(+), 21 deletions(-) create mode 100644 Govor.Contracts/Requests/SignalR/GroupMessageRequest.cs create mode 100644 Govor.Contracts/Responses/SignalR/UserMessageResponse.cs diff --git a/Govor.API/Hubs/ChatsHub.cs b/Govor.API/Hubs/ChatsHub.cs index 5c37ba9..b61dba0 100644 --- a/Govor.API/Hubs/ChatsHub.cs +++ b/Govor.API/Hubs/ChatsHub.cs @@ -2,6 +2,7 @@ using Govor.API.Services; using Govor.Application.Interfaces.Messages; using Govor.Application.Interfaces.Messages.Parameters; using Govor.Contracts.Requests.SignalR; +using Govor.Contracts.Responses.SignalR; using Govor.Core.Models; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.SignalR; @@ -26,12 +27,14 @@ public class ChatsHub : Hub public override async Task OnConnectedAsync() { var userId = GetUserId(); + if (userId != Guid.Empty) { // Binding ConnectionId to UserId await Groups.AddToGroupAsync(Context.ConnectionId, userId.ToString()); _logger.LogInformation("User {UserId} connected with ConnectionId {ConnectionId}", userId, Context.ConnectionId); } + await base.OnConnectedAsync(); } @@ -56,6 +59,33 @@ public class ChatsHub : Hub } + public async Task SendGroup(GroupMessageRequest request) + { + var senderId = GetUserId(); + + // Создание сообщения + var message = new SendMessage( + EncryptContent: request.EncryptedContent, + ReplyToMessageId: request.ReplyToMessageId, + FromUserId: senderId, + RecipientId: request.GroupId, + SendAt: DateTime.UtcNow, + Media: request.MediaAttachments?.Select(f => new SendMedia( + f.MediaId, f.EncryptedKey, f.Type, f.MimeType)) ?? Array.Empty()); + + var result = await _groupService.SendMessageAsync(message); + + if (!result.IsSuccess) + throw result.Exception!; + + // Шлём всем участникам группы, кроме отправителя + await Clients.GroupExcept($"group_{request.GroupId}", Context.ConnectionId) + .SendAsync("ReceiveGroupMessage", message); + + // Отправителю тоже + await Clients.Caller.SendAsync("ReceiveGroupMessage", message); + } + public async Task Send(MessageRequest request) { if (string.IsNullOrWhiteSpace(request.EncryptedContent)) @@ -79,10 +109,13 @@ public class ChatsHub : Hub Media: request.MediaAttachments?.Select(f => new SendMedia( f.MediaId, f.EncryptedKey, f.Type, f.MimeType)) ?? Array.Empty()); - if (request.RecipientType == RecipientType.User) - { - await SendUser(message); - } + Result result = await _chatService.SendMessageAsync(message); + if(result.IsSuccess == false) + throw result.Exception; + + // Sending a message to the sender and recipient + await Clients.Group(message.RecipientId.ToString()).SendAsync("Receive", message); + await Clients.Group(message.FromUserId.ToString()).SendAsync("Receive", message); // TODO: Send to Group } catch (Exception ex) @@ -92,17 +125,6 @@ public class ChatsHub : Hub } } - private async Task SendUser(SendMessage sendMessage) - { - Result result = await _chatService.SendMessageAsync(sendMessage); - if(result.IsSuccess == false) - throw result.Exception; - - // Sending a message to the sender and recipient - await Clients.Group(sendMessage.RecipientId.ToString()).SendAsync("Receive", sendMessage); - await Clients.Group(sendMessage.FromUserId.ToString()).SendAsync("Receive", sendMessage); - } - private Guid GetUserId() { var userIdClaim = Context.User?.FindFirst("userID")?.Value; diff --git a/Govor.Application/Interfaces/IGroupService.cs b/Govor.Application/Interfaces/IGroupService.cs index 955dc32..91ed51e 100644 --- a/Govor.Application/Interfaces/IGroupService.cs +++ b/Govor.Application/Interfaces/IGroupService.cs @@ -1,8 +1,9 @@ +using Govor.Application.Interfaces.Messages; using Govor.Core.Models; namespace Govor.API.Services; -public interface IGroupService +public interface IGroupService : IMessageSendingService, IMessageManagementService { ChatGroup GetGroupByInvite(string code); } \ No newline at end of file diff --git a/Govor.Application/Interfaces/Messages/Parameters/Result.cs b/Govor.Application/Interfaces/Messages/Parameters/Result.cs index c07618e..7151e86 100644 --- a/Govor.Application/Interfaces/Messages/Parameters/Result.cs +++ b/Govor.Application/Interfaces/Messages/Parameters/Result.cs @@ -1,3 +1,3 @@ namespace Govor.Application.Interfaces.Messages.Parameters; -public record Result(bool IsSuccess, Exception Exception); \ No newline at end of file +public record Result(bool IsSuccess, Exception Exception, Guid messageId); \ No newline at end of file diff --git a/Govor.Application/Services/PrivateChatService.cs b/Govor.Application/Services/PrivateChatService.cs index f18dad5..786ad27 100644 --- a/Govor.Application/Services/PrivateChatService.cs +++ b/Govor.Application/Services/PrivateChatService.cs @@ -48,11 +48,12 @@ public class PrivateChatService : IChatService }; await _messages.AddAsync(message); - return new Result(true, null); + + return new Result(true, null, messageId); } catch (Exception ex) { - return new Result(false, ex); + return new Result(false, ex, Guid.Empty); } } diff --git a/Govor.Contracts/Requests/SignalR/GroupMessageRequest.cs b/Govor.Contracts/Requests/SignalR/GroupMessageRequest.cs new file mode 100644 index 0000000..a972541 --- /dev/null +++ b/Govor.Contracts/Requests/SignalR/GroupMessageRequest.cs @@ -0,0 +1,9 @@ +namespace Govor.Contracts.Requests.SignalR; + +public record GroupMessageRequest() +{ + public Guid GroupId { get; init; } + public string EncryptedContent { get; init; } = string.Empty; + public Guid? ReplyToMessageId { get; set; } + public List MediaAttachments { get; set; } = new(); +} \ No newline at end of file diff --git a/Govor.Contracts/Requests/SignalR/MessageRequest.cs b/Govor.Contracts/Requests/SignalR/MessageRequest.cs index ec1417f..09295d3 100644 --- a/Govor.Contracts/Requests/SignalR/MessageRequest.cs +++ b/Govor.Contracts/Requests/SignalR/MessageRequest.cs @@ -5,7 +5,6 @@ namespace Govor.Contracts.Requests.SignalR; public record MessageRequest { public Guid RecipientId { get; init; } - public RecipientType RecipientType { get; set; } public string EncryptedContent { get; init; } = string.Empty; public Guid? ReplyToMessageId { get; set; } public List MediaAttachments { get; set; } = new(); diff --git a/Govor.Contracts/Responses/SignalR/UserMessageResponse.cs b/Govor.Contracts/Responses/SignalR/UserMessageResponse.cs new file mode 100644 index 0000000..fa98fc0 --- /dev/null +++ b/Govor.Contracts/Responses/SignalR/UserMessageResponse.cs @@ -0,0 +1,12 @@ +using Govor.Contracts.Requests.SignalR; + +namespace Govor.Contracts.Responses.SignalR; + +public record UserMessageResponse +{ + public Guid Id { get; init; } + public Guid SenderId { get; init; } + public string EncryptedContent { get; init; } = string.Empty; + public Guid? ReplyToMessageId { get; set; } + public List MediaReferences { get; init; } = new List(); +} \ No newline at end of file diff --git a/Govor.Data/Repositories/MessagesRepository.cs b/Govor.Data/Repositories/MessagesRepository.cs index bad8ce2..2ef4755 100644 --- a/Govor.Data/Repositories/MessagesRepository.cs +++ b/Govor.Data/Repositories/MessagesRepository.cs @@ -118,7 +118,7 @@ public class MessagesRepository : IMessagesRepository .SetProperty(m => m.ReplyToMessageId, message.ReplyToMessageId) .SetProperty(m => m.MessageViews, message.MessageViews) .SetProperty(m => m.MediaAttachments, message.MediaAttachments) - + ); if (rowsAffected == 0)