Files
QMAX/server/QMax.Api/Services/ChatProjectionService.cs
2026-07-03 22:39:48 +03:00

76 lines
2.2 KiB
C#

using QMax.Api.Contracts;
using QMax.Api.Data.Entities;
namespace QMax.Api.Services;
public sealed class ChatProjectionService
{
public ChatDto ToDto(Chat chat)
{
return new ChatDto(
chat.Id,
chat.ExternalId,
chat.Kind,
chat.Title,
AvatarPath(chat),
CleanPreview(chat.LastMessagePreview),
chat.LastMessageAt,
chat.UnreadCount,
chat.IsPinned,
chat.IsMuted,
chat.IsArchived);
}
public MessageDto ToDto(Message message)
{
return new MessageDto(
message.Id,
message.ChatId,
message.ExternalId,
message.SenderName,
message.Direction,
MessageTextSanitizer.CleanMessageText(message.Text, message.Attachments.Count != 0),
message.SentAt,
message.EditedAt,
message.DeletedAt,
message.ReplyToMessageId,
message.ForwardedFrom,
message.DeliveryState,
message.Error,
message.Reactions
.GroupBy(x => x.Emoji)
.OrderByDescending(x => x.Count())
.ThenBy(x => x.Key, StringComparer.Ordinal)
.Select(x => new ReactionDto(x.Key, x.Count(), x.Any(r => r.ActorKey == "self")))
.ToArray(),
message.Attachments
.OrderBy(x => x.SortOrder)
.Select(x => ToDto(message.ChatId, x))
.ToArray());
}
private static AttachmentDto ToDto(Guid chatId, MessageAttachment attachment)
{
return new AttachmentDto(
attachment.Id,
attachment.OriginalFileName,
attachment.ContentType,
attachment.FileSizeBytes,
$"/api/chats/{chatId}/attachments/{attachment.Id}/content",
attachment.Kind,
attachment.SortOrder);
}
private static string? CleanPreview(string? value)
{
return MessageTextSanitizer.CleanChatPreview(value);
}
private static string? AvatarPath(Chat chat)
{
return string.IsNullOrWhiteSpace(chat.AvatarUrl)
? null
: $"/api/chats/{chat.Id}/avatar";
}
}