From 0640bbe3953e4dae0cab8ae7b9807b6221467d17 Mon Sep 17 00:00:00 2001 From: Jake Mannens Date: Mon, 4 Sep 2023 08:45:06 +1000 Subject: Added progressive loading to Gallery --- Pages/Gallery.razor | 103 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 78 insertions(+), 25 deletions(-) (limited to 'Pages') diff --git a/Pages/Gallery.razor b/Pages/Gallery.razor index 669ac28..241bed0 100644 --- a/Pages/Gallery.razor +++ b/Pages/Gallery.razor @@ -4,12 +4,13 @@ @inject ITagService tagService @inject ISearchService searchService @inject IUserService userService +@inject IJSRuntime jsRuntime @implements IDisposable @Title
- @foreach(var media in Media) { + @foreach(var media in displayMedia) { // Precalculate thumbnail size to help the browser // lay out the images during initial page load int width = media.Width * 200 / media.Height; @@ -19,6 +20,21 @@ }
+
+ + + @code { [Parameter] [SupplyParameterFromQuery(Name = "q")] @@ -28,6 +44,8 @@ [SupplyParameterFromQuery] public bool Ingest { get; set; } = false; + public const int PageSize = 50; + private string Title { get { if(Query is null) @@ -37,42 +55,75 @@ } } - private Media[] Media; + private List displayMedia; + private Media[] queryResult; + private IEnumerator mediaEnumerator; protected override void OnInitialized() => userService.ShowNsfwChanged += ShowNsfwChanged; protected override void OnParametersSet() => LoadMedia(); + protected override void OnAfterRender(bool firstRender) { + if(firstRender) + jsRuntime.InvokeVoidAsync( + "registerScrollObserver", + DotNetObjectReference.Create(this)); + } + private void LoadMedia() { using var db = dbFactory.CreateDbContext(); - IEnumerable media = db.Media - .Include(m => m.Tags) - .OrderByDescending(m => m.ObjectId) - .ToArray(); + if(Query is not null) { + queryResult = searchService.Search(Query) + .OrderByDescending(m => m.ObjectId) + .ToArray(); + } else { + queryResult = db.Media + .Include(m => m.Tags) + .OrderByDescending(m => m.ObjectId) + .ToArray(); + } - if(Query is not null) - media = searchService.Search(Query) - .OrderByDescending(m => m.ObjectId); + mediaEnumerator = FilterMedia(queryResult).GetEnumerator(); - if(Ingest) - media = media - .AsEnumerable() - .Where(m => m.IsIngest); + displayMedia = new(); - // Filter both NSFW AND ingest images if we're not showing NSFW - if(!userService.ShowNsfw) { - var nsfwTags = tagService.TagsThatImply(HBContext.NsfwTag) - .Select(td => td.ObjectId) - .ToArray(); - media = media - .AsEnumerable() - .Where(m => !m.Tags.Select(t => t.TagDefinitionId).Intersect(nsfwTags).Any()) - .Where(m => !m.IsIngest); - } + LoadMore(); + } + + [JSInvokable("LoadMore")] + public void LoadMore() { + for(int i = 0; i < PageSize; i++) { + if(!mediaEnumerator.MoveNext()) + break; + displayMedia.Add(mediaEnumerator.Current); + } + StateHasChanged(); + } + + private IEnumerable FilterMedia(IEnumerable media) { + var nsfwTags = tagService.TagsThatImply(HBContext.NsfwTag) + .Select(td => td.ObjectId) + .ToArray(); + + using var enumerator = media.GetEnumerator(); - Media = media.ToArray(); + while(true) { + bool success = enumerator.MoveNext(); + if(!success) + break; + Media? m = enumerator.Current; + + if(!userService.ShowNsfw) + if(m.Tags.Select(t => t.TagDefinitionId).Intersect(nsfwTags).Any() || m.IsIngest) + continue; + + if(m.IsIngest != Ingest) + continue; + + yield return m; + } } private async void ShowNsfwChanged(object? sender, bool showNsfw) { @@ -82,6 +133,8 @@ }); } - public void Dispose() => + public void Dispose() { + mediaEnumerator.Dispose(); userService.ShowNsfwChanged -= ShowNsfwChanged; + } } -- cgit v1.3