Рабочий чат
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Knot.Modules.Relations.Domain;
|
||||
using Knot.Shared.Kernel;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Knot.Modules.Relations.Application.Abstractions;
|
||||
|
||||
namespace Knot.Modules.Relations.Application.Contacts;
|
||||
|
||||
public record ContactUserDto(Guid Id, string Username, string DisplayName, string Avatar);
|
||||
public record ContactRequestDto(Guid Id, ContactUserDto User, DateTime CreatedAt, bool IsOutgoing);
|
||||
|
||||
public record GetContactRequestsQuery(Guid UserId) : IQuery<List<ContactRequestDto>>;
|
||||
|
||||
internal sealed class GetContactRequestsQueryHandler : IQueryHandler<GetContactRequestsQuery, List<ContactRequestDto>>
|
||||
{
|
||||
private readonly IContactsDbContext _context;
|
||||
|
||||
public GetContactRequestsQueryHandler(IContactsDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
public async Task<Result<List<ContactRequestDto>>> Handle(GetContactRequestsQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
// 1. Fetch ALL pending requests where current user is either sender or receiver
|
||||
var contacts = await _context.Contacts
|
||||
.Where(c => (c.ContactId == request.UserId || c.UserId == request.UserId) && c.Status == ContactStatus.Pending)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
// 2. Fetch all unique IDs for users we need replicas for
|
||||
var userIds = contacts
|
||||
.Select(c => c.UserId == request.UserId ? c.ContactId : c.UserId)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
// 3. Fetch replicas
|
||||
var replicas = await _context.UserReplicas
|
||||
.Where(r => userIds.Contains(r.Id))
|
||||
.ToDictionaryAsync(r => r.Id, cancellationToken);
|
||||
|
||||
// 4. Transform into DTOs
|
||||
var result = contacts
|
||||
.Select(c =>
|
||||
{
|
||||
var isOutgoing = c.UserId == request.UserId;
|
||||
var otherUserId = isOutgoing ? c.ContactId : c.UserId;
|
||||
|
||||
// If replica is missing, we try to at least return the record (Visibility fix part 1)
|
||||
// We will handle replica creation in SendContactRequest proactively.
|
||||
if (!replicas.TryGetValue(otherUserId, out var user))
|
||||
{
|
||||
return new ContactRequestDto(
|
||||
c.Id,
|
||||
new ContactUserDto(otherUserId, "Unknown", "Unknown", ""),
|
||||
c.CreatedAt,
|
||||
isOutgoing
|
||||
);
|
||||
}
|
||||
|
||||
return new ContactRequestDto(
|
||||
c.Id,
|
||||
new ContactUserDto(user.Id, user.Username, user.DisplayName, user.Avatar),
|
||||
c.CreatedAt,
|
||||
isOutgoing
|
||||
);
|
||||
})
|
||||
.ToList();
|
||||
|
||||
return Result.Success(result);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user