C# formatting
This commit is contained in:
@@ -16,29 +16,26 @@ public static class SuggestEndpoints
|
||||
group.MapGet("/mine", async (HttpContext ctx, AppDbContext db) =>
|
||||
{
|
||||
var player = await EndpointHelpers.GetAuthenticatedPlayer(ctx, db);
|
||||
if (player is null) return Results.Unauthorized();
|
||||
var mine = await db.Suggestions.AsNoTracking()
|
||||
.Where(s => s.PlayerId == player.Id)
|
||||
.Select(s => new
|
||||
{
|
||||
s.Id,
|
||||
s.PlayerId,
|
||||
s.Name,
|
||||
s.Genre,
|
||||
s.Description,
|
||||
s.ScreenshotUrl,
|
||||
s.YoutubeUrl,
|
||||
s.GameUrl,
|
||||
s.CreatedAt,
|
||||
s.MinPlayers,
|
||||
s.MaxPlayers,
|
||||
s.ParentSuggestionId
|
||||
})
|
||||
.ToListAsync();
|
||||
if (player is null)
|
||||
return Results.Unauthorized();
|
||||
|
||||
var ordered = mine
|
||||
.OrderBy(s => s.CreatedAt)
|
||||
.Select(s => new SuggestionDto(s.Id, s.Name, s.Genre, s.Description, s.ScreenshotUrl, s.YoutubeUrl, s.GameUrl, s.MinPlayers, s.MaxPlayers, s.ParentSuggestionId));
|
||||
var mine = await db.Suggestions.AsNoTracking().Where(s => s.PlayerId == player.Id).Select(s => new
|
||||
{
|
||||
s.Id,
|
||||
s.PlayerId,
|
||||
s.Name,
|
||||
s.Genre,
|
||||
s.Description,
|
||||
s.ScreenshotUrl,
|
||||
s.YoutubeUrl,
|
||||
s.GameUrl,
|
||||
s.CreatedAt,
|
||||
s.MinPlayers,
|
||||
s.MaxPlayers,
|
||||
s.ParentSuggestionId
|
||||
}).ToListAsync();
|
||||
|
||||
var ordered = mine.OrderBy(s => s.CreatedAt).Select(s => new SuggestionDto(s.Id, s.Name, s.Genre, s.Description, s.ScreenshotUrl, s.YoutubeUrl, s.GameUrl, s.MinPlayers, s.MaxPlayers, s.ParentSuggestionId));
|
||||
|
||||
return Results.Ok(ordered);
|
||||
});
|
||||
@@ -54,10 +51,12 @@ public static class SuggestEndpoints
|
||||
{
|
||||
return Results.BadRequest(new { error = "Screenshot URL must be http(s) and end with an image file extension." });
|
||||
}
|
||||
|
||||
if (!await EndpointHelpers.IsReachableImageAsync(request.ScreenshotUrl, http))
|
||||
{
|
||||
return Results.BadRequest(new { error = "Screenshot URL could not be validated as an image. Use a public image link (http/https, no redirects, max 5 MB)." });
|
||||
}
|
||||
|
||||
if (!EndpointHelpers.IsValidHttpUrl(request.GameUrl))
|
||||
return Results.BadRequest(new { error = "Game URL must be http or https." });
|
||||
if (!EndpointHelpers.IsValidHttpUrl(request.YoutubeUrl))
|
||||
@@ -67,11 +66,14 @@ public static class SuggestEndpoints
|
||||
return Results.BadRequest(new { error = playersError });
|
||||
|
||||
var player = await EndpointHelpers.GetAuthenticatedPlayer(ctx, db);
|
||||
if (player is null) return Results.Unauthorized();
|
||||
if (player is null)
|
||||
return Results.Unauthorized();
|
||||
|
||||
var phase = await EndpointHelpers.GetPhase(db, player.Id);
|
||||
var usingJoker = phase == Phase.Vote && player.HasJoker;
|
||||
if (phase != Phase.Suggest && !usingJoker)
|
||||
return EndpointHelpers.PhaseMismatch(Phase.Suggest, phase);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(player.DisplayName))
|
||||
{
|
||||
return Results.BadRequest(new { error = "Set a display name before submitting suggestions." });
|
||||
@@ -107,13 +109,14 @@ public static class SuggestEndpoints
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
return Results.Created($"/api/suggestions/{suggestion.Id}", new { suggestion.Id });
|
||||
})
|
||||
.AddEndpointFilter(new PhaseOrJokerFilter());
|
||||
}).AddEndpointFilter(new PhaseOrJokerFilter());
|
||||
|
||||
group.MapDelete("/{id:int}", async (int id, HttpContext ctx, AppDbContext db) =>
|
||||
{
|
||||
var player = await EndpointHelpers.GetAuthenticatedPlayer(ctx, db);
|
||||
if (player is null) return Results.Unauthorized();
|
||||
if (player is null)
|
||||
return Results.Unauthorized();
|
||||
|
||||
var isAdmin = await EndpointHelpers.IsAdmin(ctx, db);
|
||||
|
||||
if (!isAdmin)
|
||||
@@ -123,16 +126,12 @@ public static class SuggestEndpoints
|
||||
return EndpointHelpers.PhaseMismatch(Phase.Suggest, phase);
|
||||
}
|
||||
|
||||
var suggestion = isAdmin
|
||||
? await db.Suggestions.FirstOrDefaultAsync(s => s.Id == id)
|
||||
: await db.Suggestions.FirstOrDefaultAsync(s => s.Id == id && s.PlayerId == player.Id);
|
||||
var suggestion = isAdmin ? await db.Suggestions.FirstOrDefaultAsync(s => s.Id == id) : await db.Suggestions.FirstOrDefaultAsync(s => s.Id == id && s.PlayerId == player.Id);
|
||||
if (suggestion == null)
|
||||
return Results.NotFound(new { error = "Suggestion not found." });
|
||||
|
||||
// Break any links that pointed at this suggestion
|
||||
await db.Suggestions
|
||||
.Where(s => s.ParentSuggestionId == suggestion.Id)
|
||||
.ExecuteUpdateAsync(s => s.SetProperty(x => x.ParentSuggestionId, (int?)null));
|
||||
await db.Suggestions.Where(s => s.ParentSuggestionId == suggestion.Id).ExecuteUpdateAsync(s => s.SetProperty(x => x.ParentSuggestionId, (int?)null));
|
||||
|
||||
// Remove votes for this suggestion to avoid orphaned vote rows or FK errors
|
||||
await db.Votes.Where(v => v.SuggestionId == suggestion.Id).ExecuteDeleteAsync();
|
||||
@@ -147,7 +146,8 @@ public static class SuggestEndpoints
|
||||
var player = await EndpointHelpers.GetAuthenticatedPlayer(ctx, db);
|
||||
var isAdmin = await EndpointHelpers.IsAdmin(ctx, db);
|
||||
|
||||
if (!isAdmin && player is null) return Results.Unauthorized();
|
||||
if (!isAdmin && player is null)
|
||||
return Results.Unauthorized();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(request.Name) || request.Name.Length > 100)
|
||||
{
|
||||
@@ -158,10 +158,12 @@ public static class SuggestEndpoints
|
||||
{
|
||||
return Results.BadRequest(new { error = "Screenshot URL must be http(s) and end with an image file extension." });
|
||||
}
|
||||
|
||||
if (!await EndpointHelpers.IsReachableImageAsync(request.ScreenshotUrl, http))
|
||||
{
|
||||
return Results.BadRequest(new { error = "Screenshot URL could not be validated as an image. Use a public image link (http/https, no redirects, max 5 MB)." });
|
||||
}
|
||||
|
||||
if (!EndpointHelpers.IsValidHttpUrl(request.GameUrl))
|
||||
return Results.BadRequest(new { error = "Game URL must be http or https." });
|
||||
if (!EndpointHelpers.IsValidHttpUrl(request.YoutubeUrl))
|
||||
@@ -171,7 +173,8 @@ public static class SuggestEndpoints
|
||||
return Results.BadRequest(new { error = playersError });
|
||||
|
||||
var suggestion = await db.Suggestions.FirstOrDefaultAsync(s => s.Id == id);
|
||||
if (suggestion == null) return Results.NotFound(new { error = "Suggestion not found." });
|
||||
if (suggestion == null)
|
||||
return Results.NotFound(new { error = "Suggestion not found." });
|
||||
|
||||
if (!isAdmin)
|
||||
{
|
||||
@@ -238,14 +241,38 @@ public static class SuggestEndpoints
|
||||
group.MapGet("/all", async (HttpContext ctx, AppDbContext db) =>
|
||||
{
|
||||
var player = await EndpointHelpers.GetAuthenticatedPlayer(ctx, db);
|
||||
if (player is null) return Results.Unauthorized();
|
||||
if (player is null)
|
||||
return Results.Unauthorized();
|
||||
|
||||
var phase = await EndpointHelpers.GetPhase(db, player.Id);
|
||||
if (phase < Phase.Vote)
|
||||
return EndpointHelpers.PhaseMismatch(Phase.Vote, phase);
|
||||
|
||||
var all = await db.Suggestions.AsNoTracking()
|
||||
.Include(s => s.Player)
|
||||
.Select(s => new
|
||||
var all = await db.Suggestions.AsNoTracking().Include(s => s.Player).Select(s => new
|
||||
{
|
||||
s.Id,
|
||||
s.Name,
|
||||
s.Genre,
|
||||
s.Description,
|
||||
s.ScreenshotUrl,
|
||||
s.YoutubeUrl,
|
||||
s.GameUrl,
|
||||
s.MinPlayers,
|
||||
s.MaxPlayers,
|
||||
Author = s.Player!.DisplayName,
|
||||
s.CreatedAt,
|
||||
s.ParentSuggestionId,
|
||||
IsOwner = s.PlayerId == player.Id
|
||||
}).ToListAsync();
|
||||
|
||||
var rootIndex = EndpointHelpers.BuildLinkRoots(all.Select(s => (s.Id, s.ParentSuggestionId)));
|
||||
var nameLookup = all.ToDictionary(s => s.Id, s => s.Name);
|
||||
|
||||
var ordered = all.OrderBy(s => s.CreatedAt).Select(s =>
|
||||
{
|
||||
var linkedIds = EndpointHelpers.LinkedIdsFor(s.Id, rootIndex).Where(id => id != s.Id).ToList();
|
||||
|
||||
return new
|
||||
{
|
||||
s.Id,
|
||||
s.Name,
|
||||
@@ -256,45 +283,13 @@ public static class SuggestEndpoints
|
||||
s.GameUrl,
|
||||
s.MinPlayers,
|
||||
s.MaxPlayers,
|
||||
Author = s.Player!.DisplayName,
|
||||
s.CreatedAt,
|
||||
s.Author,
|
||||
s.ParentSuggestionId,
|
||||
IsOwner = s.PlayerId == player.Id
|
||||
})
|
||||
.ToListAsync();
|
||||
|
||||
var rootIndex = EndpointHelpers.BuildLinkRoots(all.Select(s => (s.Id, s.ParentSuggestionId)));
|
||||
var nameLookup = all.ToDictionary(s => s.Id, s => s.Name);
|
||||
|
||||
var ordered = all
|
||||
.OrderBy(s => s.CreatedAt)
|
||||
.Select(s =>
|
||||
{
|
||||
var linkedIds = EndpointHelpers.LinkedIdsFor(s.Id, rootIndex)
|
||||
.Where(id => id != s.Id)
|
||||
.ToList();
|
||||
|
||||
return new
|
||||
{
|
||||
s.Id,
|
||||
s.Name,
|
||||
s.Genre,
|
||||
s.Description,
|
||||
s.ScreenshotUrl,
|
||||
s.YoutubeUrl,
|
||||
s.GameUrl,
|
||||
s.MinPlayers,
|
||||
s.MaxPlayers,
|
||||
s.Author,
|
||||
s.ParentSuggestionId,
|
||||
s.IsOwner,
|
||||
LinkedIds = linkedIds,
|
||||
LinkedTitles = linkedIds
|
||||
.Where(id => nameLookup.ContainsKey(id))
|
||||
.Select(id => nameLookup[id])
|
||||
.ToList()
|
||||
};
|
||||
});
|
||||
s.IsOwner,
|
||||
LinkedIds = linkedIds,
|
||||
LinkedTitles = linkedIds.Where(nameLookup.ContainsKey).Select(id => nameLookup[id]).ToList()
|
||||
};
|
||||
});
|
||||
|
||||
return Results.Ok(ordered);
|
||||
});
|
||||
@@ -303,15 +298,16 @@ public static class SuggestEndpoints
|
||||
private static bool ValidatePlayers(int? minPlayers, int? maxPlayers, out string? error)
|
||||
{
|
||||
error = null;
|
||||
if (minPlayers is null && maxPlayers is null) return true;
|
||||
if (minPlayers is null && maxPlayers is null)
|
||||
return true;
|
||||
|
||||
if (minPlayers is not null && (minPlayers < 1 || minPlayers > 32))
|
||||
if (minPlayers is < 1 or > 32)
|
||||
{
|
||||
error = "Min players must be between 1 and 32.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (maxPlayers is not null && (maxPlayers < 1 || maxPlayers > 32))
|
||||
if (maxPlayers is < 1 or > 32)
|
||||
{
|
||||
error = "Max players must be between 1 and 32.";
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user