@page "/" @page "/Gallery" @inject IDbContextFactory dbFactory @inject ITagService tagService @inject ISearchService searchService @inject IUserService userService @inject IJSRuntime jsRuntime @implements IDisposable @attribute [Authorize] @Title @if(Ingest && !userService.UserSessionState.ShowNsfw) {

Ingest feed is not available unless NSFW mode is enabled!

You must enable NSFW mode to continue...

}
@foreach(var media in displayMedia) { // Precalculate thumbnail size to help the browser // lay out the images during initial page load int width = (int) media.CurrentUploadedFile.Width! * 200 / (int) media.CurrentUploadedFile.Height!; }
@code { [Parameter] [SupplyParameterFromQuery(Name = "q")] public string? Query { get; set; } [Parameter] [SupplyParameterFromQuery] public bool Ingest { get; set; } = false; public const int PageSize = 50; private string Title { get { if(Query is null) return Ingest ? "Ingest Feed" : "Gallery"; else return "Search Results"; } } private List displayMedia; private Media[] queryResult; private IEnumerator mediaEnumerator; protected override void OnInitialized() => userService.UserSessionState.OnStateChange += 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(); if(Query is not null) { queryResult = searchService.Search(Query) .OrderByDescending(m => m.ObjectId) .ToArray(); } else { queryResult = db.Media .Include(m => m.Tags) .Include(m => m.CurrentUploadedFile) .OrderByDescending(m => m.ObjectId) .ToArray(); } mediaEnumerator = FilterMedia(queryResult).GetEnumerator(); displayMedia = new(); 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(); while(true) { bool success = enumerator.MoveNext(); if(!success) break; Media? m = enumerator.Current; if(!userService.UserSessionState.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(UserSessionState userSessionState) { await InvokeAsync(() => { LoadMedia(); StateHasChanged(); }); } public void Dispose() { mediaEnumerator.Dispose(); userService.UserSessionState.OnStateChange -= ShowNsfwChanged; } }