SOLID
This commit is contained in:
@@ -8,7 +8,6 @@ using Knot.Shared.Kernel;
|
|||||||
using Knot.Modules.Chats.Application.DTOs;
|
using Knot.Modules.Chats.Application.DTOs;
|
||||||
using Knot.Modules.Chats.Domain;
|
using Knot.Modules.Chats.Domain;
|
||||||
using Knot.Modules.Chats.Application.Abstractions;
|
using Knot.Modules.Chats.Application.Abstractions;
|
||||||
using Knot.Modules.Identity.Domain;
|
|
||||||
|
|
||||||
namespace Knot.Modules.Chats.Application.Chats.GetChatById;
|
namespace Knot.Modules.Chats.Application.Chats.GetChatById;
|
||||||
|
|
||||||
@@ -17,13 +16,13 @@ public record GetChatByIdQuery(Guid ChatId) : IQuery<ChatDto?>;
|
|||||||
internal sealed class GetChatByIdQueryHandler : IQueryHandler<GetChatByIdQuery, ChatDto?>
|
internal sealed class GetChatByIdQueryHandler : IQueryHandler<GetChatByIdQuery, ChatDto?>
|
||||||
{
|
{
|
||||||
private readonly IChatRepository _chatRepository;
|
private readonly IChatRepository _chatRepository;
|
||||||
private readonly IUserRepository _userRepository;
|
private readonly IUserDisplayNameProvider _userProvider;
|
||||||
private readonly IMessageRepository _messageRepository;
|
private readonly IMessageRepository _messageRepository;
|
||||||
|
|
||||||
public GetChatByIdQueryHandler(IChatRepository chatRepository, IUserRepository userRepository, IMessageRepository messageRepository)
|
public GetChatByIdQueryHandler(IChatRepository chatRepository, IUserDisplayNameProvider userProvider, IMessageRepository messageRepository)
|
||||||
{
|
{
|
||||||
_chatRepository = chatRepository;
|
_chatRepository = chatRepository;
|
||||||
_userRepository = userRepository;
|
_userProvider = userProvider;
|
||||||
_messageRepository = messageRepository;
|
_messageRepository = messageRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,10 +31,23 @@ internal sealed class GetChatByIdQueryHandler : IQueryHandler<GetChatByIdQuery,
|
|||||||
var chat = await _chatRepository.GetByIdAsync(request.ChatId, cancellationToken);
|
var chat = await _chatRepository.GetByIdAsync(request.ChatId, cancellationToken);
|
||||||
if (chat == null) return Result.Success<ChatDto?>(null);
|
if (chat == null) return Result.Success<ChatDto?>(null);
|
||||||
|
|
||||||
|
var userIdsToFetch = new HashSet<Guid>();
|
||||||
|
foreach (var m in chat.Members) userIdsToFetch.Add(m.UserId);
|
||||||
|
|
||||||
|
var chatMessages = await _messageRepository.GetChatMessagesAsync(chat.Id, 1, 0, cancellationToken);
|
||||||
|
var mFirst = chatMessages.FirstOrDefault();
|
||||||
|
if (mFirst != null)
|
||||||
|
{
|
||||||
|
userIdsToFetch.Add(mFirst.SenderId);
|
||||||
|
foreach (var r in mFirst.Reactions) userIdsToFetch.Add(r.UserId);
|
||||||
|
}
|
||||||
|
|
||||||
|
var usersInfo = await _userProvider.GetUsersInfoAsync(userIdsToFetch, cancellationToken);
|
||||||
|
|
||||||
var members = new List<ChatMemberDto>();
|
var members = new List<ChatMemberDto>();
|
||||||
foreach (var m in chat.Members)
|
foreach (var m in chat.Members)
|
||||||
{
|
{
|
||||||
var user = await _userRepository.GetByIdAsync(m.UserId, cancellationToken);
|
usersInfo.TryGetValue(m.UserId, out var user);
|
||||||
members.Add(new ChatMemberDto(
|
members.Add(new ChatMemberDto(
|
||||||
m.Id,
|
m.Id,
|
||||||
m.UserId,
|
m.UserId,
|
||||||
@@ -52,17 +64,16 @@ internal sealed class GetChatByIdQueryHandler : IQueryHandler<GetChatByIdQuery,
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
var chatMessages = await _messageRepository.GetChatMessagesAsync(chat.Id, 1, 0, cancellationToken);
|
|
||||||
var messagesList = new List<ChatMessageDto>();
|
var messagesList = new List<ChatMessageDto>();
|
||||||
if (chatMessages.Any())
|
if (chatMessages.Any())
|
||||||
{
|
{
|
||||||
var m = chatMessages.First();
|
var m = mFirst;
|
||||||
var senderObj = await _userRepository.GetByIdAsync(m.SenderId, cancellationToken);
|
usersInfo.TryGetValue(m.SenderId, out var senderObj);
|
||||||
|
|
||||||
var reactionsWithUser = new List<ReactionDto>();
|
var reactionsWithUser = new List<ReactionDto>();
|
||||||
foreach (var r in m.Reactions)
|
foreach (var r in m.Reactions)
|
||||||
{
|
{
|
||||||
var rUser = await _userRepository.GetByIdAsync(r.UserId, cancellationToken);
|
usersInfo.TryGetValue(r.UserId, out var rUser);
|
||||||
reactionsWithUser.Add(new ReactionDto(
|
reactionsWithUser.Add(new ReactionDto(
|
||||||
r.Id,
|
r.Id,
|
||||||
r.Emoji,
|
r.Emoji,
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ using Knot.Shared.Kernel;
|
|||||||
using Knot.Modules.Chats.Application.DTOs;
|
using Knot.Modules.Chats.Application.DTOs;
|
||||||
using Knot.Modules.Chats.Domain;
|
using Knot.Modules.Chats.Domain;
|
||||||
using Knot.Modules.Chats.Application.Abstractions;
|
using Knot.Modules.Chats.Application.Abstractions;
|
||||||
using Knot.Modules.Identity.Domain;
|
|
||||||
|
|
||||||
namespace Knot.Modules.Chats.Application.Chats.GetChats;
|
namespace Knot.Modules.Chats.Application.Chats.GetChats;
|
||||||
|
|
||||||
@@ -17,13 +17,13 @@ public record GetChatsQuery(Guid UserId) : IQuery<List<ChatDto>>;
|
|||||||
internal sealed class GetChatsQueryHandler : IQueryHandler<GetChatsQuery, List<ChatDto>>
|
internal sealed class GetChatsQueryHandler : IQueryHandler<GetChatsQuery, List<ChatDto>>
|
||||||
{
|
{
|
||||||
private readonly IChatRepository _chatRepository;
|
private readonly IChatRepository _chatRepository;
|
||||||
private readonly IUserRepository _userRepository;
|
private readonly IUserDisplayNameProvider _userProvider;
|
||||||
private readonly IMessageRepository _messageRepository;
|
private readonly IMessageRepository _messageRepository;
|
||||||
|
|
||||||
public GetChatsQueryHandler(IChatRepository chatRepository, IUserRepository userRepository, IMessageRepository messageRepository)
|
public GetChatsQueryHandler(IChatRepository chatRepository, IUserDisplayNameProvider userProvider, IMessageRepository messageRepository)
|
||||||
{
|
{
|
||||||
_chatRepository = chatRepository;
|
_chatRepository = chatRepository;
|
||||||
_userRepository = userRepository;
|
_userProvider = userProvider;
|
||||||
_messageRepository = messageRepository;
|
_messageRepository = messageRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,16 +35,23 @@ internal sealed class GetChatsQueryHandler : IQueryHandler<GetChatsQuery, List<C
|
|||||||
|
|
||||||
foreach (var c in userChats)
|
foreach (var c in userChats)
|
||||||
{
|
{
|
||||||
if (c.Type == ChatType.Favorites)
|
var userIdsToFetch = new HashSet<Guid>();
|
||||||
|
foreach (var m in c.Members) userIdsToFetch.Add(m.UserId);
|
||||||
|
|
||||||
|
var chatMessages = await _messageRepository.GetChatMessagesAsync(c.Id, 1, 0, cancellationToken);
|
||||||
|
var mFirst = chatMessages.FirstOrDefault();
|
||||||
|
if (mFirst != null)
|
||||||
{
|
{
|
||||||
if (hasFavorites) continue;
|
userIdsToFetch.Add(mFirst.SenderId);
|
||||||
hasFavorites = true;
|
foreach (var r in mFirst.Reactions) userIdsToFetch.Add(r.UserId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var usersInfo = await _userProvider.GetUsersInfoAsync(userIdsToFetch, cancellationToken);
|
||||||
|
|
||||||
var members = new List<ChatMemberDto>();
|
var members = new List<ChatMemberDto>();
|
||||||
foreach (var m in c.Members)
|
foreach (var m in c.Members)
|
||||||
{
|
{
|
||||||
var user = await _userRepository.GetByIdAsync(m.UserId, cancellationToken);
|
usersInfo.TryGetValue(m.UserId, out var user);
|
||||||
members.Add(new ChatMemberDto(
|
members.Add(new ChatMemberDto(
|
||||||
m.Id,
|
m.Id,
|
||||||
m.UserId,
|
m.UserId,
|
||||||
@@ -61,18 +68,17 @@ internal sealed class GetChatsQueryHandler : IQueryHandler<GetChatsQuery, List<C
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
var chatMessages = await _messageRepository.GetChatMessagesAsync(c.Id, 1, 0, cancellationToken);
|
|
||||||
var messagesList = new List<ChatMessageDto>();
|
var messagesList = new List<ChatMessageDto>();
|
||||||
|
|
||||||
if (chatMessages.Any())
|
if (chatMessages.Any())
|
||||||
{
|
{
|
||||||
var m = chatMessages.First();
|
var m = mFirst;
|
||||||
var senderObj = await _userRepository.GetByIdAsync(m.SenderId, cancellationToken);
|
usersInfo.TryGetValue(m.SenderId, out var senderObj);
|
||||||
|
|
||||||
var reactionsWithUser = new List<ReactionDto>();
|
var reactionsWithUser = new List<ReactionDto>();
|
||||||
foreach (var r in m.Reactions)
|
foreach (var r in m.Reactions)
|
||||||
{
|
{
|
||||||
var rUser = await _userRepository.GetByIdAsync(r.UserId, cancellationToken);
|
usersInfo.TryGetValue(r.UserId, out var rUser);
|
||||||
reactionsWithUser.Add(new ReactionDto(
|
reactionsWithUser.Add(new ReactionDto(
|
||||||
r.Id,
|
r.Id,
|
||||||
r.Emoji,
|
r.Emoji,
|
||||||
|
|||||||
+35
-37
@@ -7,7 +7,6 @@ using MediatR;
|
|||||||
using Knot.Shared.Kernel;
|
using Knot.Shared.Kernel;
|
||||||
using Knot.Modules.Chats.Application.DTOs;
|
using Knot.Modules.Chats.Application.DTOs;
|
||||||
using Knot.Modules.Chats.Domain;
|
using Knot.Modules.Chats.Domain;
|
||||||
using Knot.Modules.Identity.Domain;
|
|
||||||
|
|
||||||
namespace Knot.Modules.Chats.Application.Messages.GetMessages;
|
namespace Knot.Modules.Chats.Application.Messages.GetMessages;
|
||||||
|
|
||||||
@@ -16,12 +15,12 @@ public record GetMessagesQuery(Guid UserId, Guid ChatId, string? Cursor) : IQuer
|
|||||||
internal sealed class GetMessagesQueryHandler : IQueryHandler<GetMessagesQuery, List<MessageDetailDto>>
|
internal sealed class GetMessagesQueryHandler : IQueryHandler<GetMessagesQuery, List<MessageDetailDto>>
|
||||||
{
|
{
|
||||||
private readonly IMessageRepository _messageRepository;
|
private readonly IMessageRepository _messageRepository;
|
||||||
private readonly IUserRepository _userRepository;
|
private readonly IUserDisplayNameProvider _userProvider;
|
||||||
|
|
||||||
public GetMessagesQueryHandler(IMessageRepository messageRepository, IUserRepository userRepository)
|
public GetMessagesQueryHandler(IMessageRepository messageRepository, IUserDisplayNameProvider userProvider)
|
||||||
{
|
{
|
||||||
_messageRepository = messageRepository;
|
_messageRepository = messageRepository;
|
||||||
_userRepository = userRepository;
|
_userProvider = userProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Result<List<MessageDetailDto>>> Handle(GetMessagesQuery request, CancellationToken cancellationToken)
|
public async Task<Result<List<MessageDetailDto>>> Handle(GetMessagesQuery request, CancellationToken cancellationToken)
|
||||||
@@ -33,58 +32,57 @@ internal sealed class GetMessagesQueryHandler : IQueryHandler<GetMessagesQuery,
|
|||||||
}
|
}
|
||||||
|
|
||||||
var messages = await _messageRepository.GetChatMessagesCursorAsync(request.ChatId, cursorDate, 100, cancellationToken);
|
var messages = await _messageRepository.GetChatMessagesCursorAsync(request.ChatId, cursorDate, 100, cancellationToken);
|
||||||
var senders = new Dictionary<Guid, User>();
|
|
||||||
var result = new List<MessageDetailDto>();
|
var result = new List<MessageDetailDto>();
|
||||||
|
|
||||||
|
var userIdsToFetch = new HashSet<Guid>();
|
||||||
|
var replyMessages = new Dictionary<Guid, Message>();
|
||||||
|
|
||||||
foreach (var m in messages)
|
foreach (var m in messages)
|
||||||
{
|
{
|
||||||
if (m.DeletedByUsers.Contains(request.UserId)) continue;
|
if (m.DeletedByUsers.Contains(request.UserId)) continue;
|
||||||
|
|
||||||
if (!senders.ContainsKey(m.SenderId))
|
userIdsToFetch.Add(m.SenderId);
|
||||||
{
|
if (m.ForwardedFromId.HasValue) userIdsToFetch.Add(m.ForwardedFromId.Value);
|
||||||
var user = await _userRepository.GetByIdAsync(m.SenderId, cancellationToken);
|
|
||||||
if (user != null) senders[m.SenderId] = user;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m.ForwardedFromId.HasValue && !senders.ContainsKey(m.ForwardedFromId.Value))
|
foreach (var r in m.Reactions)
|
||||||
{
|
userIdsToFetch.Add(r.UserId);
|
||||||
var fuser = await _userRepository.GetByIdAsync(m.ForwardedFromId.Value, cancellationToken);
|
|
||||||
if (fuser != null) senders[m.ForwardedFromId.Value] = fuser;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReplyToMessageDto? replyToObj = null;
|
|
||||||
if (m.ReplyToId.HasValue)
|
if (m.ReplyToId.HasValue)
|
||||||
{
|
{
|
||||||
var replyMsg = await _messageRepository.GetByIdAsync(m.ReplyToId.Value, cancellationToken);
|
var replyMsg = await _messageRepository.GetByIdAsync(m.ReplyToId.Value, cancellationToken);
|
||||||
if (replyMsg != null)
|
if (replyMsg != null)
|
||||||
{
|
{
|
||||||
if (!senders.ContainsKey(replyMsg.SenderId))
|
replyMessages[replyMsg.Id] = replyMsg;
|
||||||
{
|
userIdsToFetch.Add(replyMsg.SenderId);
|
||||||
var replySender = await _userRepository.GetByIdAsync(replyMsg.SenderId, cancellationToken);
|
|
||||||
if (replySender != null) senders[replyMsg.SenderId] = replySender;
|
|
||||||
}
|
|
||||||
var senderObj = senders.TryGetValue(replyMsg.SenderId, out var rs)
|
|
||||||
? new MessageSenderDto(rs.Id, rs.Username, rs.DisplayName, rs.Avatar)
|
|
||||||
: null;
|
|
||||||
|
|
||||||
replyToObj = new ReplyToMessageDto(
|
|
||||||
replyMsg.Id,
|
|
||||||
replyMsg.Content,
|
|
||||||
replyMsg.IsDeleted,
|
|
||||||
replyMsg.Media.Select(rm => new MediaDto(rm.Id, rm.Type, rm.Url, rm.Filename, rm.Size)).ToList(),
|
|
||||||
senderObj
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var senders = await _userProvider.GetUsersInfoAsync(userIdsToFetch, cancellationToken);
|
||||||
|
|
||||||
|
foreach (var m in messages)
|
||||||
|
{
|
||||||
|
if (m.DeletedByUsers.Contains(request.UserId)) continue;
|
||||||
|
|
||||||
|
ReplyToMessageDto? replyToObj = null;
|
||||||
|
if (m.ReplyToId.HasValue && replyMessages.TryGetValue(m.ReplyToId.Value, out var replyMsg))
|
||||||
|
{
|
||||||
|
var senderObj = senders.TryGetValue(replyMsg.SenderId, out var rs)
|
||||||
|
? new MessageSenderDto(rs.Id, rs.Username, rs.DisplayName, rs.Avatar)
|
||||||
|
: null;
|
||||||
|
|
||||||
|
replyToObj = new ReplyToMessageDto(
|
||||||
|
replyMsg.Id,
|
||||||
|
replyMsg.Content,
|
||||||
|
replyMsg.IsDeleted,
|
||||||
|
replyMsg.Media.Select(rm => new MediaDto(rm.Id, rm.Type, rm.Url, rm.Filename, rm.Size)).ToList(),
|
||||||
|
senderObj
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
var reactionsWithUser = new List<MessageReactionDto>();
|
var reactionsWithUser = new List<MessageReactionDto>();
|
||||||
foreach (var r in m.Reactions)
|
foreach (var r in m.Reactions)
|
||||||
{
|
{
|
||||||
if (!senders.ContainsKey(r.UserId))
|
|
||||||
{
|
|
||||||
var rUser = await _userRepository.GetByIdAsync(r.UserId, cancellationToken);
|
|
||||||
if (rUser != null) senders[r.UserId] = rUser;
|
|
||||||
}
|
|
||||||
var userObj = senders.TryGetValue(r.UserId, out var ru)
|
var userObj = senders.TryGetValue(r.UserId, out var ru)
|
||||||
? new MessageSenderDto(ru.Id, ru.Username, ru.DisplayName, ru.Avatar)
|
? new MessageSenderDto(ru.Id, ru.Username, ru.DisplayName, ru.Avatar)
|
||||||
: new MessageSenderDto(r.UserId, "unknown", "Unknown", null);
|
: new MessageSenderDto(r.UserId, "unknown", "Unknown", null);
|
||||||
|
|||||||
+8
-6
@@ -8,7 +8,6 @@ using MediatR;
|
|||||||
using Knot.Shared.Kernel;
|
using Knot.Shared.Kernel;
|
||||||
using Knot.Modules.Chats.Application.DTOs;
|
using Knot.Modules.Chats.Application.DTOs;
|
||||||
using Knot.Modules.Chats.Domain;
|
using Knot.Modules.Chats.Domain;
|
||||||
using Knot.Modules.Identity.Domain;
|
|
||||||
|
|
||||||
namespace Knot.Modules.Chats.Application.Messages.GetSharedMedia;
|
namespace Knot.Modules.Chats.Application.Messages.GetSharedMedia;
|
||||||
|
|
||||||
@@ -17,12 +16,12 @@ public record GetSharedMediaQuery(Guid UserId, Guid ChatId, string? Type) : IQue
|
|||||||
internal sealed class GetSharedMediaQueryHandler : IQueryHandler<GetSharedMediaQuery, List<SharedMediaDto>>
|
internal sealed class GetSharedMediaQueryHandler : IQueryHandler<GetSharedMediaQuery, List<SharedMediaDto>>
|
||||||
{
|
{
|
||||||
private readonly IMessageRepository _messageRepository;
|
private readonly IMessageRepository _messageRepository;
|
||||||
private readonly IUserRepository _userRepository;
|
private readonly IUserDisplayNameProvider _userProvider;
|
||||||
|
|
||||||
public GetSharedMediaQueryHandler(IMessageRepository messageRepository, IUserRepository userRepository)
|
public GetSharedMediaQueryHandler(IMessageRepository messageRepository, IUserDisplayNameProvider userProvider)
|
||||||
{
|
{
|
||||||
_messageRepository = messageRepository;
|
_messageRepository = messageRepository;
|
||||||
_userRepository = userRepository;
|
_userProvider = userProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Result<List<SharedMediaDto>>> Handle(GetSharedMediaQuery request, CancellationToken cancellationToken)
|
public async Task<Result<List<SharedMediaDto>>> Handle(GetSharedMediaQuery request, CancellationToken cancellationToken)
|
||||||
@@ -33,6 +32,9 @@ internal sealed class GetSharedMediaQueryHandler : IQueryHandler<GetSharedMediaQ
|
|||||||
var result = new List<SharedMediaDto>();
|
var result = new List<SharedMediaDto>();
|
||||||
var filterType = request.Type?.ToLower();
|
var filterType = request.Type?.ToLower();
|
||||||
|
|
||||||
|
var userIds = messages.Select(m => m.SenderId).Distinct();
|
||||||
|
var senders = await _userProvider.GetUsersInfoAsync(userIds, cancellationToken);
|
||||||
|
|
||||||
foreach (var m in messages)
|
foreach (var m in messages)
|
||||||
{
|
{
|
||||||
if (filterType == "links")
|
if (filterType == "links")
|
||||||
@@ -44,7 +46,7 @@ internal sealed class GetSharedMediaQueryHandler : IQueryHandler<GetSharedMediaQ
|
|||||||
|
|
||||||
if (allLinks.Any())
|
if (allLinks.Any())
|
||||||
{
|
{
|
||||||
var sender = await _userRepository.GetByIdAsync(m.SenderId, cancellationToken);
|
senders.TryGetValue(m.SenderId, out var sender);
|
||||||
result.Add(new SharedMediaDto(
|
result.Add(new SharedMediaDto(
|
||||||
m.Id,
|
m.Id,
|
||||||
m.Content,
|
m.Content,
|
||||||
@@ -71,7 +73,7 @@ internal sealed class GetSharedMediaQueryHandler : IQueryHandler<GetSharedMediaQ
|
|||||||
|
|
||||||
if (filteredMedia.Any())
|
if (filteredMedia.Any())
|
||||||
{
|
{
|
||||||
var sender = await _userRepository.GetByIdAsync(m.SenderId, cancellationToken);
|
senders.TryGetValue(m.SenderId, out var sender);
|
||||||
result.Add(new SharedMediaDto(
|
result.Add(new SharedMediaDto(
|
||||||
m.Id,
|
m.Id,
|
||||||
m.Content,
|
m.Content,
|
||||||
|
|||||||
+4
-10
@@ -7,7 +7,6 @@ using MediatR;
|
|||||||
using Knot.Shared.Kernel;
|
using Knot.Shared.Kernel;
|
||||||
using Knot.Modules.Chats.Application.DTOs;
|
using Knot.Modules.Chats.Application.DTOs;
|
||||||
using Knot.Modules.Chats.Domain;
|
using Knot.Modules.Chats.Domain;
|
||||||
using Knot.Modules.Identity.Domain;
|
|
||||||
|
|
||||||
namespace Knot.Modules.Chats.Application.Messages.SearchMessages;
|
namespace Knot.Modules.Chats.Application.Messages.SearchMessages;
|
||||||
|
|
||||||
@@ -16,12 +15,12 @@ public record SearchMessagesQuery(Guid UserId, string Query, Guid? ChatId) : IQu
|
|||||||
internal sealed class SearchMessagesQueryHandler : IQueryHandler<SearchMessagesQuery, List<SearchMessageDto>>
|
internal sealed class SearchMessagesQueryHandler : IQueryHandler<SearchMessagesQuery, List<SearchMessageDto>>
|
||||||
{
|
{
|
||||||
private readonly IMessageRepository _messageRepository;
|
private readonly IMessageRepository _messageRepository;
|
||||||
private readonly IUserRepository _userRepository;
|
private readonly IUserDisplayNameProvider _userProvider;
|
||||||
|
|
||||||
public SearchMessagesQueryHandler(IMessageRepository messageRepository, IUserRepository userRepository)
|
public SearchMessagesQueryHandler(IMessageRepository messageRepository, IUserDisplayNameProvider userProvider)
|
||||||
{
|
{
|
||||||
_messageRepository = messageRepository;
|
_messageRepository = messageRepository;
|
||||||
_userRepository = userRepository;
|
_userProvider = userProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Result<List<SearchMessageDto>>> Handle(SearchMessagesQuery request, CancellationToken cancellationToken)
|
public async Task<Result<List<SearchMessageDto>>> Handle(SearchMessagesQuery request, CancellationToken cancellationToken)
|
||||||
@@ -32,12 +31,7 @@ internal sealed class SearchMessagesQueryHandler : IQueryHandler<SearchMessagesQ
|
|||||||
var userIds = messages.Select(m => m.SenderId).ToList();
|
var userIds = messages.Select(m => m.SenderId).ToList();
|
||||||
userIds.AddRange(messages.Where(m => m.ForwardedFromId.HasValue).Select(m => m.ForwardedFromId!.Value));
|
userIds.AddRange(messages.Where(m => m.ForwardedFromId.HasValue).Select(m => m.ForwardedFromId!.Value));
|
||||||
|
|
||||||
var senders = new Dictionary<Guid, User>();
|
var senders = await _userProvider.GetUsersInfoAsync(userIds.Distinct(), cancellationToken);
|
||||||
foreach (var id in userIds.Distinct())
|
|
||||||
{
|
|
||||||
var user = await _userRepository.GetByIdAsync(id, cancellationToken);
|
|
||||||
if (user != null) senders[id] = user;
|
|
||||||
}
|
|
||||||
|
|
||||||
var result = messages.Select(m => new SearchMessageDto(
|
var result = messages.Select(m => new SearchMessageDto(
|
||||||
m.Id,
|
m.Id,
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\Shared\Knot.Shared.Kernel\Knot.Shared.Kernel.csproj" />
|
<ProjectReference Include="..\..\Shared\Knot.Shared.Kernel\Knot.Shared.Kernel.csproj" />
|
||||||
<ProjectReference Include="..\Identity\Knot.Modules.Identity.csproj" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ namespace Knot.Modules.Identity.Domain;
|
|||||||
public interface IUserRepository
|
public interface IUserRepository
|
||||||
{
|
{
|
||||||
Task<User?> GetByIdAsync(Guid id, CancellationToken cancellationToken = default);
|
Task<User?> GetByIdAsync(Guid id, CancellationToken cancellationToken = default);
|
||||||
|
Task<List<User>> GetByIdsAsync(IEnumerable<Guid> ids, CancellationToken cancellationToken = default);
|
||||||
Task<User?> GetByUsernameAsync(string username, CancellationToken cancellationToken = default);
|
Task<User?> GetByUsernameAsync(string username, CancellationToken cancellationToken = default);
|
||||||
Task<bool> IsUsernameUniqueAsync(string username, CancellationToken cancellationToken = default);
|
Task<bool> IsUsernameUniqueAsync(string username, CancellationToken cancellationToken = default);
|
||||||
Task<List<User>> SearchUsersAsync(string query, CancellationToken cancellationToken = default);
|
Task<List<User>> SearchUsersAsync(string query, CancellationToken cancellationToken = default);
|
||||||
|
|||||||
@@ -20,6 +20,11 @@ public sealed class UserRepository : IUserRepository
|
|||||||
return await _context.Users.FirstOrDefaultAsync(u => u.Id == id, cancellationToken);
|
return await _context.Users.FirstOrDefaultAsync(u => u.Id == id, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<List<User>> GetByIdsAsync(IEnumerable<Guid> ids, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
return await _context.Users.Where(u => ids.Contains(u.Id)).ToListAsync(cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<User?> GetByUsernameAsync(string username, CancellationToken cancellationToken = default)
|
public async Task<User?> GetByUsernameAsync(string username, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
return await _context.Users.FirstOrDefaultAsync(u => u.Username == username, cancellationToken);
|
return await _context.Users.FirstOrDefaultAsync(u => u.Username == username, cancellationToken);
|
||||||
|
|||||||
+11
@@ -24,4 +24,15 @@ public sealed class UserDisplayNameProvider : IUserDisplayNameProvider
|
|||||||
if (user == null) return null;
|
if (user == null) return null;
|
||||||
return new UserInfo(user.Id, user.Username, user.DisplayName, user.Avatar);
|
return new UserInfo(user.Id, user.Username, user.DisplayName, user.Avatar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<IReadOnlyDictionary<Guid, UserInfo>> GetUsersInfoAsync(IEnumerable<Guid> userIds, CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
var users = await _userRepository.GetByIdsAsync(userIds, ct);
|
||||||
|
var result = new System.Collections.Generic.Dictionary<Guid, UserInfo>();
|
||||||
|
foreach (var user in users)
|
||||||
|
{
|
||||||
|
result[user.Id] = new UserInfo(user.Id, user.Username, user.DisplayName, user.Avatar);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,4 +6,5 @@ public interface IUserDisplayNameProvider
|
|||||||
{
|
{
|
||||||
Task<string> GetDisplayNameAsync(Guid userId, CancellationToken ct = default);
|
Task<string> GetDisplayNameAsync(Guid userId, CancellationToken ct = default);
|
||||||
Task<UserInfo?> GetUserInfoAsync(Guid userId, CancellationToken ct = default);
|
Task<UserInfo?> GetUserInfoAsync(Guid userId, CancellationToken ct = default);
|
||||||
|
Task<IReadOnlyDictionary<Guid, UserInfo>> GetUsersInfoAsync(IEnumerable<Guid> userIds, CancellationToken ct = default);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user