feat: GET /api/v1/members/{id}, api v1 flags
This commit is contained in:
		
							parent
							
								
									2281b3e478
								
							
						
					
					
						commit
						d182b07482
					
				
					 6 changed files with 229 additions and 22 deletions
				
			
		
							
								
								
									
										72
									
								
								Foxnouns.Backend/Services/V1/MembersV1Service.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								Foxnouns.Backend/Services/V1/MembersV1Service.cs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,72 @@ | |||
| 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) | ||||
| { | ||||
|     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<MemberResponse> RenderMemberAsync( | ||||
|         Member m, | ||||
|         Token? token = default, | ||||
|         bool renderFlags = true, | ||||
|         CancellationToken ct = default | ||||
|     ) | ||||
|     { | ||||
|         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, m.User.CustomPreferences), | ||||
|             Pronouns: PronounEntry.FromPronouns(m.Pronouns, m.User.CustomPreferences), | ||||
|             Fields: ProfileField.FromFields(m.Fields, m.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(m.User), | ||||
|             Unlisted: renderUnlisted ? m.Unlisted : null | ||||
|         ); | ||||
|     } | ||||
| } | ||||
|  | @ -3,6 +3,7 @@ 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; | ||||
| 
 | ||||
|  | @ -49,8 +50,26 @@ public class UsersV1Service(DatabaseContext db) | |||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     public async Task<UserResponse> RenderUserAsync(User user) | ||||
|     public async Task<UserResponse> RenderUserAsync( | ||||
|         User user, | ||||
|         Token? token = null, | ||||
|         bool renderMembers = true, | ||||
|         bool renderFlags = true, | ||||
|         CancellationToken ct = default | ||||
|     ) | ||||
|     { | ||||
|         bool isSelfUser = user.Id == token?.UserId; | ||||
|         renderMembers = renderMembers && (isSelfUser || !user.ListHidden); | ||||
| 
 | ||||
|         // Only fetch members if we're rendering members (duh) | ||||
|         List<Member> members = renderMembers | ||||
|             ? await db.Members.Where(m => m.UserId == user.Id).OrderBy(m => m.Name).ToListAsync(ct) | ||||
|             : []; | ||||
| 
 | ||||
|         List<UserFlag> flags = renderFlags | ||||
|             ? await db.UserFlags.Where(f => f.UserId == user.Id).OrderBy(f => f.Id).ToListAsync(ct) | ||||
|             : []; | ||||
| 
 | ||||
|         int? utcOffset = null; | ||||
|         if ( | ||||
|             user.Timezone != null | ||||
|  | @ -70,23 +89,67 @@ public class UsersV1Service(DatabaseContext db) | |||
|             user.MemberTitle, | ||||
|             user.Avatar, | ||||
|             user.Links, | ||||
|             FieldEntry.FromEntries(user.Names, user.CustomPreferences), | ||||
|             PronounEntry.FromPronouns(user.Pronouns, user.CustomPreferences), | ||||
|             ProfileField.FromFields(user.Fields, user.CustomPreferences), | ||||
|             Names: FieldEntry.FromEntries(user.Names, user.CustomPreferences), | ||||
|             Pronouns: PronounEntry.FromPronouns(user.Pronouns, user.CustomPreferences), | ||||
|             Fields: ProfileField.FromFields(user.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(), | ||||
|             Members: members.Select(m => RenderPartialMember(m, user.CustomPreferences)).ToArray(), | ||||
|             utcOffset, | ||||
|             user.CustomPreferences.Select(x => | ||||
|                     ( | ||||
|                         x.Value.LegacyId, | ||||
|                         new CustomPreference( | ||||
|                             x.Value.Icon, | ||||
|                             x.Value.Tooltip, | ||||
|                             x.Value.Size, | ||||
|                             x.Value.Muted, | ||||
|                             x.Value.Favourite | ||||
|                         ) | ||||
|                     ) | ||||
|                 ) | ||||
|                 .ToDictionary() | ||||
|             CustomPreferences: RenderCustomPreferences(user.CustomPreferences) | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     private static Dictionary<Guid, CustomPreference> RenderCustomPreferences( | ||||
|         Dictionary<Snowflake, User.CustomPreference> customPreferences | ||||
|     ) => | ||||
|         customPreferences | ||||
|             .Select(x => | ||||
|                 ( | ||||
|                     x.Value.LegacyId, | ||||
|                     new CustomPreference( | ||||
|                         x.Value.Icon, | ||||
|                         x.Value.Tooltip, | ||||
|                         x.Value.Size, | ||||
|                         x.Value.Muted, | ||||
|                         x.Value.Favourite | ||||
|                     ) | ||||
|                 ) | ||||
|             ) | ||||
|             .ToDictionary(); | ||||
| 
 | ||||
|     private static PartialMember RenderPartialMember( | ||||
|         Member m, | ||||
|         Dictionary<Snowflake, User.CustomPreference> customPreferences | ||||
|     ) => | ||||
|         new( | ||||
|             m.LegacyId, | ||||
|             m.Id, | ||||
|             m.Sid, | ||||
|             m.Name, | ||||
|             m.DisplayName, | ||||
|             m.Bio, | ||||
|             m.Avatar, | ||||
|             m.Links, | ||||
|             Names: FieldEntry.FromEntries(m.Names, customPreferences), | ||||
|             Pronouns: PronounEntry.FromPronouns(m.Pronouns, customPreferences) | ||||
|         ); | ||||
| 
 | ||||
|     public static PartialUser RenderPartialUser(User user) => | ||||
|         new( | ||||
|             user.LegacyId, | ||||
|             user.Id, | ||||
|             user.Username, | ||||
|             user.DisplayName, | ||||
|             user.Avatar, | ||||
|             CustomPreferences: RenderCustomPreferences(user.CustomPreferences) | ||||
|         ); | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue