Ajoute le preremplissage du joueur connecte
This commit is contained in:
@@ -1,8 +1,15 @@
|
||||
@page "/application"
|
||||
@page "/application.html"
|
||||
@using System.Net
|
||||
@using System.Net.Http.Json
|
||||
@using System.Security.Claims
|
||||
@using ChessCubing.App.Models.Users
|
||||
@implements IDisposable
|
||||
@inject BrowserBridge Browser
|
||||
@inject MatchStore Store
|
||||
@inject NavigationManager Navigation
|
||||
@inject AuthenticationStateProvider AuthenticationStateProvider
|
||||
@inject HttpClient Http
|
||||
|
||||
<PageTitle>ChessCubing Arena | Application</PageTitle>
|
||||
<PageBody Page="setup" BodyClass="@SetupBodyClass" />
|
||||
@@ -137,13 +144,39 @@
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<label class="field">
|
||||
<span>Joueur blanc</span>
|
||||
<label class="field player-name-field">
|
||||
<div class="field-heading">
|
||||
<span class="field-label-text">Joueur blanc</span>
|
||||
|
||||
@if (CanUseConnectedPlayerName)
|
||||
{
|
||||
<button class="button ghost small icon-button player-fill-button"
|
||||
type="button"
|
||||
title="@BuildPrefillTitle("blanc")"
|
||||
aria-label="@BuildPrefillTitle("blanc")"
|
||||
@onclick="FillWhiteWithConnectedPlayer">
|
||||
<span class="material-icons action-icon" aria-hidden="true">account_circle</span>
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
<input @bind="Form.WhiteName" @bind:event="oninput" name="whiteName" type="text" maxlength="40" placeholder="Blanc" />
|
||||
</label>
|
||||
|
||||
<label class="field">
|
||||
<span>Joueur noir</span>
|
||||
<label class="field player-name-field">
|
||||
<div class="field-heading">
|
||||
<span class="field-label-text">Joueur noir</span>
|
||||
|
||||
@if (CanUseConnectedPlayerName)
|
||||
{
|
||||
<button class="button ghost small icon-button player-fill-button"
|
||||
type="button"
|
||||
title="@BuildPrefillTitle("noir")"
|
||||
aria-label="@BuildPrefillTitle("noir")"
|
||||
@onclick="FillBlackWithConnectedPlayer">
|
||||
<span class="material-icons action-icon" aria-hidden="true">account_circle</span>
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
<input @bind="Form.BlackName" @bind:event="oninput" name="blackName" type="text" maxlength="40" placeholder="Noir" />
|
||||
</label>
|
||||
|
||||
@@ -254,10 +287,12 @@
|
||||
@code {
|
||||
private SetupFormModel Form { get; set; } = new();
|
||||
private bool _ready;
|
||||
private string? ConnectedPlayerName;
|
||||
|
||||
private MatchState? CurrentMatch => Store.Current;
|
||||
|
||||
private string SetupBodyClass => UsesMoveLimit ? string.Empty : "time-setup-mode";
|
||||
private bool CanUseConnectedPlayerName => !string.IsNullOrWhiteSpace(ConnectedPlayerName);
|
||||
|
||||
private bool UsesMoveLimit => MatchEngine.UsesMoveLimit(Form.Mode);
|
||||
|
||||
@@ -286,6 +321,12 @@
|
||||
? $"Quota actif : {CurrentPreset.Quota} coups par joueur."
|
||||
: $"Quota actif : {CurrentPreset.Quota} coups par joueur et par Block.";
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
AuthenticationStateProvider.AuthenticationStateChanged += HandleAuthenticationStateChanged;
|
||||
await LoadConnectedPlayerAsync();
|
||||
}
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (!firstRender)
|
||||
@@ -298,6 +339,51 @@
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private void HandleAuthenticationStateChanged(Task<AuthenticationState> authenticationStateTask)
|
||||
=> _ = InvokeAsync(LoadConnectedPlayerAsync);
|
||||
|
||||
private async Task LoadConnectedPlayerAsync()
|
||||
{
|
||||
string? fallbackName = null;
|
||||
|
||||
try
|
||||
{
|
||||
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
|
||||
var user = authState.User;
|
||||
|
||||
if (user.Identity?.IsAuthenticated != true)
|
||||
{
|
||||
ConnectedPlayerName = null;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
return;
|
||||
}
|
||||
|
||||
fallbackName = BuildConnectedPlayerFallback(user);
|
||||
|
||||
var response = await Http.GetAsync("api/users/me");
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
ConnectedPlayerName = response.StatusCode is HttpStatusCode.Unauthorized or HttpStatusCode.Forbidden
|
||||
? null
|
||||
: fallbackName;
|
||||
|
||||
await InvokeAsync(StateHasChanged);
|
||||
return;
|
||||
}
|
||||
|
||||
var profile = await response.Content.ReadFromJsonAsync<UserProfileResponse>();
|
||||
ConnectedPlayerName = !string.IsNullOrWhiteSpace(profile?.DisplayName)
|
||||
? profile.DisplayName
|
||||
: fallbackName;
|
||||
}
|
||||
catch
|
||||
{
|
||||
ConnectedPlayerName = fallbackName;
|
||||
}
|
||||
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
private async Task HandleSubmit()
|
||||
{
|
||||
await Store.EnsureLoadedAsync();
|
||||
@@ -320,6 +406,26 @@
|
||||
private void LoadDemo()
|
||||
=> Form = SetupFormModel.CreateDemo();
|
||||
|
||||
private void FillWhiteWithConnectedPlayer()
|
||||
{
|
||||
if (!CanUseConnectedPlayerName)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Form.WhiteName = ConnectedPlayerName!;
|
||||
}
|
||||
|
||||
private void FillBlackWithConnectedPlayer()
|
||||
{
|
||||
if (!CanUseConnectedPlayerName)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Form.BlackName = ConnectedPlayerName!;
|
||||
}
|
||||
|
||||
private void SetMode(string mode)
|
||||
=> Form.Mode = mode;
|
||||
|
||||
@@ -360,4 +466,20 @@
|
||||
|
||||
return match.Phase == MatchEngine.PhaseCube ? "Page cube prete" : "Page chrono prete";
|
||||
}
|
||||
|
||||
private string BuildPrefillTitle(string color)
|
||||
=> $"Utiliser mon nom cote {color}";
|
||||
|
||||
private static string? BuildConnectedPlayerFallback(ClaimsPrincipal user)
|
||||
=> FirstNonEmpty(
|
||||
user.FindFirst("name")?.Value,
|
||||
user.FindFirst(ClaimTypes.Name)?.Value,
|
||||
user.FindFirst("preferred_username")?.Value,
|
||||
user.FindFirst(ClaimTypes.Email)?.Value);
|
||||
|
||||
private static string? FirstNonEmpty(params string?[] candidates)
|
||||
=> candidates.FirstOrDefault(candidate => !string.IsNullOrWhiteSpace(candidate));
|
||||
|
||||
public void Dispose()
|
||||
=> AuthenticationStateProvider.AuthenticationStateChanged -= HandleAuthenticationStateChanged;
|
||||
}
|
||||
|
||||
35
styles.css
35
styles.css
@@ -414,6 +414,17 @@ p {
|
||||
gap: 0.45rem;
|
||||
}
|
||||
|
||||
.field-heading {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.65rem;
|
||||
}
|
||||
|
||||
.field-label-text {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
@@ -567,6 +578,20 @@ textarea:focus {
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.player-name-field .field-heading {
|
||||
margin-bottom: -0.1rem;
|
||||
}
|
||||
|
||||
.player-fill-button {
|
||||
flex: 0 0 auto;
|
||||
padding: 0.42rem 0.48rem;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.player-fill-button .action-icon {
|
||||
font-size: 1.05rem;
|
||||
}
|
||||
|
||||
.side-panel {
|
||||
display: grid;
|
||||
gap: 1rem;
|
||||
@@ -2380,11 +2405,16 @@ body.site-menu-hidden .site-menu-shell {
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
body[data-page="setup"] .field-label-text,
|
||||
body[data-page="setup"] .field > span,
|
||||
body[data-page="setup"] legend {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
body[data-page="setup"] .player-fill-button {
|
||||
padding: 0.36rem 0.42rem;
|
||||
}
|
||||
|
||||
body[data-page="setup"] input,
|
||||
body[data-page="setup"] textarea {
|
||||
padding: 0.75rem 0.85rem;
|
||||
@@ -2751,11 +2781,16 @@ body.site-menu-hidden .site-menu-shell {
|
||||
gap: 0.45rem;
|
||||
}
|
||||
|
||||
body[data-page="setup"] .field-label-text,
|
||||
body[data-page="setup"] .field > span,
|
||||
body[data-page="setup"] legend {
|
||||
font-size: 0.84rem;
|
||||
}
|
||||
|
||||
body[data-page="setup"] .player-fill-button {
|
||||
padding: 0.34rem 0.4rem;
|
||||
}
|
||||
|
||||
body[data-page="setup"] input,
|
||||
body[data-page="setup"] textarea {
|
||||
padding: 0.68rem 0.75rem;
|
||||
|
||||
Reference in New Issue
Block a user