Files
ersatztv/ErsatzTV/Shared/MediaCard.razor
T

176 lines
6.4 KiB
Plaintext

@using ErsatzTV.Application.MediaCards
@using static Prelude
@inject IMediator Mediator
@inject NavigationManager NavigationManager
<div class="@((ContainerClass ?? "media-card-container mr-6") + " pb-3")" id="@($"item_{Data.MediaItemId}")">
@if (SelectClicked.HasDelegate || !string.IsNullOrWhiteSpace(Href))
{
<div class="@(IsSelected ? DeleteClicked.HasDelegate ? "media-card-selected-delete" : "media-card-selected" : "")"
style="border-radius: 4px; position: relative;">
<MudPaper Class="@($"media-card {CardClass}")" Style="@ArtworkForItem()">
@if (string.IsNullOrWhiteSpace(Data.Poster))
{
<MudText Align="Align.Center" Typo="Typo.h1" Class="media-card-poster-placeholder mud-text-primary">
@GetPlaceholder(Data.SortTitle)
</MudText>
}
</MudPaper>
@if (IsSelected)
{
<div style="display: flex; height: 48px; left: 0; position: absolute; top: 0; width: 48px;">
<MudIcon Color="@SelectColor"
Icon="@Icons.Material.Filled.CheckBox"
Style="margin: auto"/>
</div>
}
@if (Data.State == MediaItemState.FileNotFound)
{
<div style="position: absolute; right: 12px; top: 12px;">
<MudIcon Icon="@Icons.Material.Filled.Warning" Color="Color.Error"/>
</div>
}
else if (Data.State == MediaItemState.Unavailable)
{
<div style="position: absolute; right: 12px; top: 12px;">
<MudIcon Icon="@Icons.Material.Filled.Warning" Color="Color.Warning"/>
</div>
}
<div class="media-card-overlay" style="">
<MudButton Style="height: 100%; width: 100%"
OnClick="OnOverlayClick">
</MudButton>
@if (SelectClicked.HasDelegate)
{
<MudIconButton Color="@SelectColor"
Icon="@(IsSelected ? Icons.Material.Filled.CheckBox : Icons.Material.Filled.CheckBoxOutlineBlank)"
Style="left: 0; position: absolute; top: 0;"
OnClick="@(e => SelectClicked.InvokeAsync(e))"/>
}
@if (AddToCollectionClicked.HasDelegate && !IsSelectMode)
{
<MudIconButton Color="Color.Tertiary"
Icon="@Icons.Material.Filled.PlaylistAdd"
Style="bottom: 0; left: 0; position: absolute;"
OnClick="@(() => AddToCollectionClicked.InvokeAsync(Data))"/>
}
@if (DeleteClicked.HasDelegate && !IsSelectMode)
{
<MudIconButton Color="Color.Error"
Icon="@Icons.Material.Filled.Delete"
Style="bottom: 0; position: absolute; right: 0;"
OnClick="@(() => DeleteClicked.InvokeAsync(Data))"/>
}
</div>
</div>
}
else
{
<MudPaper Class="@($"media-card {CardClass}")" Style="@ArtworkForItem()">
@if (string.IsNullOrWhiteSpace(Data.Poster))
{
<MudText Align="Align.Center" Typo="Typo.h1" Class="media-card-poster-placeholder mud-text-primary">
@GetPlaceholder(Data.SortTitle)
</MudText>
}
</MudPaper>
}
<MudText Align="Align.Center" Class="media-card-title" UserAttributes="@(new Dictionary<string, object> { { "title", Data.Title } })">
@(Title ?? Data.Title)
</MudText>
<MudText Typo="Typo.body2" Align="Align.Center" Class="mud-text-secondary">
@(Subtitle ?? Data.Subtitle)
</MudText>
</div>
@code {
[Parameter]
public MediaCardViewModel Data { get; set; }
[Parameter]
public string Href { get; set; }
[Parameter]
public EventCallback<Unit> DataRefreshed { get; set; }
[Parameter]
public string Placeholder { get; set; }
[Parameter]
public string Title { get; set; }
[Parameter]
public string Subtitle { get; set; }
[Parameter]
public string ContainerClass { get; set; }
[Parameter]
public string CardClass { get; set; }
[Parameter]
public ArtworkKind ArtworkKind { get; set; }
[Parameter]
public EventCallback<MediaCardViewModel> DeleteClicked { get; set; }
[Parameter]
public EventCallback<MediaCardViewModel> AddToCollectionClicked { get; set; }
[Parameter]
public EventCallback<MouseEventArgs> SelectClicked { get; set; }
[Parameter]
public bool IsSelectMode { get; set; }
[Parameter]
public bool IsSelected { get; set; }
[Parameter]
public Color SelectColor { get; set; } = Color.Tertiary;
[Parameter]
public bool IsRemoteArtwork { get; set; }
private string GetPlaceholder(string sortTitle)
{
if (Placeholder != null)
{
return Placeholder;
}
char first = Optional(sortTitle).Map(t => t.ToUpperInvariant().HeadOrNone()).Flatten().Match(head => head, () => ' ');
return char.IsDigit(first) || !char.IsLetter(first) ? "#" : first.ToString();
}
private string ArtworkForItem()
{
if (IsRemoteArtwork || Data.Poster?.StartsWith("http://") == true || Data.Poster?.StartsWith("https://") == true)
{
return $"position: relative; background-image: url({Data.Poster}); background-size: cover; background-position: center";
}
return string.IsNullOrWhiteSpace(Data.Poster)
? "position: relative"
: $"position: relative; background-image: url(artwork/{PathForArtwork()}/{Data.Poster}); background-size: cover; background-position: center";
}
private string PathForArtwork() => ArtworkKind switch
{
ArtworkKind.Thumbnail => "thumbnails",
_ => "posters"
};
private void OnOverlayClick(MouseEventArgs e)
{
if (IsSelectMode || string.IsNullOrWhiteSpace(Href))
{
SelectClicked.InvokeAsync(e);
}
else
{
NavigationManager.NavigateTo(Href);
}
}
}