diff --git a/DeepDrftPublic.Client/Layout/MainLayout.razor b/DeepDrftPublic.Client/Layout/MainLayout.razor index 8624e0c..6c5c444 100644 --- a/DeepDrftPublic.Client/Layout/MainLayout.razor +++ b/DeepDrftPublic.Client/Layout/MainLayout.razor @@ -45,7 +45,7 @@ @code { private const string DarkModeKey = "darkMode"; - private bool _isDarkMode = true; + private bool _isDarkMode = false; private PersistingComponentStateSubscription _persistingSubscription; [Inject] public required PersistentComponentState PersistentState { get; set; } diff --git a/DeepDrftPublic.Client/Pages/TracksView.razor.cs b/DeepDrftPublic.Client/Pages/TracksView.razor.cs index 71268a5..579ddb6 100644 --- a/DeepDrftPublic.Client/Pages/TracksView.razor.cs +++ b/DeepDrftPublic.Client/Pages/TracksView.razor.cs @@ -8,18 +8,35 @@ namespace DeepDrftPublic.Client.Pages; public partial class TracksView : ComponentBase, IDisposable { + private const string PersistKey = "tracks-page"; + [Inject] public required TracksViewModel ViewModel { get; set; } + [Inject] public required PersistentComponentState PersistentState { get; set; } [CascadingParameter] public required IStreamingPlayerService PlayerService { get; set; } private TrackDto? _selectedTrack = null; - private int _clickCount = 0; - private string _lifecycleStatus = "Not initialized"; private IStreamingPlayerService? _subscribedService; + private PersistingComponentStateSubscription _persistingSubscription; protected override async Task OnInitializedAsync() { - _lifecycleStatus = "OnInitializedAsync called"; - await SetPage(1); + // Carry the prerendered page across the prerender -> interactive (WASM) seam. + // 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>(PersistKey, out var restored) && restored is not null) + { + ViewModel.Page = restored; + ViewModel.PageNumber = restored.Page; + } + else + { + await SetPage(ViewModel.PageNumber); + } } protected override void OnParametersSet() @@ -51,21 +68,15 @@ 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!"; - StateHasChanged(); + PersistentState.PersistAsJson(PersistKey, ViewModel.Page); } + return Task.CompletedTask; } - private void TestInteractivity() - { - _clickCount++; - _lifecycleStatus = $"Button clicked {_clickCount} times - Interactivity working!"; - } - private async Task SetPage(int newPage) { var result = await ViewModel.TrackData.GetPage(newPage, ViewModel.PageSize, ViewModel.SortBy, ViewModel.IsDescending); @@ -89,16 +100,18 @@ public partial class TracksView : ComponentBase, IDisposable { await PlayerService.SelectTrack(track); } - + _selectedTrack = track; } public void Dispose() { + _persistingSubscription.Dispose(); + if (_subscribedService != null) { _subscribedService.StateChanged -= OnPlayerStateChanged; _subscribedService = null; } } -} \ No newline at end of file +} diff --git a/DeepDrftPublic/Components/App.razor b/DeepDrftPublic/Components/App.razor index 41adde5..c438bad 100644 --- a/DeepDrftPublic/Components/App.razor +++ b/DeepDrftPublic/Components/App.razor @@ -12,7 +12,7 @@ - +