Tests / test (push) Canceled after 0s
Native crypto / native-crypto (push) Canceled after 0s
Release (main) / android (oneme) (push) Canceled after 0s
Release (main) / android (qlyra) (push) Canceled after 0s
Release (main) / windows (push) Canceled after 0s
Release (main) / linux (push) Canceled after 0s
Release (main) / macos (push) Canceled after 0s
Release (main) / ios (push) Canceled after 0s
Release (main) / release (push) Canceled after 0s
51 lines
3.0 KiB
C#
51 lines
3.0 KiB
C#
using Ikar.Server.Data.Entities;
|
|
using Ikar.Shared;
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
namespace Ikar.Server.Infrastructure.Admin;
|
|
|
|
public sealed record AdminPage<T>(IReadOnlyList<T> Items, int Total, int Page, int PageSize);
|
|
|
|
public sealed partial class AdminService
|
|
{
|
|
private static IQueryable<User> FilterUsers(IQueryable<User> query, string? status) => status switch {
|
|
"blocked" => query.Where(x => x.IsBlocked), "active" => query.Where(x => !x.IsBlocked),
|
|
"bots" => query.Where(x => x.IsBot), "people" => query.Where(x => !x.IsBot), _ => query };
|
|
|
|
public async Task<AdminPage<AdminUserDto>> UserPageAsync(string? q, string? status, int page, int size, CancellationToken ct)
|
|
{
|
|
page = Math.Clamp(page, 1, 1000000); size = Math.Clamp(size, 1, 100);
|
|
var query = FilterUsers(dbContext.Users.AsNoTracking(), status);
|
|
if (!string.IsNullOrWhiteSpace(q)) {
|
|
var normalized = q.Trim().ToUpperInvariant(); var like = $"%{q.Trim()}%";
|
|
query = query.Where(x => x.NormalizedUsername.Contains(normalized) || EF.Functions.Like(x.DisplayName, like) || x.PhoneNumber != null && EF.Functions.Like(x.PhoneNumber, like));
|
|
}
|
|
return new(await GetUsersAsync(q, ct, page, size, status), await query.CountAsync(ct), page, size);
|
|
}
|
|
|
|
private static IQueryable<Chat> FilterChatAttention(IQueryable<Chat> query, string? attention) => attention switch {
|
|
"pending" => query.Where(x => x.JoinRequests.Any(r => r.Status == ChatJoinRequestStatus.Pending)),
|
|
"protected" => query.Where(x => x.HasProtectedContent || x.Messages.Any(m => m.HasProtectedContent)),
|
|
"topics" => query.Where(x => x.TopicsEnabled || x.Topics.Any()), _ => query };
|
|
|
|
public async Task<AdminPage<AdminChatDto>> ChatPageAsync(string? q, string? type, int page, int size, CancellationToken ct, string? attention = null)
|
|
{
|
|
page = Math.Clamp(page, 1, 1000000); size = Math.Clamp(size, 1, 100);
|
|
var query = BuildChatsQuery(q);
|
|
if (Enum.TryParse<ChatType>(type, true, out var kind)) query = query.Where(x => x.Type == kind);
|
|
query = FilterChatAttention(query, attention);
|
|
return new(await GetChatsAsync(q, ct, page, size, type, attention), await query.CountAsync(ct), page, size);
|
|
}
|
|
|
|
public async Task<AdminPage<AdminAttachmentDto>> AttachmentPageAsync(string? q, int page, int size, CancellationToken ct)
|
|
{
|
|
page = Math.Clamp(page, 1, 1000000); size = Math.Clamp(size, 1, 100);
|
|
var query = dbContext.MessageAttachments.AsNoTracking();
|
|
if (!string.IsNullOrWhiteSpace(q)) {
|
|
var like = $"%{q.Trim()}%";
|
|
query = query.Where(x => EF.Functions.Like(x.OriginalFileName, like) || EF.Functions.Like(x.ContentType, like) || EF.Functions.Like(x.Message.Sender.DisplayName, like) || x.Message.Chat.Title != null && EF.Functions.Like(x.Message.Chat.Title, like));
|
|
}
|
|
return new(await GetAttachmentsAsync(q, ct, page, size), await query.CountAsync(ct), page, size);
|
|
}
|
|
}
|