Browse Source

more add to playlist buttons; fix playlist preview (#1693)

pull/1694/head
Jason Dove 2 years ago committed by GitHub
parent
commit
a6d5df3ca6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 5
      ErsatzTV.Application/MediaCollections/Commands/AddEpisodeToPlaylist.cs
  2. 59
      ErsatzTV.Application/MediaCollections/Commands/AddEpisodeToPlaylistHandler.cs
  3. 5
      ErsatzTV.Application/MediaCollections/Commands/AddSeasonToPlaylist.cs
  4. 59
      ErsatzTV.Application/MediaCollections/Commands/AddSeasonToPlaylistHandler.cs
  5. 5
      ErsatzTV.Application/MediaCollections/Commands/AddShowToPlaylist.cs
  6. 59
      ErsatzTV.Application/MediaCollections/Commands/AddShowToPlaylistHandler.cs
  7. 6
      ErsatzTV.Core.Tests/Fakes/FakeMediaCollectionRepository.cs
  8. 6
      ErsatzTV.Core/Interfaces/Repositories/IMediaCollectionRepository.cs
  9. 30
      ErsatzTV.Core/Scheduling/CollectionKey.cs
  10. 36
      ErsatzTV.Core/Scheduling/MediaItemsForCollection.cs
  11. 37
      ErsatzTV.Infrastructure/Data/Repositories/MediaCollectionRepository.cs
  12. 7
      ErsatzTV/Pages/EpisodeList.razor
  13. 7
      ErsatzTV/Pages/ImageList.razor
  14. 7
      ErsatzTV/Pages/MovieList.razor
  15. 7
      ErsatzTV/Pages/MusicVideoList.razor
  16. 7
      ErsatzTV/Pages/OtherVideoList.razor
  17. 7
      ErsatzTV/Pages/SongList.razor
  18. 49
      ErsatzTV/Pages/TelevisionEpisodeList.razor
  19. 21
      ErsatzTV/Pages/TelevisionSeasonList.razor
  20. 7
      ErsatzTV/Pages/TelevisionShowList.razor

5
ErsatzTV.Application/MediaCollections/Commands/AddEpisodeToPlaylist.cs

@ -0,0 +1,5 @@ @@ -0,0 +1,5 @@
using ErsatzTV.Core;
namespace ErsatzTV.Application.MediaCollections;
public record AddEpisodeToPlaylist(int PlaylistId, int EpisodeId) : IRequest<Either<BaseError, Unit>>;

59
ErsatzTV.Application/MediaCollections/Commands/AddEpisodeToPlaylistHandler.cs

@ -0,0 +1,59 @@ @@ -0,0 +1,59 @@
using ErsatzTV.Core;
using ErsatzTV.Core.Domain;
using ErsatzTV.Infrastructure.Data;
using ErsatzTV.Infrastructure.Extensions;
using Microsoft.EntityFrameworkCore;
namespace ErsatzTV.Application.MediaCollections;
public class AddEpisodeToPlaylistHandler(IDbContextFactory<TvContext> dbContextFactory)
: IRequestHandler<AddEpisodeToPlaylist, Either<BaseError, Unit>>
{
public async Task<Either<BaseError, Unit>> Handle(
AddEpisodeToPlaylist request,
CancellationToken cancellationToken)
{
await using TvContext dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken);
Validation<BaseError, Parameters> validation = await Validate(dbContext, request);
return await validation.Apply(parameters => ApplyAddEpisodeRequest(dbContext, parameters));
}
private static async Task<Unit> ApplyAddEpisodeRequest(TvContext dbContext, Parameters parameters)
{
var playlistItem = new PlaylistItem
{
Index = parameters.Playlist.Items.Max(i => i.Index) + 1,
CollectionType = ProgramScheduleItemCollectionType.Episode,
MediaItemId = parameters.Episode.Id,
PlaybackOrder = PlaybackOrder.Shuffle,
IncludeInProgramGuide = true
};
parameters.Playlist.Items.Add(playlistItem);
await dbContext.SaveChangesAsync();
return Unit.Default;
}
private static async Task<Validation<BaseError, Parameters>> Validate(
TvContext dbContext,
AddEpisodeToPlaylist request) =>
(await PlaylistMustExist(dbContext, request), await ValidateEpisode(dbContext, request))
.Apply((collection, episode) => new Parameters(collection, episode));
private static Task<Validation<BaseError, Playlist>> PlaylistMustExist(
TvContext dbContext,
AddEpisodeToPlaylist request) =>
dbContext.Playlists
.Include(c => c.Items)
.SelectOneAsync(c => c.Id, c => c.Id == request.PlaylistId)
.Map(o => o.ToValidation<BaseError>("Playlist does not exist."));
private static Task<Validation<BaseError, Episode>> ValidateEpisode(
TvContext dbContext,
AddEpisodeToPlaylist request) =>
dbContext.Episodes
.SelectOneAsync(m => m.Id, e => e.Id == request.EpisodeId)
.Map(o => o.ToValidation<BaseError>("Episode does not exist"));
private sealed record Parameters(Playlist Playlist, Episode Episode);
}

5
ErsatzTV.Application/MediaCollections/Commands/AddSeasonToPlaylist.cs

@ -0,0 +1,5 @@ @@ -0,0 +1,5 @@
using ErsatzTV.Core;
namespace ErsatzTV.Application.MediaCollections;
public record AddSeasonToPlaylist(int PlaylistId, int SeasonId) : IRequest<Either<BaseError, Unit>>;

59
ErsatzTV.Application/MediaCollections/Commands/AddSeasonToPlaylistHandler.cs

@ -0,0 +1,59 @@ @@ -0,0 +1,59 @@
using ErsatzTV.Core;
using ErsatzTV.Core.Domain;
using ErsatzTV.Infrastructure.Data;
using ErsatzTV.Infrastructure.Extensions;
using Microsoft.EntityFrameworkCore;
namespace ErsatzTV.Application.MediaCollections;
public class AddSeasonToPlaylistHandler(IDbContextFactory<TvContext> dbContextFactory)
: IRequestHandler<AddSeasonToPlaylist, Either<BaseError, Unit>>
{
public async Task<Either<BaseError, Unit>> Handle(
AddSeasonToPlaylist request,
CancellationToken cancellationToken)
{
await using TvContext dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken);
Validation<BaseError, Parameters> validation = await Validate(dbContext, request);
return await validation.Apply(parameters => ApplyAddSeasonRequest(dbContext, parameters));
}
private static async Task<Unit> ApplyAddSeasonRequest(TvContext dbContext, Parameters parameters)
{
var playlistItem = new PlaylistItem
{
Index = parameters.Playlist.Items.Max(i => i.Index) + 1,
CollectionType = ProgramScheduleItemCollectionType.TelevisionSeason,
MediaItemId = parameters.Season.Id,
PlaybackOrder = PlaybackOrder.Shuffle,
IncludeInProgramGuide = true
};
parameters.Playlist.Items.Add(playlistItem);
await dbContext.SaveChangesAsync();
return Unit.Default;
}
private static async Task<Validation<BaseError, Parameters>> Validate(
TvContext dbContext,
AddSeasonToPlaylist request) =>
(await PlaylistMustExist(dbContext, request), await ValidateSeason(dbContext, request))
.Apply((collection, episode) => new Parameters(collection, episode));
private static Task<Validation<BaseError, Playlist>> PlaylistMustExist(
TvContext dbContext,
AddSeasonToPlaylist request) =>
dbContext.Playlists
.Include(c => c.Items)
.SelectOneAsync(c => c.Id, c => c.Id == request.PlaylistId)
.Map(o => o.ToValidation<BaseError>("Playlist does not exist."));
private static Task<Validation<BaseError, Season>> ValidateSeason(
TvContext dbContext,
AddSeasonToPlaylist request) =>
dbContext.Seasons
.SelectOneAsync(m => m.Id, e => e.Id == request.SeasonId)
.Map(o => o.ToValidation<BaseError>("Season does not exist"));
private sealed record Parameters(Playlist Playlist, Season Season);
}

5
ErsatzTV.Application/MediaCollections/Commands/AddShowToPlaylist.cs

@ -0,0 +1,5 @@ @@ -0,0 +1,5 @@
using ErsatzTV.Core;
namespace ErsatzTV.Application.MediaCollections;
public record AddShowToPlaylist(int PlaylistId, int ShowId) : IRequest<Either<BaseError, Unit>>;

59
ErsatzTV.Application/MediaCollections/Commands/AddShowToPlaylistHandler.cs

@ -0,0 +1,59 @@ @@ -0,0 +1,59 @@
using ErsatzTV.Core;
using ErsatzTV.Core.Domain;
using ErsatzTV.Infrastructure.Data;
using ErsatzTV.Infrastructure.Extensions;
using Microsoft.EntityFrameworkCore;
namespace ErsatzTV.Application.MediaCollections;
public class AddShowToPlaylistHandler(IDbContextFactory<TvContext> dbContextFactory)
: IRequestHandler<AddShowToPlaylist, Either<BaseError, Unit>>
{
public async Task<Either<BaseError, Unit>> Handle(
AddShowToPlaylist request,
CancellationToken cancellationToken)
{
await using TvContext dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken);
Validation<BaseError, Parameters> validation = await Validate(dbContext, request);
return await validation.Apply(parameters => ApplyAddShowRequest(dbContext, parameters));
}
private static async Task<Unit> ApplyAddShowRequest(TvContext dbContext, Parameters parameters)
{
var playlistItem = new PlaylistItem
{
Index = parameters.Playlist.Items.Max(i => i.Index) + 1,
CollectionType = ProgramScheduleItemCollectionType.TelevisionShow,
MediaItemId = parameters.Show.Id,
PlaybackOrder = PlaybackOrder.Shuffle,
IncludeInProgramGuide = true
};
parameters.Playlist.Items.Add(playlistItem);
await dbContext.SaveChangesAsync();
return Unit.Default;
}
private static async Task<Validation<BaseError, Parameters>> Validate(
TvContext dbContext,
AddShowToPlaylist request) =>
(await PlaylistMustExist(dbContext, request), await ValidateShow(dbContext, request))
.Apply((collection, episode) => new Parameters(collection, episode));
private static Task<Validation<BaseError, Playlist>> PlaylistMustExist(
TvContext dbContext,
AddShowToPlaylist request) =>
dbContext.Playlists
.Include(c => c.Items)
.SelectOneAsync(c => c.Id, c => c.Id == request.PlaylistId)
.Map(o => o.ToValidation<BaseError>("Playlist does not exist."));
private static Task<Validation<BaseError, Show>> ValidateShow(
TvContext dbContext,
AddShowToPlaylist request) =>
dbContext.Shows
.SelectOneAsync(m => m.Id, e => e.Id == request.ShowId)
.Map(o => o.ToValidation<BaseError>("Show does not exist"));
private sealed record Parameters(Playlist Playlist, Show Show);
}

6
ErsatzTV.Core.Tests/Fakes/FakeMediaCollectionRepository.cs

@ -20,6 +20,12 @@ public class FakeMediaCollectionRepository : IMediaCollectionRepository @@ -20,6 +20,12 @@ public class FakeMediaCollectionRepository : IMediaCollectionRepository
public Task<List<MediaItem>> GetMultiCollectionItems(int id) => throw new NotSupportedException();
public Task<List<MediaItem>> GetSmartCollectionItems(int id) => _data[id].ToList().AsTask();
public Task<List<MediaItem>> GetPlaylistItems(int id) => throw new NotSupportedException();
public Task<List<Movie>> GetMovie(int id) => throw new NotSupportedException();
public Task<List<Episode>> GetEpisode(int id) => throw new NotSupportedException();
public Task<List<MusicVideo>> GetMusicVideo(int id) => throw new NotSupportedException();
public Task<List<OtherVideo>> GetOtherVideo(int id) => throw new NotSupportedException();
public Task<List<Song>> GetSong(int id) => throw new NotSupportedException();
public Task<List<Image>> GetImage(int id) => throw new NotSupportedException();
public Task<List<CollectionWithItems>> GetMultiCollectionCollections(int id) =>
throw new NotSupportedException();

6
ErsatzTV.Core/Interfaces/Repositories/IMediaCollectionRepository.cs

@ -11,6 +11,12 @@ public interface IMediaCollectionRepository @@ -11,6 +11,12 @@ public interface IMediaCollectionRepository
Task<List<MediaItem>> GetMultiCollectionItems(int id);
Task<List<MediaItem>> GetSmartCollectionItems(int id);
Task<List<MediaItem>> GetPlaylistItems(int id);
Task<List<Movie>> GetMovie(int id);
Task<List<Episode>> GetEpisode(int id);
Task<List<MusicVideo>> GetMusicVideo(int id);
Task<List<OtherVideo>> GetOtherVideo(int id);
Task<List<Song>> GetSong(int id);
Task<List<Image>> GetImage(int id);
Task<List<CollectionWithItems>> GetMultiCollectionCollections(int id);
Task<List<CollectionWithItems>> GetFakeMultiCollectionCollections(int? collectionId, int? smartCollectionId);
Task<List<int>> PlayoutIdsUsingCollection(int collectionId);

30
ErsatzTV.Core/Scheduling/CollectionKey.cs

@ -121,6 +121,36 @@ public class CollectionKey : Record<CollectionKey> @@ -121,6 +121,36 @@ public class CollectionKey : Record<CollectionKey>
{
CollectionType = item.CollectionType
},
ProgramScheduleItemCollectionType.Movie => new CollectionKey
{
CollectionType = item.CollectionType,
MediaItemId = item.MediaItemId
},
ProgramScheduleItemCollectionType.Episode => new CollectionKey
{
CollectionType = item.CollectionType,
MediaItemId = item.MediaItemId
},
ProgramScheduleItemCollectionType.MusicVideo => new CollectionKey
{
CollectionType = item.CollectionType,
MediaItemId = item.MediaItemId
},
ProgramScheduleItemCollectionType.OtherVideo => new CollectionKey
{
CollectionType = item.CollectionType,
MediaItemId = item.MediaItemId
},
ProgramScheduleItemCollectionType.Song => new CollectionKey
{
CollectionType = item.CollectionType,
MediaItemId = item.MediaItemId
},
ProgramScheduleItemCollectionType.Image => new CollectionKey
{
CollectionType = item.CollectionType,
MediaItemId = item.MediaItemId
},
_ => throw new ArgumentOutOfRangeException(nameof(item))
};

36
ErsatzTV.Core/Scheduling/MediaItemsForCollection.cs

@ -41,6 +41,42 @@ public static class MediaItemsForCollection @@ -41,6 +41,42 @@ public static class MediaItemsForCollection
result.AddRange(
await mediaCollectionRepository.GetPlaylistItems(collectionKey.PlaylistId ?? 0));
break;
case ProgramScheduleItemCollectionType.Movie:
foreach (int mediaItemId in Optional(collectionKey.MediaItemId))
{
result.AddRange(await mediaCollectionRepository.GetMovie(mediaItemId));
}
break;
case ProgramScheduleItemCollectionType.Episode:
foreach (int mediaItemId in Optional(collectionKey.MediaItemId))
{
result.AddRange(await mediaCollectionRepository.GetEpisode(mediaItemId));
}
break;
case ProgramScheduleItemCollectionType.MusicVideo:
foreach (int mediaItemId in Optional(collectionKey.MediaItemId))
{
result.AddRange(await mediaCollectionRepository.GetMusicVideo(mediaItemId));
}
break;
case ProgramScheduleItemCollectionType.OtherVideo:
foreach (int mediaItemId in Optional(collectionKey.MediaItemId))
{
result.AddRange(await mediaCollectionRepository.GetOtherVideo(mediaItemId));
}
break;
case ProgramScheduleItemCollectionType.Song:
foreach (int mediaItemId in Optional(collectionKey.MediaItemId))
{
result.AddRange(await mediaCollectionRepository.GetSong(mediaItemId));
}
break;
case ProgramScheduleItemCollectionType.Image:
foreach (int mediaItemId in Optional(collectionKey.MediaItemId))
{
result.AddRange(await mediaCollectionRepository.GetImage(mediaItemId));
}
break;
default:
throw new ArgumentOutOfRangeException(nameof(collectionKey));
}

37
ErsatzTV.Infrastructure/Data/Repositories/MediaCollectionRepository.cs

@ -501,6 +501,41 @@ public class MediaCollectionRepository : IMediaCollectionRepository @@ -501,6 +501,41 @@ public class MediaCollectionRepository : IMediaCollectionRepository
return result.DistinctBy(x => x.Id).ToList();
}
public async Task<List<Movie>> GetMovie(int id)
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync();
return await GetMovieItems(dbContext, [id]);
}
public async Task<List<Episode>> GetEpisode(int id)
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync();
return await GetEpisodeItems(dbContext, [id]);
}
public async Task<List<MusicVideo>> GetMusicVideo(int id)
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync();
return await GetMusicVideoItems(dbContext, [id]);
}
public async Task<List<OtherVideo>> GetOtherVideo(int id)
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync();
return await GetOtherVideoItems(dbContext, [id]);
}
public async Task<List<Song>> GetSong(int id)
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync();
return await GetSongItems(dbContext, [id]);
}
public async Task<List<Image>> GetImage(int id)
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync();
return await GetImageItems(dbContext, [id]);
}
public async Task<List<CollectionWithItems>> GetFakeMultiCollectionCollections(
int? collectionId,
@ -738,7 +773,7 @@ public class MediaCollectionRepository : IMediaCollectionRepository @@ -738,7 +773,7 @@ public class MediaCollectionRepository : IMediaCollectionRepository
return await GetMovieItems(dbContext, ids);
}
private static Task<List<Movie>> GetMovieItems(TvContext dbContext, IEnumerable<int> movieIds) =>
dbContext.Movies
.Include(m => m.MovieMetadata)

7
ErsatzTV/Pages/EpisodeList.razor

@ -20,6 +20,13 @@ @@ -20,6 +20,13 @@
OnClick="@(_ => AddSelectionToCollection())">
Add To Collection
</MudButton>
<MudButton Class="ml-3"
Variant="Variant.Filled"
Color="Color.Primary"
StartIcon="@Icons.Material.Filled.PlaylistAdd"
OnClick="@(_ => AddSelectionToPlaylist())">
Add To Playlist
</MudButton>
<MudButton Class="ml-3"
Variant="Variant.Filled"
Color="Color.Secondary"

7
ErsatzTV/Pages/ImageList.razor

@ -19,6 +19,13 @@ @@ -19,6 +19,13 @@
OnClick="@(_ => AddSelectionToCollection())">
Add To Collection
</MudButton>
<MudButton Class="ml-3"
Variant="Variant.Filled"
Color="Color.Primary"
StartIcon="@Icons.Material.Filled.PlaylistAdd"
OnClick="@(_ => AddSelectionToPlaylist())">
Add To Playlist
</MudButton>
<MudButton Class="ml-3"
Variant="Variant.Filled"
Color="Color.Secondary"

7
ErsatzTV/Pages/MovieList.razor

@ -21,6 +21,13 @@ @@ -21,6 +21,13 @@
OnClick="@(_ => AddSelectionToCollection())">
Add To Collection
</MudButton>
<MudButton Class="ml-3"
Variant="Variant.Filled"
Color="Color.Primary"
StartIcon="@Icons.Material.Filled.PlaylistAdd"
OnClick="@(_ => AddSelectionToPlaylist())">
Add To Playlist
</MudButton>
<MudButton Class="ml-3"
Variant="Variant.Filled"
Color="Color.Secondary"

7
ErsatzTV/Pages/MusicVideoList.razor

@ -20,6 +20,13 @@ @@ -20,6 +20,13 @@
OnClick="@(_ => AddSelectionToCollection())">
Add To Collection
</MudButton>
<MudButton Class="ml-3"
Variant="Variant.Filled"
Color="Color.Primary"
StartIcon="@Icons.Material.Filled.PlaylistAdd"
OnClick="@(_ => AddSelectionToPlaylist())">
Add To Playlist
</MudButton>
<MudButton Class="ml-3"
Variant="Variant.Filled"
Color="Color.Secondary"

7
ErsatzTV/Pages/OtherVideoList.razor

@ -19,6 +19,13 @@ @@ -19,6 +19,13 @@
OnClick="@(_ => AddSelectionToCollection())">
Add To Collection
</MudButton>
<MudButton Class="ml-3"
Variant="Variant.Filled"
Color="Color.Primary"
StartIcon="@Icons.Material.Filled.PlaylistAdd"
OnClick="@(_ => AddSelectionToPlaylist())">
Add To Playlist
</MudButton>
<MudButton Class="ml-3"
Variant="Variant.Filled"
Color="Color.Secondary"

7
ErsatzTV/Pages/SongList.razor

@ -20,6 +20,13 @@ @@ -20,6 +20,13 @@
OnClick="@(_ => AddSelectionToCollection())">
Add To Collection
</MudButton>
<MudButton Class="ml-3"
Variant="Variant.Filled"
Color="Color.Primary"
StartIcon="@Icons.Material.Filled.PlaylistAdd"
OnClick="@(_ => AddSelectionToPlaylist())">
Add To Playlist
</MudButton>
<MudButton Class="ml-3"
Variant="Variant.Filled"
Color="Color.Secondary"

49
ErsatzTV/Pages/TelevisionEpisodeList.razor

@ -56,6 +56,13 @@ @@ -56,6 +56,13 @@
OnClick="@AddToCollection">
Add To Collection
</MudButton>
<MudButton Class="ml-3"
Variant="Variant.Filled"
Color="Color.Primary"
StartIcon="@Icons.Material.Filled.PlaylistAdd"
OnClick="@AddToPlaylist">
Add To Playlist
</MudButton>
<MudButton Class="ml-3"
Variant="Variant.Filled"
Color="Color.Primary"
@ -109,6 +116,14 @@ @@ -109,6 +116,14 @@
Add To Collection
</MudButton>
</div>
<div class="mt-6">
<MudButton Variant="Variant.Filled"
Color="Color.Primary"
StartIcon="@Icons.Material.Filled.PlaylistAdd"
OnClick="@(_ => AddEpisodeToPlaylist(episode))">
Add To Playlist
</MudButton>
</div>
<div class="mt-6">
<MudButton Variant="Variant.Filled"
Color="Color.Secondary"
@ -230,7 +245,20 @@ @@ -230,7 +245,20 @@
_navigationManager.NavigateTo($"media/collections/{collection.Id}");
}
}
private async Task AddToPlaylist()
{
var parameters = new DialogParameters { { "EntityType", "season" }, { "EntityName", $"{_season.Title} - {_season.Name}" } };
var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall };
IDialogReference dialog = await _dialog.ShowAsync<AddToPlaylistDialog>("Add To Playlist", parameters, options);
DialogResult result = await dialog.Result;
if (!result.Canceled && result.Data is PlaylistViewModel playlist)
{
await _mediator.Send(new AddSeasonToPlaylist(playlist.Id, SeasonId), _cts.Token);
_navigationManager.NavigateTo($"media/playlists/{playlist.Id}");
}
}
private async Task AddToSchedule()
{
@ -266,6 +294,27 @@ @@ -266,6 +294,27 @@
Right: _ => _snackbar.Add($"Added {episode.Title} to collection {collection.Name}", Severity.Success));
}
}
private async Task AddEpisodeToPlaylist(TelevisionEpisodeCardViewModel episode)
{
var parameters = new DialogParameters { { "EntityType", "episode" }, { "EntityName", episode.Title } };
var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall };
IDialogReference dialog = await _dialog.ShowAsync<AddToPlaylistDialog>("Add To Playlist", parameters, options);
DialogResult result = await dialog.Result;
if (!result.Canceled && result.Data is PlaylistViewModel playlist)
{
var request = new AddEpisodeToPlaylist(playlist.Id, episode.EpisodeId);
Either<BaseError, Unit> addResult = await _mediator.Send(request, _cts.Token);
addResult.Match(
Left: error =>
{
_snackbar.Add($"Unexpected error adding episode to playlist: {error.Value}");
_logger.LogError("Unexpected error adding episode to playlist: {Error}", error.Value);
},
Right: _ => _snackbar.Add($"Added {episode.Title} to playlist {playlist.Name}", Severity.Success));
}
}
private async Task ShowInfo(TelevisionEpisodeCardViewModel episode)
{

21
ErsatzTV/Pages/TelevisionSeasonList.razor

@ -62,6 +62,13 @@ @@ -62,6 +62,13 @@
OnClick="@AddToCollection">
Add To Collection
</MudButton>
<MudButton Class="ml-3"
Variant="Variant.Filled"
Color="Color.Primary"
StartIcon="@Icons.Material.Filled.PlaylistAdd"
OnClick="@AddToPlaylist">
Add To Playlist
</MudButton>
<MudButton Class="ml-3"
Variant="Variant.Filled"
Color="Color.Primary"
@ -220,6 +227,20 @@ @@ -220,6 +227,20 @@
}
}
private async Task AddToPlaylist()
{
var parameters = new DialogParameters { { "EntityType", "show" }, { "EntityName", _show.Title } };
var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall };
IDialogReference dialog = await _dialog.ShowAsync<AddToPlaylistDialog>("Add To Playlist", parameters, options);
DialogResult result = await dialog.Result;
if (!result.Canceled && result.Data is PlaylistViewModel playlist)
{
await _mediator.Send(new AddShowToPlaylist(playlist.Id, ShowId), _cts.Token);
_navigationManager.NavigateTo($"media/playlists/{playlist.Id}");
}
}
private async Task AddToSchedule()
{
var parameters = new DialogParameters { { "EntityType", "show" }, { "EntityName", _show.Title } };

7
ErsatzTV/Pages/TelevisionShowList.razor

@ -21,6 +21,13 @@ @@ -21,6 +21,13 @@
OnClick="@(_ => AddSelectionToCollection())">
Add To Collection
</MudButton>
<MudButton Class="ml-3"
Variant="Variant.Filled"
Color="Color.Primary"
StartIcon="@Icons.Material.Filled.PlaylistAdd"
OnClick="@(_ => AddSelectionToPlaylist())">
Add To Playlist
</MudButton>
<MudButton Class="ml-3"
Variant="Variant.Filled"
Color="Color.Secondary"

Loading…
Cancel
Save