Files
forkmessager/backend/src/Modules/Relations/Application/Contacts/GetContacts.cs
Халимов Рустам 4ae7dd60ce Рабочий чат
2026-04-01 23:18:55 +03:00

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);
}
}