diff options
| author | Jake Mannens <jake@asger.xyz> | 2026-03-17 03:04:36 +1100 |
|---|---|---|
| committer | Jake Mannens <jake@asger.xyz> | 2026-03-25 01:57:41 +1100 |
| commit | c751709b1b4fe6f16fd84647e8e071455e7b78d6 (patch) | |
| tree | 47734a083d888660606e6cf6cf158c93e69a9807 /Pages/TagDefinitions.razor | |
v0.1av0.1a
Diffstat (limited to 'Pages/TagDefinitions.razor')
| -rw-r--r-- | Pages/TagDefinitions.razor | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/Pages/TagDefinitions.razor b/Pages/TagDefinitions.razor new file mode 100644 index 0000000..e2e4df6 --- /dev/null +++ b/Pages/TagDefinitions.razor @@ -0,0 +1,187 @@ +@page "/TagDefinitions" +@inject IDbContextFactory<HBContext> dbFactory +@inject ITagService tagService +@inject IUserService userService +@implements IDisposable +@attribute [Authorize] + +<PageTitle>Tag Definitions</PageTitle> + +<div style="padding:var(--size-default-gap);"> + <ButtonContainer> + <button @onclick=PromptTagCreate data-keyboard-shortcut="c"><u>C</u>reate</button> + </ButtonContainer> + + <TabContainer @ref=tabContainer> + @foreach(var ns in tagNamespaces) { + <TabPane Title="@(ns ?? "Default")"> + <table id="tag-definitions" class="data-table"> + <tr> + <th>Alias</th> + <th>Name</th> + <th>Implicit Tags</th> + <th></th> + </tr> + @foreach(var tagDef in tagDefinitions.Where(td => td.Namespace == ns)) { + <tr data-guid="@tagDef.Guid"> + <td>@tagDef.Alias</td> + <td> + <a href="/Gallery?q=@tagDef.Name" 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?q=@tag.Name" class="nondecorated"> + @tag.Name + </a> + if(tag != implicitTags.Last()) + @(", ") + } + } + </i> + </td> + <td class="actions"> + <a href="javascript:;" @onclick=@(() => tagEditDialog.Show(tagDef))>Edit</a> + <a href="javascript:;" @onclick=@(() => PromptToDelete(tagDef))> + Delete + </a> + <a href="javascript:;" @onclick=@(() => PromptImplicitTags(tagDef))> + Implicit Tags + </a> + @if(tagDef.ImplicitTags.Select(td => td.Guid).Contains(HBContext.NsfwTag)) { + <a href="javascript:;" @onclick=@(() => SetNsfw(tagDef, false))>Make SFW</a> + } else { + <a href="javascript:;" @onclick=@(() => SetNsfw(tagDef, true))>Make NSFW</a> + } + </td> + </tr> + } + </table> + </TabPane> + } + </TabContainer> +</div> + +<Dialog Title="Are you sure you want to delete this tag definition?" @ref=deleteTagDialog> + <ButtonContainer> + <button @onclick=@(() => deleteTagDialog.Hide()) class="secondary">Cancel</button> + <button @onclick=@(() => DeleteTagDefinition()) class="warning">Confirm</button> + </ButtonContainer> +</Dialog> + +<TagEditDialog OnTagUpdate=TagUpdated @ref=tagEditDialog/> + +<TagSelectDialog + OnSubmit=SetImplicitTags + @ref=implicitTagDialog /> + +@code { + private TabContainer tabContainer; + private Dialog deleteTagDialog; + private TagEditDialog tagEditDialog; + private TagSelectDialog implicitTagDialog; + + private TagDefinition? toDelete; + private TagDefinition? toEditImplicit; + + private TagDefinition[] tagDefinitions; + + private string?[] tagNamespaces; + + protected override void OnInitialized() => + userService.UserSessionState.OnStateChange += ShowNsfwChanged; + + protected override void OnParametersSet() => + LoadTags(); + + private void LoadTags() { + int[] nsfwTags = Array.Empty<int>(); + 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(); + + tagNamespaces = tagDefinitions + .Select(td => td.Namespace) + .Order() + .Distinct() + .ToArray(); + } + + private void PromptToDelete(TagDefinition toDelete) { + this.toDelete = toDelete; + deleteTagDialog.Show(); + } + + private void DeleteTagDefinition() { + if(toDelete is null) + return; + + tagService.DeleteTagDefinition(toDelete); + deleteTagDialog.Hide(); + LoadTags(); + StateHasChanged(); + } + + private void PromptTagCreate() { + string? ns = tabContainer.ActivePane?.Title; + if(ns == "Default") + ns = null; + tagEditDialog.Show(ns); + } + + private void TagUpdated(object? sender, EventArgs e) { + LoadTags(); + StateHasChanged(); + } + + private void PromptImplicitTags(TagDefinition toEditImplicit) { + this.toEditImplicit = toEditImplicit; + implicitTagDialog.SelectedTags = + toEditImplicit.ImplicitTags.ToArray(); + implicitTagDialog.Show(); + } + + private void SetImplicitTags(TagDefinition[] tagDefs) { + if(toEditImplicit is null) + return; + + tagService.SetImplicitTags(toEditImplicit, tagDefs); + LoadTags(); + StateHasChanged(); + } + + private void SetNsfw(TagDefinition tagDef, bool nsfw) { + if(nsfw) + tagService.AddImplicitTag(tagDef.Guid, HBContext.NsfwTag); + else + tagService.RemoveImplicitTag(tagDef.Guid, HBContext.NsfwTag); + LoadTags(); + StateHasChanged(); + } + + private async void ShowNsfwChanged(UserSessionState userSessionState) => + await InvokeAsync(() => { + LoadTags(); + StateHasChanged(); + }); + + public void Dispose() => + userService.UserSessionState.OnStateChange -= ShowNsfwChanged; +} |
