125 lines
4.3 KiB
C#
125 lines
4.3 KiB
C#
// Copyright (C) 2023-present sam/u1f320 (vulpine.solutions)
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Affero General Public License as published
|
|
// by the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU Affero General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
using Foxnouns.Backend.Database;
|
|
using Foxnouns.Backend.Database.Models;
|
|
using Foxnouns.Backend.Dto.V1;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using FieldEntry = Foxnouns.Backend.Dto.V1.FieldEntry;
|
|
using PrideFlag = Foxnouns.Backend.Dto.V1.PrideFlag;
|
|
|
|
namespace Foxnouns.Backend.Services.V1;
|
|
|
|
public class MembersV1Service(DatabaseContext db, UsersV1Service usersV1Service)
|
|
{
|
|
public async Task<Member> ResolveMemberAsync(string id, CancellationToken ct = default)
|
|
{
|
|
Member? member;
|
|
if (Snowflake.TryParse(id, out Snowflake? sf))
|
|
{
|
|
member = await db
|
|
.Members.Include(m => m.User)
|
|
.FirstOrDefaultAsync(m => m.Id == sf && !m.User.Deleted, ct);
|
|
if (member != null)
|
|
return member;
|
|
}
|
|
|
|
member = await db
|
|
.Members.Include(m => m.User)
|
|
.FirstOrDefaultAsync(m => m.LegacyId == id && !m.User.Deleted, ct);
|
|
if (member != null)
|
|
return member;
|
|
|
|
throw new ApiError.NotFound("No member with that ID found.", ErrorCode.MemberNotFound);
|
|
}
|
|
|
|
public async Task<Member> ResolveMemberAsync(
|
|
string userRef,
|
|
string memberRef,
|
|
Token? token,
|
|
CancellationToken ct = default
|
|
)
|
|
{
|
|
User user = await usersV1Service.ResolveUserAsync(userRef, token, ct);
|
|
|
|
Member? member;
|
|
if (Snowflake.TryParse(memberRef, out Snowflake? sf))
|
|
{
|
|
member = await db
|
|
.Members.Include(m => m.User)
|
|
.FirstOrDefaultAsync(m => m.Id == sf && m.UserId == user.Id, ct);
|
|
if (member != null)
|
|
return member;
|
|
}
|
|
|
|
member = await db
|
|
.Members.Include(m => m.User)
|
|
.FirstOrDefaultAsync(m => m.LegacyId == memberRef && m.UserId == user.Id, ct);
|
|
if (member != null)
|
|
return member;
|
|
|
|
member = await db
|
|
.Members.Include(m => m.User)
|
|
.FirstOrDefaultAsync(m => m.Name == memberRef && m.UserId == user.Id, ct);
|
|
if (member != null)
|
|
return member;
|
|
|
|
throw new ApiError.NotFound(
|
|
"No member with that ID or name found.",
|
|
ErrorCode.MemberNotFound
|
|
);
|
|
}
|
|
|
|
public async Task<MemberResponse> RenderMemberAsync(
|
|
Member m,
|
|
Token? token = default,
|
|
User? user = null,
|
|
bool renderFlags = true,
|
|
CancellationToken ct = default
|
|
)
|
|
{
|
|
user ??= m.User;
|
|
bool renderUnlisted = m.UserId == token?.UserId;
|
|
|
|
List<MemberFlag> flags = renderFlags
|
|
? await db.MemberFlags.Where(f => f.MemberId == m.Id).OrderBy(f => f.Id).ToListAsync(ct)
|
|
: [];
|
|
|
|
return new MemberResponse(
|
|
m.LegacyId,
|
|
m.Id,
|
|
m.Sid,
|
|
m.Name,
|
|
m.DisplayName,
|
|
m.Bio,
|
|
m.Avatar,
|
|
m.Links,
|
|
Names: FieldEntry.FromEntries(m.Names, user.CustomPreferences),
|
|
Pronouns: PronounEntry.FromPronouns(m.Pronouns, user.CustomPreferences),
|
|
Fields: ProfileField.FromFields(m.Fields, user.CustomPreferences),
|
|
Flags: flags
|
|
.Where(f => f.PrideFlag.Hash != null)
|
|
.Select(f => new PrideFlag(
|
|
f.PrideFlag.LegacyId,
|
|
f.PrideFlag.Id,
|
|
f.PrideFlag.Hash!,
|
|
f.PrideFlag.Name,
|
|
f.PrideFlag.Description
|
|
))
|
|
.ToArray(),
|
|
User: UsersV1Service.RenderPartialUser(user),
|
|
Unlisted: renderUnlisted ? m.Unlisted : null
|
|
);
|
|
}
|
|
}
|