Enhance internationalization support by integrating language selection for school names, updating UI components for localization, and revising documentation. Implement locale-aware formatting for dates and strings, ensuring a seamless user experience in both Russian and English. Update tests to cover new language features.
ci / server (push) Failing after 3m33s
ci / client (push) Successful in 15s

This commit is contained in:
Leonid Pershin
2026-08-18 12:43:14 +03:00
parent b9ddc018d3
commit cc9efca891
24 changed files with 640 additions and 140 deletions
+7 -2
View File
@@ -29,9 +29,9 @@ internal static class SchoolEndpoints
})
.WithName("GetSchools");
schools.MapGet("/random-name", async (GameCommandQueue commands, CancellationToken cancellationToken) =>
schools.MapGet("/random-name", async (string? lang, GameCommandQueue commands, CancellationToken cancellationToken) =>
{
var command = new GameCommand.SuggestName(NewCompletion<string>());
var command = new GameCommand.SuggestName(ParseNameLanguage(lang), NewCompletion<string>());
commands.Enqueue(command);
var name = await command.Result.Task.WaitAsync(CommandTimeout, cancellationToken);
@@ -85,6 +85,11 @@ internal static class SchoolEndpoints
private static TaskCompletionSource<T> NewCompletion<T>() =>
new(TaskCreationOptions.RunContinuationsAsynchronously);
private static SchoolNameLanguage ParseNameLanguage(string? lang) =>
string.Equals(lang, "en", StringComparison.OrdinalIgnoreCase)
? SchoolNameLanguage.English
: SchoolNameLanguage.Russian;
private static IResult Problem(int statusCode, string code, string detail) =>
Results.Problem(detail: detail, statusCode: statusCode, title: code, extensions: new Dictionary<string, object?>
{
+3 -1
View File
@@ -1,3 +1,5 @@
using HSchool.Simulation;
namespace HSchool.Server.Game;
/// <summary>
@@ -13,7 +15,7 @@ internal abstract record GameCommand
internal sealed record DeleteSchool(int SchoolId, TaskCompletionSource<bool> Result) : GameCommand;
internal sealed record SuggestName(TaskCompletionSource<string> Result) : GameCommand;
internal sealed record SuggestName(SchoolNameLanguage Language, TaskCompletionSource<string> Result) : GameCommand;
/// <summary>A connection starts watching a school; its calendar starts running.</summary>
internal sealed record OpenSchool(uint PlayerId, int SchoolId) : GameCommand;
+1 -1
View File
@@ -111,7 +111,7 @@ internal sealed class GameLoopService(
break;
case GameCommand.SuggestName suggest:
Complete(suggest.Result, _schools.SuggestName);
Complete(suggest.Result, () => _schools.SuggestName(suggest.Language));
break;
case GameCommand.OpenSchool open: