Files
ersatztv/ErsatzTV/Pages/ImageBrowser.razor
T
Jason DoveandGitHub 9462156148 fix mysql playout builds (#2352)
* more cancellation tokens and fixes

* so much cancellation token

* fix mysql playout builds
2025-08-27 18:09:56 +00:00

111 lines
5.0 KiB
Plaintext

@page "/media/browser/images"
@using System.Net
@using ErsatzTV.Application.Images
@implements IDisposable
@inject IDialogService Dialog
@inject IMediator Mediator
<MudForm Style="max-height: 100%">
<div class="d-flex flex-column" style="height: 100vh; overflow-x: auto">
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8">
<MudText Typo="Typo.h5" Class="mb-2">Images</MudText>
<MudDivider Class="mb-6"/>
<MudCard>
<MudTreeView T="ImageTreeItemViewModel" ServerData="LoadServerData" Items="@TreeItems" Hover="true" ExpandOnClick="true">
<ItemTemplate Context="item">
<MudTreeViewItem T="ImageTreeItemViewModel" Items="@item.Value!.TreeItems" Icon="@item.Value.Icon" CanExpand="@item.Value.CanExpand" Value="@item.Value">
<BodyContent>
<div style="display: flex; align-items: center; width: 100%">
<div style="justify-self: start; flex: 1">
<MudText>@item.Value.Text</MudText>
</div>
<div style="display: flex; align-items: center; justify-self: end;">
<span class="d-none d-sm-flex">@item.Value.EndText</span>
<MudTooltip Text="Edit Image Folder Duration" ShowOnHover="true" ShowOnClick="false" ShowOnFocus="false">
<MudIconButton Icon="@Icons.Material.Filled.Edit"
OnClick="@(_ => EditImageFolderDuration(item.Value))">
</MudIconButton>
</MudTooltip>
@{
string query = GetSearchQuery(item.Value);
if (!string.IsNullOrWhiteSpace(query))
{
<MudIconButton
Class="d-none d-sm-flex"
Icon="@Icons.Material.Filled.Search"
Href="@($"search?query={query}")"/>
}
}
</div>
</div>
</BodyContent>
</MudTreeViewItem>
</ItemTemplate>
</MudTreeView>
</MudCard>
</MudContainer>
</div>
</MudForm>
@code {
private CancellationTokenSource _cts;
private List<TreeItemData<ImageTreeItemViewModel>> TreeItems { get; set; } = [];
public void Dispose()
{
_cts?.Cancel();
_cts?.Dispose();
}
protected override async Task OnParametersSetAsync()
{
_cts?.Cancel();
_cts?.Dispose();
_cts = new CancellationTokenSource();
var token = _cts.Token;
try
{
List<ImageFolderViewModel> imageFolders = await Mediator.Send(new GetImageFolders(Option<int>.None), token);
TreeItems = imageFolders.Map(g => new TreeItemData<ImageTreeItemViewModel> { Value = new ImageTreeItemViewModel(g) }).ToList();
}
catch (OperationCanceledException)
{
// do nothing
}
}
private async Task<IReadOnlyCollection<TreeItemData<ImageTreeItemViewModel>>> LoadServerData(ImageTreeItemViewModel parentNode)
{
List<ImageFolderViewModel> result = await Mediator.Send(new GetImageFolders(parentNode.LibraryFolderId), _cts.Token);
foreach (ImageFolderViewModel imageFolder in result)
{
parentNode.TreeItems.Add(new TreeItemData<ImageTreeItemViewModel> { Value = new ImageTreeItemViewModel(imageFolder) });
}
return parentNode.TreeItems;
}
private static string GetSearchQuery(ImageTreeItemViewModel item)
{
var query = $"library_folder_id:{item.LibraryFolderId}";
return WebUtility.UrlEncode(query);
}
private async Task EditImageFolderDuration(ImageTreeItemViewModel item)
{
var parameters = new DialogParameters { { "ImageFolderDuration", item.ImageFolderDuration } };
var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraLarge };
IDialogReference dialog = await Dialog.ShowAsync<EditImageFolderDurationDialog>("Edit Image Folder Duration", parameters, options);
DialogResult result = await dialog.Result;
if (result is { Canceled: false })
{
double? duration = await Mediator.Send(new UpdateImageFolderDuration(item.LibraryFolderId, result.Data as double?), _cts.Token);
item.UpdateDuration(duration);
await InvokeAsync(StateHasChanged);
}
}
}