176 lines
6.4 KiB
Plaintext
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);
|
|
}
|
|
}
|
|
} |