diff --git a/ChessCubing.App/Pages/ApplicationPage.razor b/ChessCubing.App/Pages/ApplicationPage.razor
index dc843c5..f6f877d 100644
--- a/ChessCubing.App/Pages/ApplicationPage.razor
+++ b/ChessCubing.App/Pages/ApplicationPage.razor
@@ -160,7 +160,7 @@
}
-
+
+ @if (!string.IsNullOrWhiteSpace(SetupError))
+ {
+
@SetupError
+ }
+
@if (IsAuthenticated)
{
@@ -379,6 +384,7 @@
private bool IsSocialLoading;
private int _knownSocialVersion;
private string? ConnectedPlayerName;
+ private string? SetupError;
private string? SocialLoadError;
private string? InviteActionError;
private SocialOverviewResponse? SocialOverview;
@@ -387,6 +393,26 @@
private string SetupBodyClass => UsesMoveLimit ? string.Empty : "time-setup-mode";
private bool CanUseConnectedPlayerName => !string.IsNullOrWhiteSpace(ConnectedPlayerName);
+ private string WhitePlayerName
+ {
+ get => Form.WhiteName;
+ set
+ {
+ Form.WhiteName = value;
+ SetupError = null;
+ }
+ }
+
+ private string BlackPlayerName
+ {
+ get => Form.BlackName;
+ set
+ {
+ Form.BlackName = value;
+ SetupError = null;
+ }
+ }
+
private SocialFriendResponse[] OnlineFriends
=> SocialOverview?.Friends
.Where(friend => ResolveOnlineStatus(friend.Subject, friend.IsOnline))
@@ -563,6 +589,13 @@
private async Task HandleSubmit()
{
+ SetupError = ValidateDistinctPlayers();
+ if (!string.IsNullOrWhiteSpace(SetupError))
+ {
+ StateHasChanged();
+ return;
+ }
+
await Store.EnsureLoadedAsync();
var match = MatchEngine.CreateMatch(Form.ToMatchConfig());
Store.SetCurrent(match);
@@ -581,7 +614,10 @@
}
private void LoadDemo()
- => Form = SetupFormModel.CreateDemo();
+ {
+ Form = SetupFormModel.CreateDemo();
+ SetupError = null;
+ }
private void FillWhiteWithConnectedPlayer()
{
@@ -590,7 +626,7 @@
return;
}
- Form.WhiteName = ConnectedPlayerName!;
+ AssignConnectedPlayerToWhite();
}
private void FillBlackWithConnectedPlayer()
@@ -600,7 +636,7 @@
return;
}
- Form.BlackName = ConnectedPlayerName!;
+ AssignConnectedPlayerToBlack();
}
private async Task InviteFriendToPlayAsync(string friendSubject, string recipientColor)
@@ -699,6 +735,53 @@
Form.WhiteName = session.WhiteName;
Form.BlackName = session.BlackName;
+ SetupError = null;
+ }
+
+ private void AssignConnectedPlayerToWhite()
+ {
+ if (!CanUseConnectedPlayerName)
+ {
+ return;
+ }
+
+ var connectedName = ConnectedPlayerName!;
+ Form.WhiteName = connectedName;
+
+ if (SamePlayerName(Form.BlackName, connectedName))
+ {
+ Form.BlackName = "Noir";
+ }
+
+ SetupError = null;
+ }
+
+ private void AssignConnectedPlayerToBlack()
+ {
+ if (!CanUseConnectedPlayerName)
+ {
+ return;
+ }
+
+ var connectedName = ConnectedPlayerName!;
+ Form.BlackName = connectedName;
+
+ if (SamePlayerName(Form.WhiteName, connectedName))
+ {
+ Form.WhiteName = "Blanc";
+ }
+
+ SetupError = null;
+ }
+
+ private string? ValidateDistinctPlayers()
+ {
+ var whiteName = NormalizePlayerName(Form.WhiteName, "Blanc");
+ var blackName = NormalizePlayerName(Form.BlackName, "Noir");
+
+ return SamePlayerName(whiteName, blackName)
+ ? "Le meme joueur ne peut pas etre renseigne des deux cotes. Choisis deux noms differents pour Blanc et Noir."
+ : null;
}
private bool ResolveOnlineStatus(string subject, bool fallbackStatus)
@@ -719,6 +802,17 @@
? "blanc"
: "noir";
+ private static string NormalizePlayerName(string? value, string fallback)
+ => MatchEngine.SanitizeText(value) is { Length: > 0 } normalized
+ ? normalized
+ : fallback;
+
+ private static bool SamePlayerName(string? left, string? right)
+ => string.Equals(
+ MatchEngine.SanitizeText(left) ?? string.Empty,
+ MatchEngine.SanitizeText(right) ?? string.Empty,
+ StringComparison.OrdinalIgnoreCase);
+
private void ResetSocialState()
{
SocialOverview = null;