From 38c60cee378b9c2ad42fc9dc79bc492b919a68f5 Mon Sep 17 00:00:00 2001 From: Jake Mannens Date: Tue, 15 Aug 2023 15:49:14 +1000 Subject: Convert Razor pages to Blazor --- Pages/Component/Dialog.razor | 38 +++++++ Pages/Component/Dialog.razor.css | 21 ++++ Pages/Component/MediaTagTable.razor | 69 ++++++++++++ Pages/Component/MediaTagTable.razor.css | 3 + Pages/Component/TabContainer.razor | 35 ++++++ Pages/Component/TabContainer.razor.css | 19 ++++ Pages/Component/TabPane.razor | 29 +++++ Pages/Component/TabPane.razor.css | 1 + Pages/Component/TagSelectDialog.razor | 59 ++++++++++ Pages/Component/TagSelectDialog.razor.css | 31 +++++ Pages/Index.cshtml | 15 --- Pages/Index.cshtml.cs | 43 ------- Pages/Index.cshtml.css | 7 -- Pages/Index.razor | 17 +++ Pages/Index.razor.css | 8 ++ Pages/Shared/_Layout.cshtml | 26 ----- Pages/Shared/_Layout.cshtml.css | 36 ------ Pages/TagDefinitions.cshtml | 108 ------------------ Pages/TagDefinitions.cshtml.cs | 16 --- Pages/TagDefinitions.cshtml.css | 12 -- Pages/TagDefinitions.razor | 92 +++++++++++++++ Pages/TagDefinitions.razor.css | 12 ++ Pages/ViewMedia.cshtml | 181 ------------------------------ Pages/ViewMedia.cshtml.cs | 43 ------- Pages/ViewMedia.cshtml.css | 97 ---------------- Pages/ViewMedia.razor | 106 +++++++++++++++++ Pages/ViewMedia.razor.css | 30 +++++ Pages/_Host.cshtml | 33 ++++++ Pages/_ViewStart.cshtml | 3 - 29 files changed, 603 insertions(+), 587 deletions(-) create mode 100644 Pages/Component/Dialog.razor create mode 100644 Pages/Component/Dialog.razor.css create mode 100644 Pages/Component/MediaTagTable.razor create mode 100644 Pages/Component/MediaTagTable.razor.css create mode 100644 Pages/Component/TabContainer.razor create mode 100644 Pages/Component/TabContainer.razor.css create mode 100644 Pages/Component/TabPane.razor create mode 100644 Pages/Component/TabPane.razor.css create mode 100644 Pages/Component/TagSelectDialog.razor create mode 100644 Pages/Component/TagSelectDialog.razor.css delete mode 100644 Pages/Index.cshtml delete mode 100644 Pages/Index.cshtml.cs delete mode 100644 Pages/Index.cshtml.css create mode 100644 Pages/Index.razor create mode 100644 Pages/Index.razor.css delete mode 100644 Pages/Shared/_Layout.cshtml delete mode 100644 Pages/Shared/_Layout.cshtml.css delete mode 100644 Pages/TagDefinitions.cshtml delete mode 100644 Pages/TagDefinitions.cshtml.cs delete mode 100644 Pages/TagDefinitions.cshtml.css create mode 100644 Pages/TagDefinitions.razor create mode 100644 Pages/TagDefinitions.razor.css delete mode 100644 Pages/ViewMedia.cshtml delete mode 100644 Pages/ViewMedia.cshtml.cs delete mode 100644 Pages/ViewMedia.cshtml.css create mode 100644 Pages/ViewMedia.razor create mode 100644 Pages/ViewMedia.razor.css create mode 100644 Pages/_Host.cshtml delete mode 100644 Pages/_ViewStart.cshtml (limited to 'Pages') diff --git a/Pages/Component/Dialog.razor b/Pages/Component/Dialog.razor new file mode 100644 index 0000000..1e2929a --- /dev/null +++ b/Pages/Component/Dialog.razor @@ -0,0 +1,38 @@ +
+ @if(Title is not null) { +

@Title

+
+ } + @ChildContent +
+ +@code { + [Parameter] + public string? Title { get; set; } + + [Parameter] + public RenderFragment ChildContent { get; set; } + + public bool Visible { + get => visible; + set { + visible = value; + StateHasChanged(); + } + } + + [Parameter] + public int HeightPixels { set => height = $"{value}px"; } + [Parameter] + public int HeightPercent { set => height = $"{value}%"; } + + public void Show() => Visible = true; + public void Hide() => Visible = false; + + private bool visible = false; + + private string? height; + + private string style => + $"{(height is null ? "" : $"max-height:{height};")}"; +} diff --git a/Pages/Component/Dialog.razor.css b/Pages/Component/Dialog.razor.css new file mode 100644 index 0000000..ff34843 --- /dev/null +++ b/Pages/Component/Dialog.razor.css @@ -0,0 +1,21 @@ +div { + background: var(--col-dialog-bg); + border-radius: 20px; + box-shadow: 0px 5px 10px 10px rgb(0 0 0 / 25%); + display: flex; + flex-direction: column; + left: 50%; + opacity: 0; + padding: 20px; + position: absolute; + top: 50%; + transform: translate(-50%, -50%); + transition: visibility 0.1s, opacity 0.1s linear; + visibility: hidden; + width: 450px; +} + +div.visible { + opacity: 1; + visibility: visible; +} diff --git a/Pages/Component/MediaTagTable.razor b/Pages/Component/MediaTagTable.razor new file mode 100644 index 0000000..1bd4de4 --- /dev/null +++ b/Pages/Component/MediaTagTable.razor @@ -0,0 +1,69 @@ +@inject IDbContextFactory dbFactory +@inject ITagService tagService + + + + + + + + + + @foreach(var tag in userTags) { + bool isImplicit = IsImplicit(tag); + + + + + + } +
NamespaceTag Name
+ @if(isImplicit) { + @tag.Namespace + } else { + @tag.Namespace + } + + @if(isImplicit) { + @tag.Name + } else { + @tag.Name + } + Delete(tag))>Delete
+ +@code { + [Parameter] + public Media Media { get; set; } + + private IEnumerable userTags { + get { + using var db = dbFactory.CreateDbContext(); + if(db.Entry(Media).State == EntityState.Detached) + db.Attach(Media); + return GetTagRecursive( + Media.Tags + .Select(t => t.TagDefinition)) + .Where(td => td.Source == TagSource.UserTag) + .OrderBy(td => td.Namespace) + .ThenBy(td => td.Name) + .ToArray(); + } + } + + public void Refresh() => StateHasChanged(); + + private void Delete(TagDefinition tagDef) { + tagService.RemoveTag(Media, tagDef); + StateHasChanged(); + } + + private bool IsImplicit(TagDefinition tagDef) => + !Media.Tags + .Select(t => t.TagDefinition.Guid) + .Contains(tagDef.Guid); + + private IEnumerable GetTagRecursive(IEnumerable tagDefs) => + tagDefs + .Concat(tagDefs.SelectMany(td => GetTagRecursive(td.ImplicitTags))) + .DistinctBy(td => td.Guid); +} diff --git a/Pages/Component/MediaTagTable.razor.css b/Pages/Component/MediaTagTable.razor.css new file mode 100644 index 0000000..dcf5e09 --- /dev/null +++ b/Pages/Component/MediaTagTable.razor.css @@ -0,0 +1,3 @@ +td { + font-size: 8pt; +} diff --git a/Pages/Component/TabContainer.razor b/Pages/Component/TabContainer.razor new file mode 100644 index 0000000..3caab0b --- /dev/null +++ b/Pages/Component/TabContainer.razor @@ -0,0 +1,35 @@ + + + + + + @ChildContent + + +@code { + [Parameter] + public RenderFragment ChildContent { get; set; } + + public TabPane? ActivePane { get; set; } + List Panes = new(); + + public void AddPane(TabPane tabPane) { + Panes.Add(tabPane); + if(Panes.Count == 1) + ActivePane = tabPane; + StateHasChanged(); + } + + public void RemovePane(TabPane tabPane) { + if(ActivePane == tabPane) + ActivePane = Panes.ElementAtOrDefault(0); + Panes.Remove(tabPane); + StateHasChanged(); + } +} \ No newline at end of file diff --git a/Pages/Component/TabContainer.razor.css b/Pages/Component/TabContainer.razor.css new file mode 100644 index 0000000..6a56021 --- /dev/null +++ b/Pages/Component/TabContainer.razor.css @@ -0,0 +1,19 @@ +div.tabs { + display: inherit !important; + border-bottom: 1px solid white; +} + +div.tabs > a { + display: inline-block; + padding: 10px 10px 9px 10px; +} + +div.tabs > a.selected { + border-bottom: 4px solid white; + padding-bottom: 5px; +} + +div.tabs > a:hover { + background: rgba(255, 255, 255, 0.4); + filter: none; +} diff --git a/Pages/Component/TabPane.razor b/Pages/Component/TabPane.razor new file mode 100644 index 0000000..ba4a13a --- /dev/null +++ b/Pages/Component/TabPane.razor @@ -0,0 +1,29 @@ +@implements IDisposable + + + +@if(Parent.ActivePane == this) { + @ChildContent +} + +@code { + [CascadingParameter] + private TabContainer Parent { get; set; } + + [Parameter] + public string Title { get; set; } + + [Parameter] + public RenderFragment ChildContent { get; set; } + + protected override void OnInitialized() { + if (Parent is null) + throw new ArgumentNullException(nameof(Parent), "TabPane must exist within a TabContainer"); + + Parent.AddPane(this); + } + + public void Dispose() { + Parent.RemovePane(this); + } +} \ No newline at end of file diff --git a/Pages/Component/TabPane.razor.css b/Pages/Component/TabPane.razor.css new file mode 100644 index 0000000..5f28270 --- /dev/null +++ b/Pages/Component/TabPane.razor.css @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Pages/Component/TagSelectDialog.razor b/Pages/Component/TagSelectDialog.razor new file mode 100644 index 0000000..590c8f2 --- /dev/null +++ b/Pages/Component/TagSelectDialog.razor @@ -0,0 +1,59 @@ +@inject HBContext db + + + + + +
+ @foreach(var tagDef in tagDefinitions) { + Checked(tagDef, e.Value))/> + + } +
+
+ + +
+
+ +@code { + [Parameter] + public string? Title { get; set; } + + [Parameter] + public EventCallback OnSubmit { get; set; } + + public bool Visible { + get => visible; + set => visible = dialog.Visible = value; + } + + private bool visible; + + private Dialog dialog; + + private IEnumerable tagDefinitions => db.TagDefinitions + .Where(td => td.Source == TagSource.UserTag) + .OrderBy(td => td.Name); + + private List selected = new(); + + public void Show() => Visible = true; + public void Hide() => Visible = false; + + private async void Submit() { + await OnSubmit.InvokeAsync(selected.ToArray()); + selected.Clear(); + Hide(); + StateHasChanged(); + } + + private void Checked(TagDefinition tagDef, object? isChecked) { + if(isChecked is bool && (bool) isChecked == true) + if (!selected.Contains(tagDef)) + selected.Add(tagDef); + else + if (selected.Contains(tagDef)) + selected.Remove(tagDef); + } +} diff --git a/Pages/Component/TagSelectDialog.razor.css b/Pages/Component/TagSelectDialog.razor.css new file mode 100644 index 0000000..f6f704e --- /dev/null +++ b/Pages/Component/TagSelectDialog.razor.css @@ -0,0 +1,31 @@ +div.button-container { + display: flex; + justify-content: flex-end; +} + +div.tag-definitions { + overflow-y: auto; + user-select: none; +} + +div.tag-definitions label { + background: #555; + border-radius: 10px; + display: inline-block; + font-size: 10pt; + margin: 0 5px 5px 0; + padding: 5px 7px 5px 7px; + transition: background 0.1s linear; +} + +div.tag-definitions label:hover { + background: #777; +} + +div.tag-definitions input:checked + label { + background: #aaa; +} + +div.tag-definitions input { + display: none; +} diff --git a/Pages/Index.cshtml b/Pages/Index.cshtml deleted file mode 100644 index 80e05d9..0000000 --- a/Pages/Index.cshtml +++ /dev/null @@ -1,15 +0,0 @@ -@page -@model HyperBooru.Pages.IndexModel - - - -
- - -
- -@foreach(var media in Model.Media) { - - - -} \ No newline at end of file diff --git a/Pages/Index.cshtml.cs b/Pages/Index.cshtml.cs deleted file mode 100644 index 07d24f0..0000000 --- a/Pages/Index.cshtml.cs +++ /dev/null @@ -1,43 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.RazorPages; - -namespace HyperBooru.Pages; - -public class IndexModel : PageModel { - public IEnumerable Media { get; private set; } - - private HyperBooruDbContext db; - - public IndexModel(HyperBooruDbContext db) => - this.db = db; - - public void OnGet([FromQuery(Name = "q")] string? query) { - IEnumerable media; - - if(query is null) { - media = db.UploadedFiles - .OrderByDescending(uf => uf.UploadTime) - .Select(uf => uf.Media) - .Distinct(); - } else { - query = query.ToLower(); - - var matchingTags = db.TagDefinitions - .Where(td => td.Name.ToLower().Contains(query)) - .Select(td => td.Guid); - - media = db.Media - .Where(m => - m.Tags - .Select(t => t.TagDefinition.Guid) - .Intersect(matchingTags) - .Any()); - } - - Media = media.OrderByDescending(m => - m.UploadedFiles - .Select(uf => uf.UploadTime) - .Order() - .Last()); - } -} \ No newline at end of file diff --git a/Pages/Index.cshtml.css b/Pages/Index.cshtml.css deleted file mode 100644 index f573988..0000000 --- a/Pages/Index.cshtml.css +++ /dev/null @@ -1,7 +0,0 @@ -img { - max-height: 200px; -} - -form#upload { - padding-bottom: 30px; -} \ No newline at end of file diff --git a/Pages/Index.razor b/Pages/Index.razor new file mode 100644 index 0000000..a69d69c --- /dev/null +++ b/Pages/Index.razor @@ -0,0 +1,17 @@ +@page "/" +@inject HBContext db; + +Gallery + + + +
+ + +
+ +@foreach(var media in db.Media) { + + + +} diff --git a/Pages/Index.razor.css b/Pages/Index.razor.css new file mode 100644 index 0000000..d1750b4 --- /dev/null +++ b/Pages/Index.razor.css @@ -0,0 +1,8 @@ +img { + margin-right: 5px; + max-height: 200px; +} + +form#upload { + padding-bottom: 30px; +} \ No newline at end of file diff --git a/Pages/Shared/_Layout.cshtml b/Pages/Shared/_Layout.cshtml deleted file mode 100644 index 9d6d382..0000000 --- a/Pages/Shared/_Layout.cshtml +++ /dev/null @@ -1,26 +0,0 @@ -@{ - ViewBag.Title ??= "HyperBooru"; - ViewBag.ContentScroll ??= true; - ViewBag.ContentMargin ??= "30px"; -} - - - - - - - - - @ViewBag.Title - - - -
- @RenderBody() -
- - \ No newline at end of file diff --git a/Pages/Shared/_Layout.cshtml.css b/Pages/Shared/_Layout.cshtml.css deleted file mode 100644 index 5b2f26e..0000000 --- a/Pages/Shared/_Layout.cshtml.css +++ /dev/null @@ -1,36 +0,0 @@ -div#navbar { - background: var(--col-navbar-bg); - box-shadow: rgba(0, 0, 0, 0.5) 0px 10px 10px; - display: flex; -} - -div#navbar > a { - color: white; - display: inline-block; - padding: 20px 20px 20px 20px; -} - -div#navbar > a:hover { - background: rgba(255, 255, 255, 0.4); - filter: none; -} - -div#navbar > a:active { - background: #fff; - color: var(--col-navbar-bg); -} - -div#navbar > input { - align-self: center; - background: var(--col-bg); - border-radius: 0; - color: white; - height: 40px !important; - margin: 0 20px 0 auto; - font-size: 12pt; - min-width: 30%; -} - -#content { - flex: 1 1 calc(100vh - 119px); -} \ No newline at end of file diff --git a/Pages/TagDefinitions.cshtml b/Pages/TagDefinitions.cshtml deleted file mode 100644 index 7bf1790..0000000 --- a/Pages/TagDefinitions.cshtml +++ /dev/null @@ -1,108 +0,0 @@ -@page -@model HyperBooru.Pages.TagDefinitionsModel -@{ - ViewBag.Title = "Tag Definitions"; -} - - - - - - - - - - - - - - @foreach(var tagDef in Model.TagDefinitions) { - - - - - - - - } -
GuidSourceNamespaceName
@tagDef.Guid@tagDef.Source@tagDef.Namespace@tagDef.NameDelete
- -
- -
- -
-

Create a new tag definition

-
-
- - - - -
- - -
-
-
- -
-

Are you sure you want to delete this tag definition?

-
-
- - -
-
diff --git a/Pages/TagDefinitions.cshtml.cs b/Pages/TagDefinitions.cshtml.cs deleted file mode 100644 index afbad87..0000000 --- a/Pages/TagDefinitions.cshtml.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.RazorPages; - -namespace HyperBooru.Pages; - -public class TagDefinitionsModel : PageModel { - public IEnumerable TagDefinitions => - db.TagDefinitions.Where(td => td.Source == TagSource.UserTag); - - private HyperBooruDbContext db; - - public TagDefinitionsModel(HyperBooruDbContext db) => - this.db = db; - - public void OnGet() {} -} diff --git a/Pages/TagDefinitions.cshtml.css b/Pages/TagDefinitions.cshtml.css deleted file mode 100644 index 93001c7..0000000 --- a/Pages/TagDefinitions.cshtml.css +++ /dev/null @@ -1,12 +0,0 @@ -form > input { - width: 100%; -} - -div.button-container { - display: flex; - justify-content: flex-end; -} - -table#tag-definitions td:first-child { - font-family: 'Lucida Console'; -} \ No newline at end of file diff --git a/Pages/TagDefinitions.razor b/Pages/TagDefinitions.razor new file mode 100644 index 0000000..e48402b --- /dev/null +++ b/Pages/TagDefinitions.razor @@ -0,0 +1,92 @@ +@page "/TagDefinitions" +@inject IDbContextFactory dbFactory +@inject ITagService tagService + +Tag Definitions + + + + + + + + + + + + @foreach(var tagDef in tagDefinitions) { + + + + + + + + } +
GuidSourceNamespaceName
@tagDef.Guid@tagDef.Source@tagDef.Namespace@tagDef.Name + PromptToDelete(tagDef))> + Delete + +
+ +
+ +
+ + +
+ + + + +
+ + +
+
+
+ + +
+ + +
+
+ +@code { + private Dialog createTagDialog; + private Dialog deleteTagDialog; + + private string tagName; + private string? tagNamespace; + + private TagDefinition? toDelete; + + private IEnumerable tagDefinitions => + dbFactory.CreateDbContext().TagDefinitions + .Where(td => td.Source == TagSource.UserTag) + .OrderBy(td => td.Namespace) + .ThenBy(td => td.Name); + + private void CreateTagDefinition() { + if(string.IsNullOrEmpty(tagNamespace)) + tagNamespace = null; + + tagService.CreateTagDefinition(tagName, tagNamespace); + createTagDialog.Hide(); + StateHasChanged(); + } + + private void PromptToDelete(TagDefinition toDelete) { + this.toDelete = toDelete; + deleteTagDialog.Show(); + } + + private void DeleteTagDefinition() { + if(toDelete is null) + return; + + tagService.DeleteTagDefinition(toDelete); + deleteTagDialog.Hide(); + } +} diff --git a/Pages/TagDefinitions.razor.css b/Pages/TagDefinitions.razor.css new file mode 100644 index 0000000..93001c7 --- /dev/null +++ b/Pages/TagDefinitions.razor.css @@ -0,0 +1,12 @@ +form > input { + width: 100%; +} + +div.button-container { + display: flex; + justify-content: flex-end; +} + +table#tag-definitions td:first-child { + font-family: 'Lucida Console'; +} \ No newline at end of file diff --git a/Pages/ViewMedia.cshtml b/Pages/ViewMedia.cshtml deleted file mode 100644 index e77ec22..0000000 --- a/Pages/ViewMedia.cshtml +++ /dev/null @@ -1,181 +0,0 @@ -@page -@model HyperBooru.Pages.ViewMediaModel -@{ - ViewBag.ContentScroll = false; -} - - - - - -
- -
-
- File Info - Tags -
-@*
- - - - - -
*@ -
-

Upload history

-
- - - - - - - - - @foreach(var file in Model.Media.UploadedFiles) { - - - - - - - - } -
Created OnLast WriteUploaded OnFilenameOriginal Checksum
@(file.CreateTime?.ToString() ?? "N/A")@(file.LastWriteTime?.ToString() ?? "N/A")@file.UploadTime@file.Filename@file.OriginalChecksum
-
- - -
-
-
- - - - - - - @foreach(var tag in Model.UserTags) { - bool isImplicit = Model.IsImplicit(tag); - - - - - - } -
NamespaceTag Name
- @if(isImplicit) { - @tag.Namespace - } else { - @tag.Namespace - } - - @if(isImplicit) { - @tag.Name - } else { - @tag.Name - } - Delete
-
- - -
-
-
-
- -
-

Delete this media?

-
-
- - -
-
- -
-

Select one or more tag(s) to add

-
- -
- @foreach(var tagdef in Model.TagDefinitions) { - - - } -
-
- - -
-
diff --git a/Pages/ViewMedia.cshtml.cs b/Pages/ViewMedia.cshtml.cs deleted file mode 100644 index 76c515b..0000000 --- a/Pages/ViewMedia.cshtml.cs +++ /dev/null @@ -1,43 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.RazorPages; - -namespace HyperBooru.Pages; - -public class ViewMediaModel : PageModel { - public DbMedia Media { get; private set; } - - public DbTagDefinition[] UserTags { get; private set; } - - public IEnumerable TagDefinitions => - db.TagDefinitions.Where(td => td.Source == TagSource.UserTag); - - private HyperBooruDbContext db; - - public ViewMediaModel(HyperBooruDbContext db) => - this.db = db; - - public IActionResult OnGet([FromQuery(Name = "m")] Guid mediaId) { - Media = db.Media.First(m => m.Guid == mediaId); - if(Media is null) - return NotFound(); - - UserTags = GetTagRecursive( - Media.Tags - .Select(t => t.TagDefinition)) - .OrderBy(td => td.Namespace) - .ThenBy(td => td.Name) - .ToArray(); - - return Page(); - } - - public bool IsImplicit(DbTagDefinition tagDef) => - !Media.Tags - .Select(t => t.TagDefinition.Guid) - .Contains(tagDef.Guid); - - private IEnumerable GetTagRecursive(IEnumerable tagDefs) => - tagDefs - .Concat(tagDefs.SelectMany(td => GetTagRecursive(td.ImplicitTags))) - .DistinctBy(td => td.Guid); -} \ No newline at end of file diff --git a/Pages/ViewMedia.cshtml.css b/Pages/ViewMedia.cshtml.css deleted file mode 100644 index 29094b8..0000000 --- a/Pages/ViewMedia.cshtml.css +++ /dev/null @@ -1,97 +0,0 @@ -div#content { - display: flex; - align-items: start; - height: 100%; -} - -div#content > img { - max-width: 60%; - height: 100%; - object-fit: contain; -} - -div#metadata { - margin-left: 15px; - width: 100%; -} - -div#metadata > div { - display: none; -} - -div#metadata > div.selected { - display: inherit !important; -} - -div#metadata-header { - display: inherit !important; - border-bottom: 1px solid white; -} - -div#metadata-header > a { - display: inline-block; - padding: 10px 10px 9px 10px; -} - -div#metadata-header > a.selected { - border-bottom: 4px solid white; - padding-bottom: 5px; -} - -div#metadata-header > a:hover { - background: rgba(255, 255, 255, 0.4); - filter: none; -} - -div#metadata-fileinfo > table th { - font-size: 8pt; -} - -div#metadata-fileinfo > table td { - font-family: 'Lucida Console'; - font-size: 8pt; -} - -div#metadata-fileinfo button#delete-button { - background: #ff4848; -} - -div#metadata-tags > table td { - font-size: 8pt; -} - -div.button-container { - display: flex; - justify-content: flex-end; -} - -div#tag-dialog { - max-height: 400px; -} - -div#tag-dialog div#tag-definitions { - overflow-y: auto; - user-select: none; -} - -div#tag-dialog div#tag-definitions label { - background: #555; - border-radius: 10px; - display: inline-block; - font-size: 10pt; - margin: 0 5px 5px 0; - padding: 5px 7px 5px 7px; - transition: background 0.1s linear; -} - -div#tag-dialog div#tag-definitions label:hover { - background: #777; -} - -div#tag-dialog div#tag-definitions input:checked + label { - background: #aaa; -} - -div#tag-dialog div#tag-definitions input { - display: none; -} diff --git a/Pages/ViewMedia.razor b/Pages/ViewMedia.razor new file mode 100644 index 0000000..8436159 --- /dev/null +++ b/Pages/ViewMedia.razor @@ -0,0 +1,106 @@ +@page "/ViewMedia" +@inject IDbContextFactory dbFactory +@inject ITagService tagService + +@title + + + +
+ +
+ + +
+

Title: @(@media.ShortDescription ?? "None")

+

Description: @(media.LongDescription ?? "None")

+

Upload history

+
+ + + + + + + + + @foreach(var file in media.UploadedFiles) { + + + + + + + + } +
Created OnLast WriteUploaded OnFilenameOriginal Checksum
@(file.CreateTime?.ToString() ?? "N/A")@(file.LastWriteTime?.ToString() ?? "N/A")@file.UploadTime@file.Filename@file.OriginalChecksum
+
+ + +
+
+
+ +
+ +
+ + @if(media.IsIngest) { + + } else { + + } +
+
+
+
+
+
+ + +
+ + +
+
+ + + +@code { + [Parameter] + [SupplyParameterFromQuery(Name = "m")] + public Guid MediaId { get; set; } + + private Media media; + + private string title; + + private bool infoEditMode = false; + + private Dialog deleteDialog; + private TagSelectDialog tagDialog; + private MediaTagTable mediaTagTable; + + protected override void OnInitialized() { + using var db = dbFactory.CreateDbContext(); + media = db.Media.AsNoTracking().First(m => m.Guid == MediaId); + if(media is null) + throw new ArgumentException("Media not found!"); + + title = media.DisplayName ?? "Media View"; + } + + private void AddTags(TagDefinition[] tagDefs) { + Console.WriteLine($"Adding tags: {string.Join(", ", tagDefs.Select(td => td.Name))}"); + foreach(var tagDef in tagDefs) + tagService.AddTag(media, tagDef); + mediaTagTable.Refresh(); + } + + private void SetIngest(bool ingest) { + StateHasChanged(); + } +} diff --git a/Pages/ViewMedia.razor.css b/Pages/ViewMedia.razor.css new file mode 100644 index 0000000..abf8e08 --- /dev/null +++ b/Pages/ViewMedia.razor.css @@ -0,0 +1,30 @@ +div#content { + display: flex; + align-items: start; + height: 100%; +} + +div#content > img { + max-width: 60%; + height: 100%; + object-fit: contain; +} + +div#metadata { + margin-left: 15px; + width: 100%; +} + +div#metadata-fileinfo > table th { + font-size: 8pt; +} + +div#metadata-fileinfo > table td { + font-family: 'Lucida Console'; + font-size: 8pt; +} + +div.button-container { + display: flex; + justify-content: flex-end; +} diff --git a/Pages/_Host.cshtml b/Pages/_Host.cshtml new file mode 100644 index 0000000..e01b94d --- /dev/null +++ b/Pages/_Host.cshtml @@ -0,0 +1,33 @@ +@page "/" +@using Microsoft.AspNetCore.Components.Web +@namespace HyperBooru.Pages +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers + + + + + + + + + + + + + + + +
+ + An error has occurred. This application may no longer respond until reloaded. + + + An unhandled exception has occurred. See browser dev tools for details. + + Reload + 🗙 +
+ + + + diff --git a/Pages/_ViewStart.cshtml b/Pages/_ViewStart.cshtml deleted file mode 100644 index 1af6e49..0000000 --- a/Pages/_ViewStart.cshtml +++ /dev/null @@ -1,3 +0,0 @@ -@{ - Layout = "_Layout"; -} \ No newline at end of file -- cgit v1.3