WASM State Fixes

This commit is contained in:
daniel-c-harvey
2026-06-06 09:59:43 -04:00
parent 75bf93c2bb
commit d055c2a548
3 changed files with 31 additions and 18 deletions
@@ -45,7 +45,7 @@
@code { @code {
private const string DarkModeKey = "darkMode"; private const string DarkModeKey = "darkMode";
private bool _isDarkMode = true; private bool _isDarkMode = false;
private PersistingComponentStateSubscription _persistingSubscription; private PersistingComponentStateSubscription _persistingSubscription;
[Inject] public required PersistentComponentState PersistentState { get; set; } [Inject] public required PersistentComponentState PersistentState { get; set; }
+27 -14
View File
@@ -8,18 +8,35 @@ namespace DeepDrftPublic.Client.Pages;
public partial class TracksView : ComponentBase, IDisposable public partial class TracksView : ComponentBase, IDisposable
{ {
private const string PersistKey = "tracks-page";
[Inject] public required TracksViewModel ViewModel { get; set; } [Inject] public required TracksViewModel ViewModel { get; set; }
[Inject] public required PersistentComponentState PersistentState { get; set; }
[CascadingParameter] public required IStreamingPlayerService PlayerService { get; set; } [CascadingParameter] public required IStreamingPlayerService PlayerService { get; set; }
private TrackDto? _selectedTrack = null; private TrackDto? _selectedTrack = null;
private int _clickCount = 0;
private string _lifecycleStatus = "Not initialized";
private IStreamingPlayerService? _subscribedService; private IStreamingPlayerService? _subscribedService;
private PersistingComponentStateSubscription _persistingSubscription;
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
_lifecycleStatus = "OnInitializedAsync called"; // Carry the prerendered page across the prerender -> interactive (WASM) seam.
await SetPage(1); // Without this, the WASM pass gets a fresh scoped ViewModel (Page == null),
// re-renders the skeleton, re-fetches, and replaces the gallery DOM a few
// seconds in — replaying TrackCard entrance animations. Mirror the dark-mode
// PersistentComponentState bridge: persist on the way out of prerender,
// restore on the interactive pass, and only fetch on a miss.
_persistingSubscription = PersistentState.RegisterOnPersisting(PersistTracks);
if (PersistentState.TryTakeFromJson<PagedResult<TrackDto>>(PersistKey, out var restored) && restored is not null)
{
ViewModel.Page = restored;
ViewModel.PageNumber = restored.Page;
}
else
{
await SetPage(ViewModel.PageNumber);
}
} }
protected override void OnParametersSet() protected override void OnParametersSet()
@@ -51,19 +68,13 @@ public partial class TracksView : ComponentBase, IDisposable
} }
} }
protected override async Task OnAfterRenderAsync(bool firstRender) private Task PersistTracks()
{ {
if (firstRender) if (ViewModel.Page is not null)
{ {
_lifecycleStatus = "OnAfterRenderAsync called - WebAssembly is active!"; PersistentState.PersistAsJson(PersistKey, ViewModel.Page);
StateHasChanged();
} }
} return Task.CompletedTask;
private void TestInteractivity()
{
_clickCount++;
_lifecycleStatus = $"Button clicked {_clickCount} times - Interactivity working!";
} }
private async Task SetPage(int newPage) private async Task SetPage(int newPage)
@@ -95,6 +106,8 @@ public partial class TracksView : ComponentBase, IDisposable
public void Dispose() public void Dispose()
{ {
_persistingSubscription.Dispose();
if (_subscribedService != null) if (_subscribedService != null)
{ {
_subscribedService.StateChanged -= OnPlayerStateChanged; _subscribedService.StateChanged -= OnPlayerStateChanged;
+1 -1
View File
@@ -12,7 +12,7 @@
<link href=@Assets["_content/MudBlazor/MudBlazor.min.css"] rel="stylesheet" /> <link href=@Assets["_content/MudBlazor/MudBlazor.min.css"] rel="stylesheet" />
<link rel="stylesheet" href="@Assets["DeepDrftPublic.styles.css"]"/> <link rel="stylesheet" href="@Assets["DeepDrftPublic.styles.css"]"/>
<link rel="stylesheet" href="@Assets["_content/DeepDrftShared.Client/styles/deepdrft-tokens.css"]" /> <link rel="stylesheet" href="@Assets["_content/DeepDrftShared.Client/styles/deepdrft-tokens.css"]" />
<link rel="stylesheet" href="styles/deepdrft-styles.css" /> <link rel="stylesheet" href="@Assets["styles/deepdrft-styles.css"]" />
<ImportMap /> <ImportMap />
<link rel="icon" type="image/ico" href="deepdrft-logo.ico" /> <link rel="icon" type="image/ico" href="deepdrft-logo.ico" />
<HeadOutlet @rendermode="InteractiveAuto" /> <HeadOutlet @rendermode="InteractiveAuto" />