76 lines
2.8 KiB
C#
76 lines
2.8 KiB
C#
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);
|
|
}
|
|
}
|