Структура, доп модули, федерация, документация

This commit is contained in:
Халимов Рустам
2026-03-27 00:55:01 +03:00
parent 7cb6ac61dd
commit 7ef73b414c
64 changed files with 3080 additions and 133 deletions

View File

@@ -2,6 +2,7 @@ using Knot.Modules.Messaging.Application.Abstractions;
using Knot.Modules.Messaging.Domain;
using Knot.Modules.Conversations.Domain;
using Knot.Shared.Kernel;
using Knot.Shared.Kernel.Configuration;
using Knot.Modules.Conversations.Application.Abstractions;
namespace Knot.Modules.Conversations.Application.Messages.Send;
@@ -22,7 +23,11 @@ public sealed record SendMessageCommand(
Guid? ForwardedFromId = null,
Guid? StoryId = null,
string? StoryMediaUrl = null,
string? StoryMediaType = null) : ICommand<Guid>;
string? StoryMediaType = null,
List<string>? PollOptions = null,
bool? PollIsAnonymous = null,
bool? PollAllowMultipleAnswers = null,
DateTime? PollExpiresAt = null) : ICommand<Guid>;
public sealed class SendMessageCommandHandler : ICommandHandler<SendMessageCommand, Guid>
{
@@ -30,17 +35,20 @@ public sealed class SendMessageCommandHandler : ICommandHandler<SendMessageComma
private readonly IMessageRepository _messageRepository;
private readonly IChatsUnitOfWork _unitOfWork;
private readonly MediatR.IMediator _mediator;
private readonly IMessagesSettings _messagesSettings;
public SendMessageCommandHandler(
IChatRepository chatRepository,
IMessageRepository messageRepository,
IChatsUnitOfWork unitOfWork,
MediatR.IMediator mediator)
MediatR.IMediator mediator,
IMessagesSettings messagesSettings)
{
_chatRepository = chatRepository;
_messageRepository = messageRepository;
_unitOfWork = unitOfWork;
_mediator = mediator;
_messagesSettings = messagesSettings;
}
public async Task<Result<Guid>> Handle(SendMessageCommand request, CancellationToken cancellationToken)
@@ -62,6 +70,8 @@ public sealed class SendMessageCommandHandler : ICommandHandler<SendMessageComma
Message message;
if (request.Type == "story_reply" || request.Type == "story_reaction")
{
if (!_messagesSettings.Current.AllowMedia) return Result.Failure<Guid>(ChatErrors.MediaDisabled);
var parsedStoryMediaType = Enum.TryParse<MediaType>(request.StoryMediaType, true, out var sTypeEnum) ? sTypeEnum : MediaType.Image;
message = new StoryMessage(
Guid.NewGuid(),
@@ -78,6 +88,8 @@ public sealed class SendMessageCommandHandler : ICommandHandler<SendMessageComma
}
else if (request.Attachments != null && request.Attachments.Any())
{
if (!_messagesSettings.Current.AllowMedia) return Result.Failure<Guid>(ChatErrors.MediaDisabled);
var firstAtt = request.Attachments.First();
var parsedType = Enum.TryParse<MediaType>(firstAtt.Type, true, out var mTypeEnum) ? mTypeEnum : MediaType.File;
@@ -98,6 +110,24 @@ public sealed class SendMessageCommandHandler : ICommandHandler<SendMessageComma
((MediaMessage)message).AddMedia(pType, att.Url, att.FileName, att.FileSize);
}
}
else if (request.Type == "poll")
{
if (!_messagesSettings.Current.AllowPolls) return Result.Failure<Guid>(ChatErrors.PollsDisabled);
message = new PollMessage(
Guid.NewGuid(),
request.ChatId,
request.SenderId,
request.Content ?? "Poll",
request.PollOptions ?? new List<string>(),
request.PollIsAnonymous ?? true,
request.PollAllowMultipleAnswers ?? false,
request.PollExpiresAt,
request.ReplyToId,
request.ForwardedFromId,
DateTime.UtcNow,
false);
}
else
{
message = new TextMessage(