Skip to content

Commit 877f2d7

Browse files
committed
Updated GamePage UI and logic for gamer name handling
Updated `GamePage.razor` and `GamePage.razor.cs` to improve handling of gamer names. Changes include conditional rendering of UI elements based on the `_isNamePrefilled` variable, replacement of `_name` with `_gamerName` and `_gamerNameSuggestions`, and addition of new variables to track loading state and persisting state. Services for fetching gamer name suggestions and handling persisting state have been injected. Methods for initializing, starting game, and disposing have been updated accordingly. A new method for persisting gamer name and suggestions has been added.
1 parent 6cf031d commit 877f2d7

2 files changed

Lines changed: 68 additions & 16 deletions

File tree

src/CodeBreaker.Blazor.Client/Pages/GamePage.razor

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,26 @@
99
{
1010
<FluentGrid Class="align-items-end">
1111
<FluentGridItem xs="12" md="6">
12-
<FluentTextField
13-
Class="full-width"
14-
Label="@Loc["GamePage_NameInput"]"
15-
Placeholder="@Loc["GamePage_NameInputPlaceholder"]"
16-
@bind-Value="_name"
17-
Immediate
18-
Required
19-
Maxlength="100" />
12+
@if (_isNamePrefilled)
13+
{
14+
<FluentTextField
15+
Class="full-width"
16+
Label="@Loc["GamePage_NameInput"]"
17+
Required
18+
Value="@_gamerName"
19+
ReadOnly />
20+
}
21+
else
22+
{
23+
<FluentSelect
24+
Class="full-width"
25+
Label="@Loc["GamePage_NameInput"]"
26+
Items="_gamerNameSuggestions"
27+
@bind-Value="_gamerName"
28+
Required>
29+
<FluentProgressRing />
30+
</FluentSelect>
31+
}
2032
</FluentGridItem>
2133
<FluentGridItem xs="12" md="3">
2234
<FluentSelect

src/CodeBreaker.Blazor.Client/Pages/GamePage.razor.cs

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
using Microsoft.Extensions.Localization;
99
using System.Collections.Frozen;
1010
using Microsoft.FluentUI.AspNetCore.Components;
11+
using Microsoft.AspNetCore.Components.Authorization;
12+
using CodeBreaker.Blazor.Client.Contracts.Services;
1113

1214
namespace CodeBreaker.Blazor.Client.Pages;
1315

@@ -24,31 +26,56 @@ public partial class GamePage : IDisposable
2426
private IDisposable? _beforeNavigationInterceptor;
2527
private readonly System.Timers.Timer _timer = new(TimeSpan.FromHours(1));
2628
private GameMode _gameStatus = GameMode.NotRunning;
27-
private string _name = string.Empty;
29+
private string? _gamerName;
30+
private string[]? _gamerNameSuggestions;
2831
private bool _loadingGame = false;
32+
private bool _loadingGamerNameSuggestions = false;
2933
private bool _isGameCancelling = false;
3034
private GameInfo? _game;
3135
private GameType _gameType; // A workaround, because the GameType in GameInfo is a string.
36+
private bool _isNamePrefilled;
37+
private PersistingComponentStateSubscription _persistingSubscription;
38+
39+
[Inject] private ILogger<GamePage> Logger { get; init; } = default!;
3240

3341
[Inject] private IGamesClient Client { get; init; } = default!;
42+
43+
[Inject] private IGamerNameSuggestionClient GamerNameSuggestionClient { get; init; } = default!;
3444

3545
[Inject] private NavigationManager NavigationManager { get; init; } = default!;
3646

37-
[Inject] private Microsoft.FluentUI.AspNetCore.Components.IDialogService DialogService { get; init; } = default!;
47+
[Inject] private IDialogService DialogService { get; init; } = default!;
3848

3949
[Inject] private IStringLocalizer<Resource> Loc { get; init; } = default!;
4050

51+
[CascadingParameter] private Task<AuthenticationState> AuthenticationStateTask { get; set; } = default!;
52+
53+
[Inject] private PersistentComponentState ApplicationState { get; init; } = default!;
54+
4155
private string? SelectedGameTypeKey { get; set; }
4256

4357
private GameType? SelectedGameType => SelectedGameTypeKey is null ? null : _gameTypes[SelectedGameTypeKey];
4458

45-
private bool CanStartGame => !string.IsNullOrWhiteSpace(_name) && _name.Length > 3 && !_loadingGame;
59+
private bool CanStartGame => !string.IsNullOrWhiteSpace(_gamerName) && !_loadingGame;
4660

4761
protected override async Task OnInitializedAsync()
4862
{
4963
_timer.Elapsed += OnTimedEvent;
5064
_timer.AutoReset = true;
51-
_name = string.Empty;
65+
_persistingSubscription = ApplicationState.RegisterOnPersisting(PersistGamerNameAsync);
66+
67+
// Get gamer name from user claims (if available)
68+
_gamerName = (await AuthenticationStateTask).User.FindFirst("extension_gamerName")?.Value;
69+
_isNamePrefilled = !string.IsNullOrEmpty(_gamerName);
70+
71+
// Get gamer name suggestions, if not prefilled and therefore the user is not authenticated
72+
if (!_isNamePrefilled && !ApplicationState.TryTakeFromJson(nameof(_gamerNameSuggestions), out _gamerNameSuggestions))
73+
_gamerNameSuggestions = (await GamerNameSuggestionClient.GetGamerNameSuggestionsAsync()).Suggestions;
74+
75+
// Set the first suggestion as default, if there are any and therefore the user is not authenticated
76+
if (_gamerNameSuggestions is not null)
77+
_gamerName = _gamerNameSuggestions.FirstOrDefault();
78+
5279
await base.OnInitializedAsync();
5380
}
5481

@@ -60,6 +87,13 @@ protected override void OnAfterRender(bool firstRender)
6087
base.OnAfterRender(firstRender);
6188
}
6289

90+
private Task PersistGamerNameAsync()
91+
{
92+
ApplicationState.PersistAsJson(nameof(_gamerName), _gamerName);
93+
ApplicationState.PersistAsJson(nameof(_gamerNameSuggestions), _gamerNameSuggestions);
94+
return Task.CompletedTask;
95+
}
96+
6397
private async Task StartGameAsync()
6498
{
6599
if (SelectedGameType is null)
@@ -69,19 +103,24 @@ private async Task StartGameAsync()
69103
{
70104
_loadingGame = true;
71105
_gameStatus = GameMode.NotRunning;
72-
(Guid gameId, int numberCodes, int maxMoves, IDictionary<string, string[]> fieldValues) = await Client.StartGameAsync(SelectedGameType.Value, _name);
73-
_game = new(gameId, SelectedGameType.Value.ToString(), _name, DateTime.Now, numberCodes, maxMoves)
106+
(Guid gameId, int numberCodes, int maxMoves, IDictionary<string, string[]> fieldValues) = await Client.StartGameAsync(SelectedGameType.Value, _gamerName);
107+
_game = new(gameId, SelectedGameType.Value.ToString(), _gamerName, DateTime.Now, numberCodes, maxMoves)
74108
{
75109
FieldValues = fieldValues.ToDictionary(x => x.Key, x => x.Value.AsEnumerable()),
76110
Codes = []
77111
};
78112
_gameType = SelectedGameType.Value;
79113
_gameStatus = GameMode.Started;
80114
}
115+
catch (HttpRequestException ex)
116+
{
117+
Logger.LogError(ex, ex.Message);
118+
DialogService.ShowError(ex.Message);
119+
}
81120
catch (Exception ex)
82121
{
83-
//TODO: Handle Exception
84-
Console.WriteLine(ex.Message);
122+
Logger.LogError(ex, ex.Message);
123+
throw;
85124
}
86125
finally
87126
{
@@ -179,5 +218,6 @@ public void Dispose()
179218
{
180219
_timer?.Dispose();
181220
_beforeNavigationInterceptor?.Dispose();
221+
_persistingSubscription.Dispose();
182222
}
183223
}

0 commit comments

Comments
 (0)