diff options
| author | Jake Mannens <jake@asger.xyz> | 2026-05-25 01:06:59 +1000 |
|---|---|---|
| committer | Jake Mannens <jake@asger.xyz> | 2026-06-11 01:13:32 +1000 |
| commit | a932b1bcb946bd70a5eb3e8fe1857fb74210a76b (patch) | |
| tree | c3377cb963026e68bd29e34a21a6d319f378dee7 /Pages | |
| parent | 96d44f2947fd3ebef78411f65b09bbd2110d215f (diff) | |
Re-implemented existing features via the API
Diffstat (limited to 'Pages')
| -rw-r--r-- | Pages/Component/AboutDialog.razor | 44 | ||||
| -rw-r--r-- | Pages/Component/MediaTagTable.razor | 158 | ||||
| -rw-r--r-- | Pages/Component/TagSelectDialog.razor | 131 | ||||
| -rw-r--r-- | Pages/Component/Titlebar.razor | 7 | ||||
| -rw-r--r-- | Pages/TagDefinitions.razor | 77 | ||||
| -rw-r--r-- | Pages/ViewMedia.razor | 145 |
6 files changed, 316 insertions, 246 deletions
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<HBContext> dbFactory - * @inject IHostingEnvironment hostingEnvironment - *@ +@using Microsoft.AspNetCore.Components.WebAssembly.Hosting +@using System.Reflection +@inject IWebAssemblyHostEnvironment hostEnvironment +@inject HBSession hb @implements IDialog <Dialog @ref=dialog> @@ -676,10 +674,11 @@ </div> <a href="https://gitlab.com/plasmicplexus/HyperBooru-Server" target="_blank">Source</a> <div id="progressContainer"> - @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"); <p id="progress">Untagged: @($"{untagged}/{total} ({percent}%)")</p> } <ProgressBar @ref=progressBar /> @@ -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 -<table class="data-table"> - <tr> - <th>Namespace</th> - <th>Tag Name</th> - <th></th> - </tr> - @foreach(var e in tagDefs) { - <tr> - <td> - @if(e.isImplicit) { - <i>@e.tagDef.Namespace</i> - } else { - @e.tagDef.Namespace - } - </td> - <td> - <a href="/Gallery?t=@(e.tagDef.TagDefinitionId)" class="nondecorated"> - @if(e.isImplicit) { - <i>@e.tagDef.Name</i> - } else { - @e.tagDef.Name - } - </a> - </td> - <td> - @if(!e.isImplicit) { - <a href="javascript:;" @onclick=@(() => Delete(e.tagDef))>Delete</a> - } else { - <a href="javascript:;" @onclick=@(() => MakeExplicit(e.tagDef))>Make Explicit</a> - } - </td> - </tr> - } -</table> +<LoadableContent T="List<TagTableEntry>" DataSource=LoadTagDefs @ref=tagContent> + <LoadingState> + <p><i>Loading...</i></p> + </LoadingState> + <ErrorState> + <p><i>Unable to fetch tags for this item!</i></p> + </ErrorState> + <LoadedState> + <table class="data-table"> + <tr> + <th>Namespace</th> + <th>Tag Name</th> + <th></th> + </tr> + @{ + var tags = tagContent.Data.Where(td => td.TagDefinition.Source == TagSource.UserTag); + } + @foreach(var e in tags) { + <tr> + <td> + @if(e.IsImplicit) { + <i>@e.TagDefinition.Namespace</i> + } else { + @e.TagDefinition.Namespace + } + </td> + <td> + <a href="/Gallery?t=@(e.TagDefinition.TagDefinitionId)" class="nondecorated"> + @if(e.IsImplicit) { + <i>@e.TagDefinition.Name</i> + } else { + @e.TagDefinition.Name + } + </a> + </td> + <td> + @if(!e.IsImplicit) { + <a href="javascript:;" @onclick=@(() => Delete(e.TagDefinition))>Delete</a> + } else { + <a href="javascript:;" @onclick=@(() => MakeExplicit(e.TagDefinition))>Make Explicit</a> + } + </td> + </tr> + } + </table> + </LoadedState> +</LoadableContent> @code { - [Parameter] - public Guid MediaId { get; set; } + [Parameter] + public Guid MediaId { get; set; } - private (TagDefinition tagDef, bool isImplicit)[] tagDefs = []; + private LoadableContent<List<TagTableEntry>> 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<List<TagTableEntry>> 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 -<link rel="stylesheet" href="@(nameof(HyperBooru)).styles.css"/> - <Dialog Title=@(Title ?? "Select one or more tag(s)") @ref=dialog> - <input - type="text" - placeholder="Search" - autocorrect="off" - autocapitalize="off" - autocomplete="off" - @ref=queryInput - @oninput=QueryInput - @onkeypress=QueryKey - value=@query/> - <div class="tag-definitions"> - @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 - }); -@* - <input - type="checkbox" - id="tagDef-@tagDefinitions[i].tagDefinition.Guid" - @bind=tagDefinitions[local].selected /> - <label - for="tagDef-@tagDefinitions[i].tagDefinition.Guid" - title=@title> - @tagDefinitions[i].tagDefinition.Name - </label> -*@ - } - </div> + @switch(state) { + case ComponentState.Loading: + <p><i>Loading...</i></p> + break; + case ComponentState.Error: + break; + case ComponentState.Loaded: + <input + type="text" + placeholder="Search" + autocorrect="off" + autocapitalize="off" + autocomplete="off" + @ref=queryInput + @oninput=QueryInput + @onkeypress=QueryKey + value=@query/> + <div class="tag-definitions"> + @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 + }); + <input + type="checkbox" + id="tagDef-@tagDefinitions[i].tagDefinition.TagDefinitionId" + @bind=tagDefinitions[local].selected /> + <label + for="tagDef-@tagDefinitions[i].tagDefinition.TagDefinitionId" + title=@title> + @tagDefinitions[i].tagDefinition.Name + </label> + } + </div> + break; + } <ButtonContainer> <button @onclick=@(() => dialog.Hide()) class="secondary">Cancel</button> - <button @onclick=@(() => Submit())>Accept</button> + @if(state == ComponentState.Loaded) { + <button @onclick=@(() => Submit())>Accept</button> + } </ButtonContainer> </Dialog> @@ -57,19 +65,21 @@ public EventCallback<TagDefinition[]> OnSubmit { get; set; } public TagDefinition[] SelectedTags { get; set; } = - Array.Empty<TagDefinition>(); + Array.Empty<TagDefinition>(); 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<int>(); + Guid[] nsfwTags = Array.Empty<Guid>(); // 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<TagDefinition, bool>( - // 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<TagDefinition, bool>( + 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 @@ <a class="desktop" href="/TagDefinitions">Tags</a> <a class="desktop" href="/Gallery?ingest=true">Ingest</a> <a class="desktop" href="/Upload">Upload</a> - @* <a class="desktop" href="javascript:;" @onclick=@(() => aboutDialog.Show())>About</a> *@ - <a class="desktop" href="javascript:;">About</a> + <a class="desktop" href="javascript:;" @onclick=@(() => aboutDialog.Show())>About</a> <p class="desktop" id="nsfw-label">NSFW</p> <div id="nsfw-switch" class="desktop"> @@ -63,7 +62,7 @@ </form> <a class="desktop" href="javascript:logout();">Logout</a> </div> - @* <AboutDialog @ref=aboutDialog/> *@ + <AboutDialog @ref=aboutDialog/> } else { <div id="navbar"> <h2>Login</h2> @@ -84,7 +83,7 @@ } @code { - // private AboutDialog aboutDialog; + private AboutDialog aboutDialog; public string Username { get; set; } = ""; public string Password { get; set; } = ""; diff --git a/Pages/TagDefinitions.razor b/Pages/TagDefinitions.razor index 7ce5400..b9f90d6 100644 --- a/Pages/TagDefinitions.razor +++ b/Pages/TagDefinitions.razor @@ -5,6 +5,7 @@ * @inject IUserService userService * @implements IDisposable *@ +@inject HBSession hb <PageTitle>Tag Definitions</PageTitle> @@ -24,28 +25,27 @@ <th></th> </tr> @foreach(var tagDef in tagDefinitions.Where(td => td.Namespace == ns)) { - @* <tr data-guid="@tagDef.Guid"> *@ - <tr> + <tr data-guid="@tagDef.TagDefinitionId"> <td>@tagDef.Alias</td> <td> -@* - <a href="/Gallery?t=@tagDef.Guid" class="nondecorated"> + <a href="/Gallery?t=@tagDef.TagDefinitionId" class="nondecorated"> @tagDef.Name </a> -*@ </td> <td> <i> @{ - // var implicitTags = tagDef.ImplicitTags - // .Where(td => td.Source == TagSource.UserTag); - // foreach(var tag in implicitTags) { - // <a href="/Gallery?t=@tag.Guid" class="nondecorated"> - // @tag.Name - // </a> - // if(tag != implicitTags.Last()) - // @(", ") - // } + var implicitTags = tagDefinitions + .IntersectBy(tagDef.ImplicitTags, td => td.TagDefinitionId) + .OrderBy(td => td.Name); + // .Where(td => td.Source == TagSource.UserTag); + foreach(var tag in implicitTags) { + <a href="/Gallery?t=@tag.TagDefinitionId" class="nondecorated"> + @tag.Name + </a> + if(tag != implicitTags.Last()) + @(", ") + } } </i> </td> @@ -97,37 +97,38 @@ private TagDefinition[] tagDefinitions; - private string?[] tagNamespaces; + private string[] tagNamespaces = Array.Empty<string>(); // protected override void OnInitialized() => // userService.UserSessionState.OnStateChange += ShowNsfwChanged; protected override void OnParametersSet() => - LoadTags(); + LoadTagsAsync(); + + private async void LoadTagsAsync() { + bool showNsfw = true; - private void LoadTags() { - // int[] nsfwTags = Array.Empty<int>(); + Guid[] nsfwTags = Array.Empty<Guid>(); // if(!userService.UserSessionState.ShowNsfw) // nsfwTags = tagService.TagsThatImply(HBContext.NsfwTag) // .Select(td => td.ObjectId) // .ToArray(); - // tagDefinitions = dbFactory.CreateDbContext().TagDefinitions - // .Include(td => td.ImplicitTags) - // .Where(td => td.Source == TagSource.UserTag) - // .OrderBy(td => td.Namespace) - // .ThenBy(td => td.Name) - // .AsEnumerable() - // .Where(td => userService.UserSessionState.ShowNsfw || !td.ImplicitTags - // .IntersectBy(nsfwTags, td => td.ObjectId) - // .Any()) - // .ToArray(); + tagDefinitions = (await hb.Tag.GetTagDefinitionAsync()) + // TODO: Limit shown tags to user-tags + //.Where(td => td.Source == TagSource.UserTag) + .OrderBy(td => td.Namespace) + .ThenBy(td => td.Name) + .Where(td => showNsfw || !td.ImplicitTags.Intersect(nsfwTags).Any()) + .ToArray(); + + tagNamespaces = tagDefinitions + .Select(td => td.Namespace) + .Order() + .Distinct() + .ToArray(); - // tagNamespaces = tagDefinitions - // .Select(td => td.Namespace) - // .Order() - // .Distinct() - // .ToArray(); + await InvokeAsync(() => StateHasChanged()); } private void PromptToDelete(TagDefinition toDelete) { @@ -141,7 +142,7 @@ // tagService.DeleteTagDefinition(toDelete); // deleteTagDialog.Hide(); - // LoadTags(); + // LoadTagsAsync(); // StateHasChanged(); } @@ -153,7 +154,7 @@ } private void TagUpdated(object? sender, EventArgs e) { - LoadTags(); + LoadTagsAsync(); StateHasChanged(); } @@ -169,7 +170,7 @@ return; // tagService.SetImplicitTags(toEditImplicit, tagDefs); - LoadTags(); + LoadTagsAsync(); StateHasChanged(); } @@ -178,13 +179,13 @@ // tagService.AddImplicitTag(tagDef.Guid, HBContext.NsfwTag); // else // tagService.RemoveImplicitTag(tagDef.Guid, HBContext.NsfwTag); - // LoadTags(); + // LoadTagsAsync(); // StateHasChanged(); } // private async void ShowNsfwChanged(UserSessionState userSessionState) => // await InvokeAsync(() => { - // LoadTags(); + // LoadTagsAsync(); // StateHasChanged(); // }); diff --git a/Pages/ViewMedia.razor b/Pages/ViewMedia.razor index e210e79..d44b430 100644 --- a/Pages/ViewMedia.razor +++ b/Pages/ViewMedia.razor @@ -1,9 +1,9 @@ @page "/ViewMedia" -@* @using HyperBooru.Util*@ +@inject ISourceService sourceService @inject HBSession hb @inject IJSRuntime jsRuntime -<PageTitle>@title</PageTitle> +<PageTitle>@Title</PageTitle> <script suppress-warning="BL9992"> function toggleSidebar() { @@ -62,8 +62,7 @@ <p>Title: <i>@(media?.ShortDescription ?? "None")</i></p> <p class="newlines">Description:<br/><i>@(media?.LongDescription ?? "None")</i></p> } -@* - <p>Resolution: @(media.CurrentUploadedFile.Width)x@(media.CurrentUploadedFile.Height)</p> + @*<p>Resolution: @(media.CurrentUploadedFile.Width)x@(media.CurrentUploadedFile.Height)</p>*@ <p class="heading">Upload history</p> <hr/> <table id="uploaded-files" class="data-table"> @@ -75,36 +74,45 @@ <th>Size</th> <th>Original Checksum</th> </tr> - @foreach(var file in media.UploadedFiles.OrderByDescending(uf => uf.UploadTime)) { - string? sourceUrl = null; - if(file.Filename is not null) - sourceUrl = sourceService.GetUrlFromFilename(file.Filename); - <tr> - <td title=@file.CreateTime?.ToString()> - @(file.CreateTime?.ToString("d") ?? "N/A") - </td> - <td title=@file.LastWriteTime?.ToString()> - @(file.LastWriteTime?.ToString("d") ?? "N/A") - </td> - <td title=@file.UploadTime>@(file.UploadTime.ToString("d"))</td> - <td title=@(file.Path is not null ? $"{file.Path.Replace('\\', '/')}/{file.Filename}" : file.Filename)> - @if(sourceUrl is not null) { - <a class="nondecorated" target="_blank" href=@sourceUrl>@file.Filename</a> - } else { - @file.Filename - } - </td> - <td title=@file.Length>@file.Length.ToBytesSI()</td> - <td - title=@(file.Checksum + (file.ChecksumVerified ? " (verified)" : "")) - class=@(file.ChecksumVerified ? "verified" : null)> - - @file.Checksum.Substring(0, 8) - </td> - </tr> - } + <LoadableContent T="List<UploadedFile>" DataSource=LoadUploadedFiles @ref=uploadedFilesContent> + <LoadingState> + <p><i>Loading...</i></p> + </LoadingState> + <ErrorState> + <p><i>Unable to fetch file info for this item!</i></p> + </ErrorState> + <LoadedState> + @foreach(var file in uploadedFilesContent.Data!) { + string? sourceUrl = null; + if(file.Filename is not null) + sourceUrl = sourceService.GetUrlFromFilename(file.Filename); + <tr> + <td title=@file.CreateTime?.ToString()> + @(file.CreateTime?.ToString("d") ?? "N/A") + </td> + <td title=@file.LastWriteTime?.ToString()> + @(file.LastWriteTime?.ToString("d") ?? "N/A") + </td> + <td title=@file.UploadTime>@(file.UploadTime.ToString("d"))</td> + <td title=@(file.Path is not null ? $"{file.Path.Replace('\\', '/')}/{file.Filename}" : file.Filename)> + @if(sourceUrl is not null) { + <a class="nondecorated" target="_blank" href=@sourceUrl>@file.Filename</a> + } else { + @file.Filename + } + </td> + <td title=@file.Length>@file.Length.ToBytesSI()</td> + <td + title=@(file.Checksum + (file.ChecksumVerified ? " (verified)" : "")) + class=@(file.ChecksumVerified ? "verified" : null)> + + @file.Checksum.Substring(0, 8) + </td> + </tr> + } + </LoadedState> + </LoadableContent> </table> -*@ </div> <div id="metadata-tags"> <p class="heading">Tags</p> @@ -114,8 +122,7 @@ </div> <div id="button-container"> <ButtonContainer> -@* - <button @onclick=@(() => deleteDialog.Show()) class="warning" data-keyboard-shortcut="d"> + <button @onclick=@(() => deleteDialog.Show()) class="warning" data-keyboard-shortcut="d"> <img src="/images/trash.svg"/> <p><u>D</u>elete</p> </button> @@ -127,7 +134,6 @@ <img src="/images/book.svg"/> <p>View <u>O</u>CR</p> </button> -*@ @if(infoEditMode) { @* <button @onclick=@(() => ApplyInfoEdit(false)) class="secondary"> @@ -168,7 +174,6 @@ </div> </div> -@* <Dialog Title="Delete this media?" @ref=deleteDialog> <ButtonContainer> <button @onclick=@(() => deleteDialog.Hide()) class="secondary">Cancel</button> @@ -177,11 +182,13 @@ </Dialog> <Dialog Title="OCR Data" @ref=ocrDialog> - @if(media.OcrData is null) { + @*@if(media.OcrData is null) {*@ <p><center>This media item hasn't been scanned yet!</center></p> +@* } else { <code style="max-height:400px;">@media.OcrData?.Text</code> } +*@ <ButtonContainer> <button @onclick=@(() => ocrDialog.Hide())>Close</button> </ButtonContainer> @@ -191,14 +198,15 @@ Title="Select one or more tag(s) to add" OnSubmit=AddTags @ref=tagDialog/> -*@ @code { [Parameter] [SupplyParameterFromQuery(Name = "m")] public Guid MediaId { get; set; } - private ApiModels.Media media; + private ApiModels.Media? media; + + private LoadableContent<List<UploadedFile>> uploadedFilesContent; private string title; @@ -207,9 +215,9 @@ private string? longDescription; private MediaTagTable mediaTagTable; - // private Dialog deleteDialog; - // private Dialog ocrDialog; - // private TagSelectDialog tagDialog; + private Dialog deleteDialog; + private Dialog ocrDialog; + private TagSelectDialog tagDialog; private ElementReference shortDescriptionInput; @@ -223,24 +231,20 @@ private async void LoadMedia() { media = await hb.Media.GetAsync(MediaId); - // using var db = dbFactory.CreateDbContext(); - // media = db.Media - // .Include(m => m.Tags) - // .ThenInclude(t => t.TagDefinition) - // .Include(m => m.CurrentUploadedFile) - // .Include(m => m.UploadedFiles) - // .Include(m => m.OcrData) - // .First(m => m.Guid == MediaId); + await InvokeAsync(() => StateHasChanged()); + } - // title = media.DisplayName ?? "Media View"; - // InvokeAsync(() => StateHasChanged()); + private async Task<List<UploadedFile>> LoadUploadedFiles() { + return (await hb.Media.GetUploadedFilesAsync(MediaId)) + .OrderByDescending(uf => uf.UploadTime) + .ToList(); } - // private void AddTags(TagDefinition[] tagDefs) { - // foreach(var tagDef in tagDefs) - // tagService.AddTag(media, tagDef); - // mediaTagTable.Refresh(); - // } + private void AddTags(TagDefinition[] tagDefs) { + // foreach(var tagDef in tagDefs) + // tagService.AddTag(media, tagDef); + // mediaTagTable.Refresh(); + } private async void SetIngest(bool ingest) { // mediaService.SetIngest(media, ingest); @@ -252,6 +256,23 @@ await jsRuntime.InvokeVoidAsync("history.back"); } + private string Title { + get { + if(media is null) + return "View Media"; + + if(media.ShortDescription is not null) + return media.ShortDescription; + + if(uploadedFilesContent.Data is null) + return $"Media ({media.MediaId.ToString().ToUpper().Substring(0, 8)})"; + + return uploadedFilesContent.Data + .OrderBy(f => f.UploadTime) + .FirstOrDefault()?.Filename ?? media.MediaId.ToString().ToUpper(); + } + } + private bool InfoEditMode { get => infoEditMode; set { @@ -271,8 +292,8 @@ // infoEditMode = false; // } - // private async void DeleteMedia() { - // mediaService.Delete(media); - // await jsRuntime.InvokeVoidAsync("history.back"); - // } + private async void DeleteMedia() { + // mediaService.Delete(media); + // await jsRuntime.InvokeVoidAsync("history.back"); + } } |
