@page "/media/music/artists/{ArtistId:int}" @using System.Globalization @using ErsatzTV.Application.Artists @using ErsatzTV.Application.MediaCards @using ErsatzTV.Application.MediaCollections @using ErsatzTV.Application.ProgramSchedules @using ErsatzTV.Core.Search @using ErsatzTV.Extensions @implements IDisposable @inject IMediator Mediator @inject IDialogService Dialog @inject NavigationManager NavigationManager @inject ILogger Logger @inject ISnackbar Snackbar
@if (!string.IsNullOrWhiteSpace(_artist?.FanArt)) { fan art } else { }
@if (!string.IsNullOrWhiteSpace(_artist?.Thumbnail)) { } else { }
@_artist?.Name @_artist?.Name @_artist?.Disambiguation @if (!string.IsNullOrWhiteSpace(_artist?.Biography)) { @if (_artist.Biography.Length > 400) { @(_artist.Biography.Substring(0, 400) + "...") } else { @_artist.Biography } } else {
}
Add To Collection Add To Schedule
@if (_sortedLanguages.Any()) {
Languages:  @_sortedLanguages.Head().EnglishName @foreach (CultureInfo language in _sortedLanguages.Skip(1)) { @language.EnglishName }
} @if (_sortedGenres.Any()) {
Genres:  @_sortedGenres.Head() @foreach (string genre in _sortedGenres.Skip(1)) { @genre }
} @if (_sortedStyles.Any()) {
Styles:  @_sortedStyles.Head() @foreach (string style in _sortedStyles.Skip(1)) { @style }
} @if (_sortedMoods.Any()) {
Moods:  @_sortedMoods.Head() @foreach (string mood in _sortedMoods.Skip(1)) { @mood }
}
@foreach (MusicVideoCardViewModel musicVideo in _musicVideos.Cards) { @if (!string.IsNullOrWhiteSpace(musicVideo.Poster)) {
@if (musicVideo.State == MediaItemState.FileNotFound) {
} else if (musicVideo.State == MediaItemState.Unavailable) {
}
} else { @if (musicVideo.State is not MediaItemState.Normal and not MediaItemState.RemoteOnly) {
@if (musicVideo.State == MediaItemState.FileNotFound) {
} else if (musicVideo.State == MediaItemState.Unavailable) {
}
}
@if (musicVideo.State == MediaItemState.FileNotFound) {
} else if (musicVideo.State == MediaItemState.Unavailable) {
}
}
@musicVideo.Title @if (!string.IsNullOrWhiteSpace(musicVideo.Album)) {
Album:  @musicVideo.Album
} @musicVideo.Plot
Add To Collection
@if (musicVideo.State == MediaItemState.FileNotFound) {
File Not Found:  @musicVideo.Path
} else if (musicVideo.State == MediaItemState.Unavailable) {
Unavailable:  @musicVideo.LocalPath
}
}
@code { private CancellationTokenSource _cts; [Parameter] public int ArtistId { get; set; } private ArtistViewModel _artist; private List _sortedLanguages = []; private List _sortedGenres = []; private List _sortedStyles = []; private List _sortedMoods = []; private MusicVideoCardResultsViewModel _musicVideos = new(0, [], new SearchPageMap([])); public void Dispose() { _cts?.Cancel(); _cts?.Dispose(); } protected override async Task OnParametersSetAsync() { _cts?.Cancel(); _cts?.Dispose(); _cts = new CancellationTokenSource(); var token = _cts.Token; try { await Mediator.Send(new GetArtistById(ArtistId), token).IfSomeAsync(vm => { _artist = vm; _sortedLanguages = _artist.Languages.OrderBy(ci => ci.EnglishName).ToList(); _sortedGenres = _artist.Genres.OrderBy(g => g).ToList(); _sortedStyles = _artist.Styles.OrderBy(s => s).ToList(); _sortedMoods = _artist.Moods.OrderBy(m => m).ToList(); }); _musicVideos = await Mediator.Send(new GetMusicVideoCards(ArtistId, 1, 100), token); } catch (OperationCanceledException) { // do nothing } } private async Task AddToCollection() { var parameters = new DialogParameters { { "EntityType", "artist" }, { "EntityName", _artist.Name } }; var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall }; IDialogReference dialog = await Dialog.ShowAsync("Add To Collection", parameters, options); DialogResult result = await dialog.Result; if (result is { Canceled: false, Data: MediaCollectionViewModel collection }) { await Mediator.Send(new AddArtistToCollection(collection.Id, ArtistId), _cts.Token); NavigationManager.NavigateTo($"media/collections/{collection.Id}"); } } private async Task AddToSchedule() { var parameters = new DialogParameters { { "EntityType", "artist" }, { "EntityName", _artist.Name } }; var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall }; IDialogReference dialog = await Dialog.ShowAsync("Add To Schedule", parameters, options); DialogResult result = await dialog.Result; if (result is { Canceled: false, Data: ProgramScheduleViewModel schedule }) { await Mediator.Send(AddProgramScheduleItem.ForMediaItem(schedule.Id, CollectionType.Artist, ArtistId), _cts.Token); NavigationManager.NavigateTo($"schedules/{schedule.Id}/items"); } } private async Task AddMusicVideoToCollection(MusicVideoCardViewModel musicVideo) { var parameters = new DialogParameters { { "EntityType", "music video" }, { "EntityName", musicVideo.Title } }; var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall }; IDialogReference dialog = await Dialog.ShowAsync("Add To Collection", parameters, options); DialogResult result = await dialog.Result; if (result is { Canceled: false, Data: MediaCollectionViewModel collection }) { var request = new AddMusicVideoToCollection(collection.Id, musicVideo.MusicVideoId); Either addResult = await Mediator.Send(request, _cts.Token); addResult.Match( Left: error => { Snackbar.Add($"Unexpected error adding music video to collection: {error.Value}"); Logger.LogError("Unexpected error adding music video to collection: {Error}", error.Value); }, Right: _ => Snackbar.Add($"Added {musicVideo.Title} to collection {collection.Name}", Severity.Success)); } } }