a fork of iceshrimp.net but a tweaked frontend to my personal liking. waow
fediverse social-media social iceshrimp fedi
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

[frontend/components] Fix JS interop being used before initialization on SingleNote Page

Lilian 67a8819a a8e35978

+25 -19
+25 -19
Iceshrimp.Frontend/Pages/SingleNote.razor
··· 21 21 @using Microsoft.AspNetCore.Authorization 22 22 @using Microsoft.AspNetCore.Components.Sections 23 23 @using Microsoft.Extensions.Localization 24 - @implements IDisposable 24 + @implements IAsyncDisposable 25 25 26 26 @if (_componentState == State.Loaded) 27 27 { ··· 138 138 { 139 139 <HeadTitle Text="@Loc["Loading"]"/> 140 140 141 - <div class="loading"><LoadingSpinner Scale="2" /></div> 141 + <div class="loading"> 142 + <LoadingSpinner Scale="2"/> 143 + </div> 142 144 } 143 145 @if (_componentState == State.NotFound) 144 146 { ··· 165 167 private SortedList<string, NoteResponse>? Descendants { get; set; } 166 168 private SortedList<string, NoteResponse>? Ascendants { get; set; } 167 169 private IJSInProcessObjectReference? Module { get; set; } 170 + private readonly Lazy<Task<IJSObjectReference>> _moduleTask; 168 171 private ElementReference RootNoteRef { get; set; } 169 172 private int _depth = 20; 170 173 private IDisposable? _locationChangingHandlerDisposable; ··· 175 178 private async Task Load() 176 179 { 177 180 Logger.LogTrace($"Opening NoteID: {NoteId}"); 181 + Module = (IJSInProcessObjectReference?)await _moduleTask.Value; 182 + Logger.LogInformation("Loaded Module"); 178 183 _componentState = State.Loading; 179 184 if (NoteId == null) 180 185 { ··· 261 266 } 262 267 263 268 // ReSharper disable once InconsistentNaming 264 - private ValueTask LocationChangeHandler(LocationChangingContext arg) 269 + private async ValueTask LocationChangeHandler(LocationChangingContext arg) 265 270 { 266 - SaveState(); 267 - return ValueTask.CompletedTask; 271 + await SaveState(); 268 272 } 269 273 270 - protected override async Task OnAfterRenderAsync(bool firstRender) 274 + public SingleNote() 271 275 { 272 - if (firstRender) 273 - { 274 - Module = (IJSInProcessObjectReference)await Js.InvokeAsync 275 - <IJSObjectReference>("import", "/Pages/SingleNote.razor.js"); 276 - } 276 + _moduleTask = new Lazy<Task<IJSObjectReference>>(() => 277 + Js.InvokeAsync<IJSObjectReference>( 278 + "import", 279 + "./Pages/SingleNote.razor.js") 280 + .AsTask()); 281 + } 277 282 283 + protected override void OnAfterRender(bool firstRender) 284 + { 278 285 if (_componentState == State.Loaded) 279 286 { 280 287 var state = StateSvc.SingleNote.GetState(NoteId!); ··· 332 339 } 333 340 } 334 341 335 - private void SaveState() 342 + private async Task SaveState() 336 343 { 337 344 if (NoteId == null || _componentState != State.Loaded) return; 338 - var scrollTop = (Module ?? throw new Exception("JS Interop used before init")) 339 - .Invoke 340 - <float>("GetScrollY"); 341 - var state = new SingleNoteState { ScrollTop = scrollTop }; 345 + var module = await _moduleTask.Value; 346 + var scrollTop = await module.InvokeAsync<float>("GetScrollY"); 347 + var state = new SingleNoteState { ScrollTop = scrollTop }; 342 348 StateSvc.SingleNote.SetState(NoteId, state); 343 349 } 344 - 345 - public void Dispose() 350 + 351 + public async ValueTask DisposeAsync() 346 352 { 347 - SaveState(); 353 + await SaveState(); 348 354 _locationChangingHandlerDisposable?.Dispose(); 349 355 StateSynchronizer.NoteDeleted -= OnNoteDeleted; 350 356 NoteStore.AnyNoteChanged -= OnNoteChanged;