diff options
| author | Jake Mannens <jake@asger.xyz> | 2023-09-07 09:34:07 +1000 |
|---|---|---|
| committer | Jake Mannens <jake@asger.xyz> | 2025-08-20 01:20:57 +1000 |
| commit | f36c9e8d52b08253041392b0be9845422adca005 (patch) | |
| tree | a3859709d8810ba10fb9fd31038047be5f5d151b | |
| parent | ad9e63035809ce65054df80bde95572b993de415 (diff) | |
Improved dialog styling and made dialogs draggable
| -rw-r--r-- | Pages/Component/Dialog.razor | 55 | ||||
| -rw-r--r-- | Pages/Component/Dialog.razor.css | 24 | ||||
| -rw-r--r-- | Pages/_Host.cshtml | 1 | ||||
| -rw-r--r-- | Program.cs | 1 | ||||
| -rw-r--r-- | Services/DialogService.cs | 39 | ||||
| -rw-r--r-- | wwwroot/js/dialog.js | 68 |
6 files changed, 108 insertions, 80 deletions
diff --git a/Pages/Component/Dialog.razor b/Pages/Component/Dialog.razor index e71ddc6..dbfec49 100644 --- a/Pages/Component/Dialog.razor +++ b/Pages/Component/Dialog.razor @@ -1,13 +1,20 @@ -@inject IDialogService dialogService +@inject IJSRuntime jsRuntime @implements IDialog -@implements IDisposable -<div @onclick=Bump style="@(style)"> +<div + class="dialog" + onmousedown="dialogMouseDown(event)" + style="opacity:0;visibility:hidden;@(heightStyle)" + @ref=dialogDiv> @if(Title is not null) { - <p>@Title</p> - <hr/> + <div class="titlebar" onmousedown="dialogTitleMouseDown(event)"> + <p class="title">@Title</p> + <hr/> + </div> } - @ChildContent + <div class="content"> + @ChildContent + </div> </div> @code { @@ -26,49 +33,21 @@ get => visible; set { visible = value; - if(value) - Bump(); - StateHasChanged(); - } - } - - public int? ZIndex { - get => zIndex; - set { - zIndex = value; - StateHasChanged(); + jsRuntime.InvokeVoidAsync( + "setDialogVisibility", + new object?[] { dialogDiv, value }); } } private bool visible = false; - private int? zIndex; - private string? height; - protected override void OnInitialized() => - dialogService.Register(this); + private ElementReference dialogDiv; public void Show() => Visible = true; public void Hide() => Visible = false; - private void Bump() => - dialogService.BumpZIndex(this); - - private string style => - zIndexStyle + - heightStyle + - visiblilityStyle; - - private string zIndexStyle => - zIndex is null ? "display:none;" : $"z-index:{zIndex};"; - private string heightStyle => $"{(height is null ? "" : $"max-height:{height};")}"; - - private string visiblilityStyle => - Visible ? "opacity:1;visibility:visible;" : "opacity:0;visibility:hidden;"; - - public void Dispose() => - dialogService.Unregister(this); } diff --git a/Pages/Component/Dialog.razor.css b/Pages/Component/Dialog.razor.css index dea3d8d..1447407 100644 --- a/Pages/Component/Dialog.razor.css +++ b/Pages/Component/Dialog.razor.css @@ -1,11 +1,11 @@ -div { +div.dialog { 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%; - padding: 20px; + padding: 0; position: absolute; top: 50%; transform: translate(-50%, -50%); @@ -13,3 +13,23 @@ width: 450px; z-index: 1000; } + +hr { + margin: 0; +} + +div.titlebar { + cursor: grab; +} + +div.titlebar p.title { + font-size: 10pt; + margin: 0; + padding: 10px 20px 10px 20px; +} + +div.content { + display: flex; + flex-direction: column; + padding: 20px; +} diff --git a/Pages/_Host.cshtml b/Pages/_Host.cshtml index e01b94d..177e2df 100644 --- a/Pages/_Host.cshtml +++ b/Pages/_Host.cshtml @@ -12,6 +12,7 @@ <link href="/styles/global.css" rel="stylesheet" /> <link href="/favicon.ico" rel="icon" /> <link href="/manifest.webmanifest" rel="manifest" /> + <script type="text/javascript" src="/js/dialog.js"></script> <component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" /> </head> <body> @@ -21,7 +21,6 @@ public class Program { builder.Services.AddScoped<ITagService, TagService>(); builder.Services.AddScoped<IMediaService, MediaService>(); builder.Services.AddSingleton<IUserService, UserService>(); - builder.Services.AddScoped<IDialogService, DialogService>(); builder.Services.AddHostedService<OcrService>(); var app = builder.Build(); diff --git a/Services/DialogService.cs b/Services/DialogService.cs deleted file mode 100644 index 5967d95..0000000 --- a/Services/DialogService.cs +++ /dev/null @@ -1,39 +0,0 @@ -using HyperBooru.Pages.Component; - -namespace HyperBooru.Services; - -public interface IDialogService { - public void Register(Dialog dialog); - public void Unregister(Dialog dialog); - public void BumpZIndex(Dialog dialog); -} - -public class DialogService : IDialogService { - private const int MinZLevel = 900; - - private List<Dialog> dialogs = new(); - - public void Register(Dialog dialog) { - if(!dialogs.Contains(dialog)) - dialogs.Add(dialog); - - dialog.ZIndex = dialogs.Count() - 1 + MinZLevel; - } - - public void Unregister(Dialog dialog) { - dialogs.Remove(dialog); - for(int i = 0; i < dialogs.Count(); i++) - dialogs[i].ZIndex = i + MinZLevel; - } - - public void BumpZIndex(Dialog dialog) { - if(!dialogs.Contains(dialog)) - return; - - dialogs.Remove(dialog); - dialogs.Add(dialog); - - for(int i = 0; i < dialogs.Count(); i++) - dialogs[i].ZIndex = i + MinZLevel; - } -}
\ No newline at end of file diff --git a/wwwroot/js/dialog.js b/wwwroot/js/dialog.js new file mode 100644 index 0000000..065014a --- /dev/null +++ b/wwwroot/js/dialog.js @@ -0,0 +1,68 @@ +function dialogMouseDown(e) { + bumpDialog(e.currentTarget); +} + +function dialogTitleMouseDown(e) { + e = e || window.event; + e.preventDefault(); + var element = e.currentTarget.parentElement; + var ds = element.dataset; + ds.lastX = e.clientX; + ds.lastY = e.clientY; + + window.dragDialog = element; + document.onmouseup = dragMouseUp; + document.onmousemove = dragMouseMove; +} + +function dragMouseUp() { + window.dragDialog = null; + document.onmouseup = null; + document.onmousemove = null; +} + +function dragMouseMove(e) { + e = e || window.event; + e.preventDefault(); + var element = window.dragDialog; + var ds = element.dataset; + deltaX = ds.lastX - e.clientX; + deltaY = ds.lastY - e.clientY; + ds.lastX = e.clientX; + ds.lastY = e.clientY; + element.style.left = (element.offsetLeft - deltaX) + 'px'; + element.style.top = (element.offsetTop - deltaY) + 'px'; +} + +function setDialogVisibility(element, visible) { + if(visible) { + element.style.left = null; + element.style.top = null; + element.style.opacity = 1; + element.style.visibility = 'visible'; + bumpDialog(element); + + var input = element.querySelector('input[type="text"]'); + if(input) { + setTimeout(() => input.focus(), 100); + } + } else { + element.style.opacity = 0; + element.style.visibility = 'hidden'; + } +} + +function bumpDialog(element) { + var dialogs = Array + .from(document.querySelectorAll('div.dialog')) + .map(e => ({ zIndex: parseInt(e.style.zIndex), element: e })) + .sort((a, b) => a.zIndex - b.zIndex) + .map(d => d.element) + .filter(e => e != element); + + dialogs.push(element); + + var z = 900; + for(var d of dialogs) + d.style.zIndex = z++; +} |
