Skip to content

Commit

Permalink
+ generation error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
NicklausBrain committed Nov 30, 2024
1 parent 6d15030 commit a30c750
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 50 deletions.
5 changes: 5 additions & 0 deletions My1kWordsEe/Components/Layout/NavMenu.razor
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@
<span class="bi bi-translate" aria-hidden="true"></span> Translate to English
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="/listen-game/en" Match="NavLinkMatch.All">
<span class="bi bi-ear-fill" aria-hidden="true"></span> Listen to Estonian
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="/word-2-word-match-game/en" Match="NavLinkMatch.All">
<span class="bi bi-dice-6-fill" aria-hidden="true"></span> Match Words
Expand Down
37 changes: 27 additions & 10 deletions My1kWordsEe/Components/Pages/Games/ListenToEeGamePage.razor
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
@rendermode @(new InteractiveServerRenderMode(prerender: false))

@using BlazorBootstrap
@using CSharpFunctionalExtensions
@using My1kWordsEe.Models
@using My1kWordsEe.Models.Games
@using My1kWordsEe.Services.Cqs
Expand All @@ -13,12 +14,21 @@
@inject IJSRuntime JS;

@code {
TranslateToEnGame Game = TranslateToEnGame.Empty;
ListenToEeGame Game = ListenToEeGame.Empty;
Maybe<string> GameGenerationError;

protected override async Task OnParametersSetAsync()
{
Game = TranslateToEnGame.Empty;
Game = await TranslateToEnGame.Generate(EnsureWordCommand, CreateSampleCommand);
Game = ListenToEeGame.Empty;
var gameGen = await ListenToEeGame.Generate(EnsureWordCommand, CreateSampleCommand);
if (gameGen.IsSuccess)
{
Game = gameGen.Value;
}
else
{
GameGenerationError = gameGen.Error;
}
await base.OnParametersSetAsync();
}

Expand Down Expand Up @@ -69,7 +79,7 @@
<div class="card text-center">
<div class="card-body">
<h5 class="card-title">
@Game.EeSentence
@* @Game.EeSentence *@
<button type="button" class="btn btn-primary btn-sm" @onclick="PlaySample">
<i class="bi bi-volume-down-fill"></i>
</button>
Expand All @@ -87,17 +97,17 @@
if (checkResult.IsMaxMatch)
{
<li class="list-group-item list-group-item-success">
@checkResult.EnUserSentence
@checkResult.EeSentence
</li>
}
else
{
<li class="list-group-item list-group-item-warning">
@checkResult.EnUserSentence
@checkResult.EeUserSentence
(@checkResult.Match / 5)
</li>
<li class="list-group-item list-group-item-success">
@checkResult.EnExpectedSentence
@checkResult.EeSentence
</li>
<li class="list-group-item list-group-item-info">
@checkResult.EnComment
Expand All @@ -121,20 +131,27 @@
else
{
<div class="input-group input-group-sm">
<span class="input-group-text btn-success">Your translation:</span>
<InputText @bind-Value="@Game.UserTranslation" class="form-control" autocomplete="off" />
<span class="input-group-text btn-success">You hear:</span>
<InputText @bind-Value="@Game.UserInput" class="form-control" autocomplete="off" />
<button @onclick="@OnSubmit" class="btn btn-outline-primary" type="button">Submit</button>
</div>
}
</div>
</div>
</div>
}
else
else if (GameGenerationError.HasNoValue)
{
<div class="d-flex justify-content-center">
<Spinner />
</div>
}

@if (GameGenerationError.HasValue)
{
<p class="text-danger">
@GameGenerationError
</p>
}
</div>
</div>
74 changes: 44 additions & 30 deletions My1kWordsEe/Components/Pages/Games/TranslateToEnGamePage.razor
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
@rendermode @(new InteractiveServerRenderMode(prerender: false))

@using BlazorBootstrap
@using CSharpFunctionalExtensions
@using My1kWordsEe.Models
@using My1kWordsEe.Models.Games
@using My1kWordsEe.Services.Cqs
Expand All @@ -13,12 +14,21 @@
@inject IJSRuntime JS;

@code {
TranslateToEnGame Game = TranslateToEnGame.Empty;
TranslateToEnGame Game;

Check warning on line 17 in My1kWordsEe/Components/Pages/Games/TranslateToEnGamePage.razor

View workflow job for this annotation

GitHub Actions / test

Non-nullable field 'Game' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.
Maybe<string> GameGenerationError;

protected override async Task OnParametersSetAsync()
{
Game = TranslateToEnGame.Empty;
Game = await TranslateToEnGame.Generate(EnsureWordCommand, CreateSampleCommand);
var gameGen = await TranslateToEnGame.Generate(EnsureWordCommand, CreateSampleCommand);
if (gameGen.IsSuccess)
{
Game = gameGen.Value;
}
else
{
GameGenerationError = gameGen.Error;
}
await base.OnParametersSetAsync();
}

Expand Down Expand Up @@ -77,48 +87,45 @@
</h5>
<img id="sampleImage" class="img-fluid rounded img-max-w-256 p-1" src="@Game.ImageUrl" />

@if (Game.CheckResult.HasValue)
@if (Game.CheckResult.HasValue && Game.CheckResult.Value.IsSuccess)
{
var checkResult = Game.CheckResult.Value.Value;

<ul class="list-group">
@if (Game.CheckResult.Value.IsSuccess)
@if (checkResult.IsMaxMatch)
{
var checkResult = Game.CheckResult.Value.Value;

if (checkResult.IsMaxMatch)
{
<li class="list-group-item list-group-item-success">
@checkResult.EnUserSentence
</li>
}
else
{
<li class="list-group-item list-group-item-warning">
@checkResult.EnUserSentence
(@checkResult.Match / 5)
</li>
<li class="list-group-item list-group-item-success">
@checkResult.EnExpectedSentence
</li>
<li class="list-group-item list-group-item-info">
@checkResult.EnComment
</li>
}
<li class="list-group-item list-group-item-success">
@checkResult.EnUserSentence
</li>
}
@if (Game.CheckResult.Value.IsFailure)
else
{
<li class="list-group-item list-group-item-warning">
@Game.CheckResult.Value.Error
@checkResult.EnUserSentence
(@checkResult.Match / 5)
</li>
<li class="list-group-item list-group-item-success">
@checkResult.EnExpectedSentence
</li>
<li class="list-group-item list-group-item-info">
@checkResult.EnComment
</li>
}
</ul>
}
else if (@Game.IsCheckInProgress)
@if (Game.CheckResult.HasValue && Game.CheckResult.Value.IsFailure)
{
<p class="text-danger">
@Game.CheckResult.Value.Error
</p>
}
@if (Game.IsCheckInProgress)
{
<div class="text-center">
<Spinner />
</div>
}
else
else if (Game.CheckResult.HasNoValue)
{
<div class="input-group input-group-sm">
<span class="input-group-text btn-success">Your translation:</span>
Expand All @@ -130,11 +137,18 @@
</div>
</div>
}
else
else if (GameGenerationError.HasNoValue)
{
<div class="d-flex justify-content-center">
<Spinner />
</div>
}

@if (GameGenerationError.HasValue)
{
<p class="text-danger">
@GameGenerationError
</p>
}
</div>
</div>
41 changes: 33 additions & 8 deletions My1kWordsEe/Models/Games/ListenToEeGame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,42 +40,56 @@ public async Task Submit(CheckEnTranslationCommand checkEnTranslationCommand)
}

var userInput = UserInput.Trim('.', ' ');
var eeSampleSentence = sampleSentence.EnSentence.Trim('.', ' ');
var eeSampleSentence = sampleSentence.EeSentence.Trim('.', ' ');

if (string.Equals(
userInput,
eeSampleSentence,
StringComparison.InvariantCultureIgnoreCase))
{
CheckResult = Result.Success(EeListeningCheckResult.Success(
eeSentence: eeSampleSentence,
eeSentence: sampleSentence.EeSentence,
enSentence: sampleSentence.EnSentence,
eeUserSentence: userInput));
}
else
{
//IsCheckInProgress = true;
CheckResult = Result.Success(EeListeningCheckResult.Failure(
eeSentence: eeSampleSentence,
eeSentence: sampleSentence.EeSentence,
enSentence: sampleSentence.EnSentence,
eeUserSentence: userInput));
//IsCheckInProgress = false;
}
}

public static async Task<TranslateToEnGame> Generate(
public static async Task<Result<ListenToEeGame>> Generate(
GetOrAddSampleWordCommand getOrAddSampleWordCommand,
AddSampleSentenceCommand addSampleSentenceCommand)
{
var rn = new Random(Environment.TickCount);
var eeWord = Ee1kWords.AllWords[rn.Next(0, Ee1kWords.AllWords.Length)];
var sampleWord = await getOrAddSampleWordCommand.Invoke(eeWord.Value);

if (sampleWord.IsFailure)
{
return Result.Failure<ListenToEeGame>(sampleWord.Error);
}

if (sampleWord.Value.Samples.Any())
{
return new TranslateToEnGame(sampleWord.Value.Samples.First());
return new ListenToEeGame(sampleWord.Value.Samples.First());
}
else
{
return new TranslateToEnGame((await addSampleSentenceCommand.Invoke(sampleWord.Value)).Value.Samples.First());
var addSampleResult = await addSampleSentenceCommand.Invoke(sampleWord.Value);

if (addSampleResult.IsSuccess)
{
return new ListenToEeGame(addSampleResult.Value.Samples.First());
}

return Result.Failure<ListenToEeGame>(addSampleResult.Error);
}
}

Expand All @@ -92,6 +106,9 @@ public record EeListeningCheckResult
[JsonPropertyName("ee_sentence")]
public required string EeSentence { get; init; }

[JsonPropertyName("en_sentence")]
public required string EnSentence { get; init; }

[JsonPropertyName("ee_user_sentence")]
public required string EeUserSentence { get; init; }

Expand All @@ -103,19 +120,27 @@ public record EeListeningCheckResult

public bool IsMaxMatch => this.Match == 5;

public static EeListeningCheckResult Success(string eeSentence, string eeUserSentence) =>
public static EeListeningCheckResult Success(
string eeSentence,
string enSentence,
string eeUserSentence) =>
new EeListeningCheckResult
{
EeSentence = eeSentence,
EnSentence = enSentence,
EeUserSentence = eeUserSentence,
Match = 5,
EnComment = string.Empty
};

public static EeListeningCheckResult Failure(string eeSentence, string eeUserSentence) =>
public static EeListeningCheckResult Failure(
string eeSentence,
string enSentence,
string eeUserSentence) =>
new EeListeningCheckResult
{
EeSentence = eeSentence,
EnSentence = enSentence,
EeUserSentence = eeUserSentence,
Match = 0,
EnComment = string.Empty
Expand Down
16 changes: 14 additions & 2 deletions My1kWordsEe/Models/Games/TranslateToEnGame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,21 +59,33 @@ public async Task Submit(CheckEnTranslationCommand checkEnTranslationCommand)
}
}

public static async Task<TranslateToEnGame> Generate(
public static async Task<Result<TranslateToEnGame>> Generate(
GetOrAddSampleWordCommand getOrAddSampleWordCommand,
AddSampleSentenceCommand addSampleSentenceCommand)
{
var rn = new Random(Environment.TickCount);
var eeWord = Ee1kWords.AllWords[rn.Next(0, Ee1kWords.AllWords.Length)];
var sampleWord = await getOrAddSampleWordCommand.Invoke(eeWord.Value);

if (sampleWord.IsFailure)
{
return Result.Failure<TranslateToEnGame>(sampleWord.Error);
}

if (sampleWord.Value.Samples.Any())
{
return new TranslateToEnGame(sampleWord.Value.Samples.First());
}
else
{
return new TranslateToEnGame((await addSampleSentenceCommand.Invoke(sampleWord.Value)).Value.Samples.First());
var addSampleResult = await addSampleSentenceCommand.Invoke(sampleWord.Value);

if (addSampleResult.IsSuccess)
{
return new TranslateToEnGame(addSampleResult.Value.Samples.First());
}

return Result.Failure<TranslateToEnGame>(addSampleResult.Error);
}
}

Expand Down

0 comments on commit a30c750

Please sign in to comment.