82 lines
2.8 KiB
C#
82 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 GetContactsQuery(Guid UserId) : IQuery<List<ContactDto>>;
|
|
|
|
internal sealed class GetContactsQueryHandler : IQueryHandler<GetContactsQuery, List<ContactDto>>
|
|
{
|
|
private readonly IContactsDbContext _context;
|
|
|
|
public GetContactsQueryHandler(IContactsDbContext context)
|
|
{
|
|
_context = context;
|
|
}
|
|
|
|
public async Task<Result<List<ContactDto>>> Handle(GetContactsQuery request, CancellationToken cancellationToken)
|
|
{
|
|
// 1. Fetch ALL accepted relations for current user
|
|
var relations = await _context.Contacts
|
|
.Where(c => (c.UserId == request.UserId || c.ContactId == request.UserId) && c.Status == ContactStatus.Accepted)
|
|
.ToListAsync(cancellationToken);
|
|
|
|
// 2. Fetch all unique IDs for users we need replicas for
|
|
var contactIds = relations.Select(c => c.UserId == request.UserId ? c.ContactId : c.UserId).Distinct().ToList();
|
|
|
|
// 3. Fetch replicas
|
|
var replicas = await _context.UserReplicas
|
|
.Where(r => contactIds.Contains(r.Id))
|
|
.ToDictionaryAsync(r => r.Id, cancellationToken);
|
|
|
|
var result = new List<ContactDto>();
|
|
|
|
// 4. Iterate over RELATIONS (to ensure we don't skip people with missing replicas)
|
|
foreach (var rel in relations)
|
|
{
|
|
var otherUserId = rel.UserId == request.UserId ? rel.ContactId : rel.UserId;
|
|
|
|
if (replicas.TryGetValue(otherUserId, out var replica))
|
|
{
|
|
result.Add(new ContactDto(
|
|
replica.Id,
|
|
replica.Username,
|
|
replica.DisplayName,
|
|
replica.Avatar,
|
|
false, // isOnline - current user query doesn't handle this here
|
|
null, // lastSeen
|
|
rel.Id,
|
|
rel.Status == ContactStatus.Blocked,
|
|
replica.IsExternal,
|
|
replica.Domain
|
|
));
|
|
}
|
|
else
|
|
{
|
|
// Return placeholder but ensure it's in the list
|
|
result.Add(new ContactDto(
|
|
otherUserId,
|
|
"Unknown",
|
|
"Unknown",
|
|
"",
|
|
false,
|
|
null,
|
|
rel.Id,
|
|
false,
|
|
false,
|
|
null
|
|
));
|
|
}
|
|
}
|
|
|
|
return Result.Success(result);
|
|
}
|
|
}
|