From a932b1bcb946bd70a5eb3e8fe1857fb74210a76b Mon Sep 17 00:00:00 2001 From: Jake Mannens Date: Mon, 25 May 2026 01:06:59 +1000 Subject: Re-implemented existing features via the API --- Pages/Component/AboutDialog.razor | 44 +++++----- Pages/Component/MediaTagTable.razor | 158 +++++++++++++++++++++------------- Pages/Component/TagSelectDialog.razor | 131 ++++++++++++++++------------ Pages/Component/Titlebar.razor | 7 +- Pages/TagDefinitions.razor | 79 ++++++++--------- Pages/ViewMedia.razor | 147 +++++++++++++++++-------------- 6 files changed, 318 insertions(+), 248 deletions(-) (limited to 'Pages') diff --git a/Pages/Component/AboutDialog.razor b/Pages/Component/AboutDialog.razor index fa7b1ca..888040e 100644 --- a/Pages/Component/AboutDialog.razor +++ b/Pages/Component/AboutDialog.razor @@ -1,9 +1,7 @@ -@using System.Reflection -@* - * @using Microsoft.AspNetCore.Hosting - * @inject IDbContextFactory dbFactory - * @inject IHostingEnvironment hostingEnvironment - *@ +@using Microsoft.AspNetCore.Components.WebAssembly.Hosting +@using System.Reflection +@inject IWebAssemblyHostEnvironment hostEnvironment +@inject HBSession hb @implements IDialog @@ -676,10 +674,11 @@ Source
- @if(progress.HasValue) { - var untagged = progress.Value.Untagged.ToString("N0"); - var total = progress.Value.Total.ToString("N0"); - var percent = (progress.Value.Untagged * 100f / progress.Value.Total).ToString("f1"); + @if(ingestStatistics is not null) { + var untagged = ingestStatistics.UntaggedMediaCount.ToString("N0"); + var total = ingestStatistics.TotalMediaCount.ToString("N0"); + var percent = + (ingestStatistics.UntaggedMediaCount * 100f / ingestStatistics.TotalMediaCount).ToString("f1");

Untagged: @($"{untagged}/{total} ({percent}%)")

} @@ -694,23 +693,15 @@ private ProgressBar progressBar; - private (long Untagged, long Total)? progress; + private IngestStatistics? ingestStatistics; public bool Visible { get => dialog.Visible; set { dialog.Visible = value; - if(value) { - // using var db = dbFactory.CreateDbContext(); - // progress = ( - // Untagged: db.Media - // .Where(m => m.Tags.Any(t => t.TagDefinition.ObjectId == (int) HBObjectId.IngestTag)) - // .Count(), - // Total: db.Media.Count() - // ); - // progressBar.Progress = (float) progress.Value!.Untagged / (float) progress.Value!.Total; - // InvokeAsync(() => StateHasChanged()); - } + InvokeAsync(() => StateHasChanged()); + if(value) + LoadProgressAsync(); } } @@ -731,8 +722,15 @@ #if DEBUG return "(Development)"; #else - return hostingEnvironment.IsDevelopment() ? "(Development)" : null; + return hostEnvironment.IsDevelopment() ? "(Development)" : null; #endif } } + + private async void LoadProgressAsync() { + ingestStatistics = await hb.Statistics.GetIngestStatisticsAsync(); + progressBar.Progress = + (float) ingestStatistics.UntaggedMediaCount / (float) ingestStatistics.TotalMediaCount; + await InvokeAsync(() => StateHasChanged()); + } } diff --git a/Pages/Component/MediaTagTable.razor b/Pages/Component/MediaTagTable.razor index 0524739..5e60d20 100644 --- a/Pages/Component/MediaTagTable.razor +++ b/Pages/Component/MediaTagTable.razor @@ -1,75 +1,109 @@ @inject HBSession hb - - - - - - - @foreach(var e in tagDefs) { - - - - - - } -
NamespaceTag Name
- @if(e.isImplicit) { - @e.tagDef.Namespace - } else { - @e.tagDef.Namespace - } - - - @if(e.isImplicit) { - @e.tagDef.Name - } else { - @e.tagDef.Name - } - - - @if(!e.isImplicit) { - Delete(e.tagDef))>Delete - } else { - MakeExplicit(e.tagDef))>Make Explicit - } -
+ + +

Loading...

+
+ +

Unable to fetch tags for this item!

+
+ + + + + + + + @{ + var tags = tagContent.Data.Where(td => td.TagDefinition.Source == TagSource.UserTag); + } + @foreach(var e in tags) { + + + + + + } +
NamespaceTag Name
+ @if(e.IsImplicit) { + @e.TagDefinition.Namespace + } else { + @e.TagDefinition.Namespace + } + + + @if(e.IsImplicit) { + @e.TagDefinition.Name + } else { + @e.TagDefinition.Name + } + + + @if(!e.IsImplicit) { + Delete(e.TagDefinition))>Delete + } else { + MakeExplicit(e.TagDefinition))>Make Explicit + } +
+
+
@code { - [Parameter] - public Guid MediaId { get; set; } + [Parameter] + public Guid MediaId { get; set; } - private (TagDefinition tagDef, bool isImplicit)[] tagDefs = []; + private LoadableContent> tagContent; - protected override void OnInitialized() => LoadTagDefs(); + private void Delete(TagDefinition tagDef) { + // tagService.RemoveTag(Media.Guid, tagDef.Guid); + // Refresh(); + } - public void Refresh() { - LoadTagDefs(); - // StateHasChanged(); - } + private async Task> LoadTagDefs() { + var itemTags = await hb.Media.GetTagsAsync(MediaId); + var allTags = await hb.Tag.GetTagDefinitionAsync(); - private void Delete(TagDefinition tagDef) { - // tagService.RemoveTag(Media.Guid, tagDef.Guid); - // Refresh(); - } + var tags = itemTags + .Select(td => new TagTableEntry() { + TagDefinition = td, + IsImplicit = false + }) + .ToList(); - private async void LoadTagDefs() { - var tags = await hb.Media.GetTagsAsync(MediaId); + while(true) { + var toAdd = allTags + .IntersectBy(tags + .SelectMany(t => t.TagDefinition.ImplicitTags), td => td.TagDefinitionId) + .Where(td => !tags + .Select(t => t.TagDefinition.TagDefinitionId) + .Contains(td.TagDefinitionId)); + if(toAdd.Count() == 0) + break; + tags.AddRange(toAdd.Select(td => new TagTableEntry() { + TagDefinition = td, + IsImplicit = true + })); + } - tagDefs = tags.Select(td => (tagDef: td, isImplicit: false)).ToArray(); + return tags + .OrderBy(td => td.IsImplicit) + .ThenBy(td => td.TagDefinition.Namespace) + .ThenBy(td => td.TagDefinition.Name) + .ToList(); + } - await InvokeAsync(() => StateHasChanged()); + private async Task MakeExplicit(TagDefinition tagDef) { + // TODO: Add error handling + await hb.Media.AddTagsAsync(MediaId, [ tagDef.TagDefinitionId ]); + //var index = + // tagDefs.IndexOf(tagDefs.First(td => td.tagDef.TagDefinitionId == tagDef.TagDefinitionId)); + //tagDefs[index].isImplicit = false; + tagContent.Load(); + await InvokeAsync(() => StateHasChanged()); + } - // using var db = dbFactory.CreateDbContext(); - // var media = db.Media.First(m => m.ObjectId == Media.ObjectId); - - // tagDefs = tagService.GetAllTags(Media) - // .Where(e => e.tagDefinition.Source == TagSource.UserTag) - // .ToArray(); - } - - private void MakeExplicit(TagDefinition tagDef) { - // tagService.AddTag(Media, tagDef); - // Refresh(); - } + private record TagTableEntry { + internal required TagDefinition TagDefinition { get; set; } + internal required bool IsImplicit { get; set; } + } } diff --git a/Pages/Component/TagSelectDialog.razor b/Pages/Component/TagSelectDialog.razor index 99321fe..5872ce7 100644 --- a/Pages/Component/TagSelectDialog.razor +++ b/Pages/Component/TagSelectDialog.razor @@ -3,49 +3,57 @@ * @inject ITagService tagService * @inject IUserService userService *@ +@inject HBSession hb @implements IDisposable @implements IDialog - - - -
- @for(int i = 0; i < tagDefinitions.Count(); i++) { - if(!MatchesQuery(tagDefinitions[i].tagDefinition)) - continue; - var local = i; - var ns = tagDefinitions[i].tagDefinition.Namespace; - var alias = tagDefinitions[i].tagDefinition.Alias; - var title = string.Join(" ", new[] { - ns, - alias is not null ? $"({alias})" : null - }); -@* - - -*@ - } -
+ @switch(state) { + case ComponentState.Loading: +

Loading...

+ break; + case ComponentState.Error: + break; + case ComponentState.Loaded: + +
+ @for(int i = 0; i < tagDefinitions.Count(); i++) { + if(!MatchesQuery(tagDefinitions[i].tagDefinition)) + continue; + var local = i; + var ns = tagDefinitions[i].tagDefinition.Namespace; + var alias = tagDefinitions[i].tagDefinition.Alias; + var title = string.Join(" ", new[] { + ns, + alias is not null ? $"({alias})" : null + }); + + + } +
+ break; + } - + @if(state == ComponentState.Loaded) { + + }
@@ -57,19 +65,21 @@ public EventCallback OnSubmit { get; set; } public TagDefinition[] SelectedTags { get; set; } = - Array.Empty(); + Array.Empty(); public bool Visible { get => visible; set { if(value) - LoadTags(); + LoadTagsAsync(); query = null; visible = dialog.Visible = value; } } - private (TagDefinition tagDefinition, bool selected)[] tagDefinitions; + private (TagDefinition tagDefinition, bool selected)[] tagDefinitions = []; + + private ComponentState state = ComponentState.Loading; // private HBContext db; @@ -85,32 +95,39 @@ protected override void OnInitialized() { // userService.UserSessionState.OnStateChange += ShowNsfwChanged; - LoadTags(); + LoadTagsAsync(); } - private void LoadTags() { + private async void LoadTagsAsync() { // db = dbFactory.CreateDbContext(); - // var selected = SelectedTags.Select(td => td.Guid); + var selected = SelectedTags.Select(td => td.TagDefinitionId); + + // TODO: Factor in whether show NSFW is actually selected + bool showNsfw = true; - // int[] nsfwTags = Array.Empty(); + Guid[] nsfwTags = Array.Empty(); // if(!userService.UserSessionState.ShowNsfw) // nsfwTags = tagService.TagsThatImply(HBContext.NsfwTag) // .Select(td => td.ObjectId) // .ToArray(); - // tagDefinitions = db.TagDefinitions - // .Include(td => td.ImplicitTags) - // .Where(td => td.Source == TagSource.UserTag) - // .OrderBy(td => td.Name) - // .AsEnumerable() - // .Where(td => userService.UserSessionState.ShowNsfw || !td.ImplicitTags - // .IntersectBy(nsfwTags, td => td.ObjectId) - // .Any()) - // .Select(td => new Tuple( - // td, - // selected.Contains(td.Guid)).ToValueTuple()) - // .ToArray(); + try { + tagDefinitions = (await hb.Tag.GetTagDefinitionAsync()) + // .Where(td => td.Source == TagSource.UserTag) + .OrderBy(td => td.Name) + .Where(td => showNsfw || !td.ImplicitTags.Intersect(nsfwTags).Any()) + .Select(td => new Tuple( + td, + selected.Contains(td.TagDefinitionId)).ToValueTuple()) + .ToArray(); + + state = ComponentState.Loaded; + } catch { + state = ComponentState.Error; + } + + await InvokeAsync(() => StateHasChanged()); } private void QueryInput(ChangeEventArgs e) { @@ -169,7 +186,7 @@ // return tagDef.Guid == singleTag.Guid; // return tagDef.Name.ToLower().Contains(query.ToLower()); - return false; + return true; } private async void Submit() { diff --git a/Pages/Component/Titlebar.razor b/Pages/Component/Titlebar.razor index 521fb46..65af89a 100644 --- a/Pages/Component/Titlebar.razor +++ b/Pages/Component/Titlebar.razor @@ -51,8 +51,7 @@ Tags Ingest Upload - @* aboutDialog.Show())>About *@ - About + aboutDialog.Show())>About

NSFW

@@ -63,7 +62,7 @@ Logout
- @* *@ + } else {