diff --git a/docs/development_guidelines.md b/docs/development_guidelines.md
index 9bc734e..347dab2 100644
--- a/docs/development_guidelines.md
+++ b/docs/development_guidelines.md
@@ -92,6 +92,11 @@ Break complex work into 3-5 stages. Document in `IMPLEMENTATION_PLAN.md` see [do
- Handle errors at appropriate level
- Never silently swallow exceptions
+Be aware of critical patterns, that can lead to deadlocks or other problem when using async methods. E.G.:
+- Search(pattern: "@\(_.*\.Result\)", glob: "*.razor", output_mode: "content")
+- Search(pattern: "\)\.Result", glob: "*.razor", output_mode: "content")
+- Search(pattern: "\.Wait\(\)", glob: "*.razor", output_mode: "content")
+
## Decision Framework
When multiple valid approaches exist, choose based on:
diff --git a/src/Koogle.Web/Components/Game/DeathBox/DeathBoxBoard.razor b/src/Koogle.Web/Components/Game/DeathBox/DeathBoxBoard.razor
index 3fd061c..5917d88 100644
--- a/src/Koogle.Web/Components/Game/DeathBox/DeathBoxBoard.razor
+++ b/src/Koogle.Web/Components/Game/DeathBox/DeathBoxBoard.razor
@@ -46,7 +46,7 @@
@if (_model.LastThrow != null)
{
- @(_ = GetLastThrowMessage().Result)
+ @_lastThrowMessage
}
@@ -172,18 +172,21 @@
private DeathBoxGameModel? _model;
private List _playerStats = [];
private int _activePlayerCount = 0;
+ private string _lastThrowMessage = "";
- protected override void OnInitialized()
+ protected override async Task OnInitializedAsync()
{
- base.OnInitialized();
+ await base.OnInitializedAsync();
GameState.StateChanged += OnGameStateChanged;
UpdateStats();
+ _lastThrowMessage = await GetLastThrowMessage();
}
- private void OnGameStateChanged(object? sender, EventArgs e)
+ private async void OnGameStateChanged(object? sender, EventArgs e)
{
UpdateStats();
- InvokeAsync(StateHasChanged);
+ _lastThrowMessage = await GetLastThrowMessage();
+ await InvokeAsync(StateHasChanged);
}
private void UpdateStats()
diff --git a/src/Koogle.Web/Components/Pages/Admin/GifManagement.razor b/src/Koogle.Web/Components/Pages/Admin/GifManagement.razor
index 4a62ac6..c2978c9 100644
--- a/src/Koogle.Web/Components/Pages/Admin/GifManagement.razor
+++ b/src/Koogle.Web/Components/Pages/Admin/GifManagement.razor
@@ -63,13 +63,14 @@
+
@if (context.ContentType.StartsWith("image/"))
{
-
+
}
else
{
-
+
}
@@ -80,7 +81,7 @@
@foreach (var evt in GetAssignedEvents(context.AssignedEvents))
{
- @(_ = Term.GetThrowEventName(evt).Result)
+ @GetEventName(evt)
}
@@ -245,6 +246,7 @@
private bool _isLoading = true;
private string? _error;
private int _pendingCount => _gifs.Count(g => g.IsPendingApproval);
+ private Dictionary _eventNames = new();
protected override async Task OnInitializedAsync()
{
@@ -259,6 +261,7 @@
var clubId = ClubContext.ClubId;
_gifs = (await GifService.GetByClubAsync(clubId, includePending: true)).ToList();
_tokens = (await GifService.GetSubmissionTokensByClubAsync(clubId)).ToList();
+ await LoadEventNames();
}
catch (Exception ex)
{
@@ -267,6 +270,17 @@
finally
{
_isLoading = false;
+ StateHasChanged();
+ }
+ }
+
+ private async Task LoadEventNames()
+ {
+ var eventTypes = new[] { ThrowEventType.Strike, ThrowEventType.Circle, ThrowEventType.Bell,
+ ThrowEventType.Gutter, ThrowEventType.NoWood, ThrowEventType.Cleared };
+ foreach (var evt in eventTypes)
+ {
+ _eventNames[evt] = await Term.GetThrowEventName(evt);
}
}
@@ -516,6 +530,9 @@
return result;
}
+ private string GetEventName(ThrowEventType type) =>
+ _eventNames.TryGetValue(type, out var name) ? name : type.ToString();
+
private static Color GetEventColor(ThrowEventType type) => type switch
{
ThrowEventType.Strike => Color.Success,