diff --git a/ErsatzTV.Application/MediaCollections/Commands/AddEpisodeToCollectionHandler.cs b/ErsatzTV.Application/MediaCollections/Commands/AddEpisodeToCollectionHandler.cs index 00c9abaeb..8b41da6cc 100644 --- a/ErsatzTV.Application/MediaCollections/Commands/AddEpisodeToCollectionHandler.cs +++ b/ErsatzTV.Application/MediaCollections/Commands/AddEpisodeToCollectionHandler.cs @@ -1,5 +1,7 @@ using System.Threading; +using System.Threading.Channels; using System.Threading.Tasks; +using ErsatzTV.Application.Playouts.Commands; using ErsatzTV.Core; using ErsatzTV.Core.Interfaces.Repositories; using LanguageExt; @@ -9,15 +11,18 @@ namespace ErsatzTV.Application.MediaCollections.Commands public class AddEpisodeToCollectionHandler : MediatR.IRequestHandler> { + private readonly ChannelWriter _channel; private readonly IMediaCollectionRepository _mediaCollectionRepository; private readonly ITelevisionRepository _televisionRepository; public AddEpisodeToCollectionHandler( IMediaCollectionRepository mediaCollectionRepository, - ITelevisionRepository televisionRepository) + ITelevisionRepository televisionRepository, + ChannelWriter channel) { _mediaCollectionRepository = mediaCollectionRepository; _televisionRepository = televisionRepository; + _channel = channel; } public Task> Handle( @@ -27,8 +32,20 @@ namespace ErsatzTV.Application.MediaCollections.Commands .MapT(_ => ApplyAddTelevisionEpisodeRequest(request)) .Bind(v => v.ToEitherAsync()); - private Task ApplyAddTelevisionEpisodeRequest(AddEpisodeToCollection request) => - _mediaCollectionRepository.AddMediaItem(request.CollectionId, request.EpisodeId); + private async Task ApplyAddTelevisionEpisodeRequest(AddEpisodeToCollection request) + { + if (await _mediaCollectionRepository.AddMediaItem(request.CollectionId, request.EpisodeId)) + { + // rebuild all playouts that use this collection + foreach (int playoutId in await _mediaCollectionRepository + .PlayoutIdsUsingCollection(request.CollectionId)) + { + await _channel.WriteAsync(new BuildPlayout(playoutId, true)); + } + } + + return Unit.Default; + } private async Task> Validate(AddEpisodeToCollection request) => (await CollectionMustExist(request), await ValidateEpisode(request)) diff --git a/ErsatzTV.Application/MediaCollections/Commands/AddMovieToCollectionHandler.cs b/ErsatzTV.Application/MediaCollections/Commands/AddMovieToCollectionHandler.cs index d0f3d521b..3f8d0225a 100644 --- a/ErsatzTV.Application/MediaCollections/Commands/AddMovieToCollectionHandler.cs +++ b/ErsatzTV.Application/MediaCollections/Commands/AddMovieToCollectionHandler.cs @@ -1,5 +1,7 @@ using System.Threading; +using System.Threading.Channels; using System.Threading.Tasks; +using ErsatzTV.Application.Playouts.Commands; using ErsatzTV.Core; using ErsatzTV.Core.Domain; using ErsatzTV.Core.Interfaces.Repositories; @@ -7,17 +9,21 @@ using LanguageExt; namespace ErsatzTV.Application.MediaCollections.Commands { - public class AddMovieToCollectionHandler : MediatR.IRequestHandler> + public class + AddMovieToCollectionHandler : MediatR.IRequestHandler> { + private readonly ChannelWriter _channel; private readonly IMediaCollectionRepository _mediaCollectionRepository; private readonly IMovieRepository _movieRepository; public AddMovieToCollectionHandler( IMediaCollectionRepository mediaCollectionRepository, - IMovieRepository movieRepository) + IMovieRepository movieRepository, + ChannelWriter channel) { _mediaCollectionRepository = mediaCollectionRepository; _movieRepository = movieRepository; + _channel = channel; } public Task> Handle( @@ -27,8 +33,20 @@ namespace ErsatzTV.Application.MediaCollections.Commands .MapT(_ => ApplyAddMoviesRequest(request)) .Bind(v => v.ToEitherAsync()); - private Task ApplyAddMoviesRequest(AddMovieToCollection request) => - _mediaCollectionRepository.AddMediaItem(request.CollectionId, request.MovieId); + private async Task ApplyAddMoviesRequest(AddMovieToCollection request) + { + if (await _mediaCollectionRepository.AddMediaItem(request.CollectionId, request.MovieId)) + { + // rebuild all playouts that use this collection + foreach (int playoutId in await _mediaCollectionRepository + .PlayoutIdsUsingCollection(request.CollectionId)) + { + await _channel.WriteAsync(new BuildPlayout(playoutId, true)); + } + } + + return Unit.Default; + } private async Task> Validate(AddMovieToCollection request) => (await CollectionMustExist(request), await ValidateMovies(request)) diff --git a/ErsatzTV.Application/MediaCollections/Commands/AddSeasonToCollectionHandler.cs b/ErsatzTV.Application/MediaCollections/Commands/AddSeasonToCollectionHandler.cs index 4812be04b..b677da943 100644 --- a/ErsatzTV.Application/MediaCollections/Commands/AddSeasonToCollectionHandler.cs +++ b/ErsatzTV.Application/MediaCollections/Commands/AddSeasonToCollectionHandler.cs @@ -1,5 +1,7 @@ using System.Threading; +using System.Threading.Channels; using System.Threading.Tasks; +using ErsatzTV.Application.Playouts.Commands; using ErsatzTV.Core; using ErsatzTV.Core.Domain; using ErsatzTV.Core.Interfaces.Repositories; @@ -7,17 +9,21 @@ using LanguageExt; namespace ErsatzTV.Application.MediaCollections.Commands { - public class AddSeasonToCollectionHandler : MediatR.IRequestHandler> + public class + AddSeasonToCollectionHandler : MediatR.IRequestHandler> { + private readonly ChannelWriter _channel; private readonly IMediaCollectionRepository _mediaCollectionRepository; private readonly ITelevisionRepository _televisionRepository; public AddSeasonToCollectionHandler( IMediaCollectionRepository mediaCollectionRepository, - ITelevisionRepository televisionRepository) + ITelevisionRepository televisionRepository, + ChannelWriter channel) { _mediaCollectionRepository = mediaCollectionRepository; _televisionRepository = televisionRepository; + _channel = channel; } public Task> Handle( @@ -27,8 +33,20 @@ namespace ErsatzTV.Application.MediaCollections.Commands .MapT(_ => ApplyAddTelevisionSeasonRequest(request)) .Bind(v => v.ToEitherAsync()); - private async Task ApplyAddTelevisionSeasonRequest(AddSeasonToCollection request) => - await _mediaCollectionRepository.AddMediaItem(request.CollectionId, request.SeasonId); + private async Task ApplyAddTelevisionSeasonRequest(AddSeasonToCollection request) + { + if (await _mediaCollectionRepository.AddMediaItem(request.CollectionId, request.SeasonId)) + { + // rebuild all playouts that use this collection + foreach (int playoutId in await _mediaCollectionRepository + .PlayoutIdsUsingCollection(request.CollectionId)) + { + await _channel.WriteAsync(new BuildPlayout(playoutId, true)); + } + } + + return Unit.Default; + } private async Task> Validate(AddSeasonToCollection request) => (await CollectionMustExist(request), await ValidateSeason(request)) diff --git a/ErsatzTV.Application/MediaCollections/Commands/AddShowToCollectionHandler.cs b/ErsatzTV.Application/MediaCollections/Commands/AddShowToCollectionHandler.cs index 9c7e780a9..de77bacfa 100644 --- a/ErsatzTV.Application/MediaCollections/Commands/AddShowToCollectionHandler.cs +++ b/ErsatzTV.Application/MediaCollections/Commands/AddShowToCollectionHandler.cs @@ -1,5 +1,7 @@ using System.Threading; +using System.Threading.Channels; using System.Threading.Tasks; +using ErsatzTV.Application.Playouts.Commands; using ErsatzTV.Core; using ErsatzTV.Core.Domain; using ErsatzTV.Core.Interfaces.Repositories; @@ -9,15 +11,18 @@ namespace ErsatzTV.Application.MediaCollections.Commands { public class AddShowToCollectionHandler : MediatR.IRequestHandler> { + private readonly ChannelWriter _channel; private readonly IMediaCollectionRepository _mediaCollectionRepository; private readonly ITelevisionRepository _televisionRepository; public AddShowToCollectionHandler( IMediaCollectionRepository mediaCollectionRepository, - ITelevisionRepository televisionRepository) + ITelevisionRepository televisionRepository, + ChannelWriter channel) { _mediaCollectionRepository = mediaCollectionRepository; _televisionRepository = televisionRepository; + _channel = channel; } public Task> Handle( @@ -27,8 +32,22 @@ namespace ErsatzTV.Application.MediaCollections.Commands .MapT(_ => ApplyAddTelevisionShowRequest(request)) .Bind(v => v.ToEitherAsync()); - private Task ApplyAddTelevisionShowRequest(AddShowToCollection request) - => _mediaCollectionRepository.AddMediaItem(request.CollectionId, request.ShowId); + private async Task ApplyAddTelevisionShowRequest(AddShowToCollection request) + { + var result = new Unit(); + + if (await _mediaCollectionRepository.AddMediaItem(request.CollectionId, request.ShowId)) + { + // rebuild all playouts that use this collection + foreach (int playoutId in await _mediaCollectionRepository + .PlayoutIdsUsingCollection(request.CollectionId)) + { + await _channel.WriteAsync(new BuildPlayout(playoutId, true)); + } + } + + return result; + } private async Task> Validate(AddShowToCollection request) => (await CollectionMustExist(request), await ValidateShow(request)) diff --git a/ErsatzTV.Application/MediaCollections/Commands/RemoveItemsFromCollectionHandler.cs b/ErsatzTV.Application/MediaCollections/Commands/RemoveItemsFromCollectionHandler.cs index f4341f2bd..cab1d2a9d 100644 --- a/ErsatzTV.Application/MediaCollections/Commands/RemoveItemsFromCollectionHandler.cs +++ b/ErsatzTV.Application/MediaCollections/Commands/RemoveItemsFromCollectionHandler.cs @@ -1,6 +1,8 @@ using System.Linq; using System.Threading; +using System.Threading.Channels; using System.Threading.Tasks; +using ErsatzTV.Application.Playouts.Commands; using ErsatzTV.Core; using ErsatzTV.Core.Domain; using ErsatzTV.Core.Interfaces.Repositories; @@ -11,20 +13,25 @@ namespace ErsatzTV.Application.MediaCollections.Commands public class RemoveItemsFromCollectionHandler : MediatR.IRequestHandler> { + private readonly ChannelWriter _channel; private readonly IMediaCollectionRepository _mediaCollectionRepository; public RemoveItemsFromCollectionHandler( - IMediaCollectionRepository mediaCollectionRepository) => + IMediaCollectionRepository mediaCollectionRepository, + ChannelWriter channel) + { _mediaCollectionRepository = mediaCollectionRepository; + _channel = channel; + } public Task> Handle( RemoveItemsFromCollection request, CancellationToken cancellationToken) => Validate(request) - .MapT(collection => ApplyAddTelevisionEpisodeRequest(request, collection)) + .MapT(collection => ApplyRemoveItemsRequest(request, collection)) .Bind(v => v.ToEitherAsync()); - private Task ApplyAddTelevisionEpisodeRequest( + private async Task ApplyRemoveItemsRequest( RemoveItemsFromCollection request, Collection collection) { @@ -34,9 +41,16 @@ namespace ErsatzTV.Application.MediaCollections.Commands itemsToRemove.ForEach(m => collection.MediaItems.Remove(m)); - return itemsToRemove.Any() - ? _mediaCollectionRepository.Update(collection).ToUnit() - : Task.FromResult(Unit.Default); + if (itemsToRemove.Any() && await _mediaCollectionRepository.Update(collection)) + { + // rebuild all playouts that use this collection + foreach (int playoutId in await _mediaCollectionRepository.PlayoutIdsUsingCollection(collection.Id)) + { + await _channel.WriteAsync(new BuildPlayout(playoutId, true)); + } + } + + return Unit.Default; } private Task> Validate( diff --git a/ErsatzTV.Core.Tests/Fakes/FakeMediaCollectionRepository.cs b/ErsatzTV.Core.Tests/Fakes/FakeMediaCollectionRepository.cs index 8a94581a2..2323eaa8b 100644 --- a/ErsatzTV.Core.Tests/Fakes/FakeMediaCollectionRepository.cs +++ b/ErsatzTV.Core.Tests/Fakes/FakeMediaCollectionRepository.cs @@ -14,23 +14,15 @@ namespace ErsatzTV.Core.Tests.Fakes private readonly Map> _data; public FakeMediaCollectionRepository(Map> data) => _data = data; - public Task Add(Collection collection) => throw new NotSupportedException(); - public Task AddMediaItem(int collectionId, int mediaItemId) => throw new NotSupportedException(); - + public Task AddMediaItem(int collectionId, int mediaItemId) => throw new NotSupportedException(); public Task> Get(int id) => throw new NotSupportedException(); - public Task> GetCollectionWithItems(int id) => throw new NotSupportedException(); - public Task> GetCollectionWithItemsUntracked(int id) => throw new NotSupportedException(); - public Task> GetAll() => throw new NotSupportedException(); - public Task>> GetItems(int id) => Some(_data[id].ToList()).AsTask(); - - public Task Update(Collection collection) => throw new NotSupportedException(); - + Task IMediaCollectionRepository.Update(Collection collection) => throw new NotSupportedException(); public Task Delete(int collectionId) => throw new NotSupportedException(); - public Task>> GetSimpleMediaCollectionItems(int id) => throw new NotSupportedException(); + public Task> PlayoutIdsUsingCollection(int collectionId) => throw new NotSupportedException(); } } diff --git a/ErsatzTV.Core/Interfaces/Repositories/IMediaCollectionRepository.cs b/ErsatzTV.Core/Interfaces/Repositories/IMediaCollectionRepository.cs index 248fa0764..60ddbc70e 100644 --- a/ErsatzTV.Core/Interfaces/Repositories/IMediaCollectionRepository.cs +++ b/ErsatzTV.Core/Interfaces/Repositories/IMediaCollectionRepository.cs @@ -8,13 +8,14 @@ namespace ErsatzTV.Core.Interfaces.Repositories public interface IMediaCollectionRepository { Task Add(Collection collection); - Task AddMediaItem(int collectionId, int mediaItemId); + Task AddMediaItem(int collectionId, int mediaItemId); Task> Get(int id); Task> GetCollectionWithItems(int id); Task> GetCollectionWithItemsUntracked(int id); Task> GetAll(); Task>> GetItems(int id); - Task Update(Collection collection); + Task Update(Collection collection); Task Delete(int collectionId); + Task> PlayoutIdsUsingCollection(int collectionId); } } diff --git a/ErsatzTV.Core/Iptv/ChannelGuide.cs b/ErsatzTV.Core/Iptv/ChannelGuide.cs index 11289b785..fbdb59e0a 100644 --- a/ErsatzTV.Core/Iptv/ChannelGuide.cs +++ b/ErsatzTV.Core/Iptv/ChannelGuide.cs @@ -62,15 +62,18 @@ namespace ErsatzTV.Core.Iptv string title = playoutItem.MediaItem switch { - Movie m => m.MovieMetadata.HeadOrNone().Map(mm => mm.Title ?? string.Empty).IfNone("[unknown movie]"), - Episode e => e.EpisodeMetadata.HeadOrNone().Map(em => em.Title ?? string.Empty).IfNone("[unknown episode]"), + Movie m => m.MovieMetadata.HeadOrNone().Map(mm => mm.Title ?? string.Empty) + .IfNone("[unknown movie]"), + Episode e => e.EpisodeMetadata.HeadOrNone().Map(em => em.Title ?? string.Empty) + .IfNone("[unknown episode]"), _ => "[unknown]" }; string description = playoutItem.MediaItem switch { Movie m => m.MovieMetadata.HeadOrNone().Map(mm => mm.Plot ?? string.Empty).IfNone(string.Empty), - Episode e => e.EpisodeMetadata.HeadOrNone().Map(em => em.Plot ?? string.Empty).IfNone(string.Empty), + Episode e => e.EpisodeMetadata.HeadOrNone().Map(em => em.Plot ?? string.Empty) + .IfNone(string.Empty), _ => string.Empty }; @@ -108,7 +111,7 @@ namespace ErsatzTV.Core.Iptv xml.WriteAttributeString("system", "onscreen"); xml.WriteString($"S{s:00}E{e:00}"); xml.WriteEndElement(); // episode-num - + xml.WriteStartElement("episode-num"); xml.WriteAttributeString("system", "xmltv_ns"); xml.WriteString($"{s - 1}.{e - 1}.0/1"); diff --git a/ErsatzTV.Core/Metadata/FallbackMetadataProvider.cs b/ErsatzTV.Core/Metadata/FallbackMetadataProvider.cs index aa911336d..15cdd7cf1 100644 --- a/ErsatzTV.Core/Metadata/FallbackMetadataProvider.cs +++ b/ErsatzTV.Core/Metadata/FallbackMetadataProvider.cs @@ -34,7 +34,7 @@ namespace ErsatzTV.Core.Metadata return fileName != null ? GetMovieMetadata(fileName, metadata) : metadata; } - + public string GetSortTitle(string title) { if (string.IsNullOrWhiteSpace(title)) diff --git a/ErsatzTV.Infrastructure/Data/Repositories/MediaCollectionRepository.cs b/ErsatzTV.Infrastructure/Data/Repositories/MediaCollectionRepository.cs index f28f7fd46..0a0afeef0 100644 --- a/ErsatzTV.Infrastructure/Data/Repositories/MediaCollectionRepository.cs +++ b/ErsatzTV.Infrastructure/Data/Repositories/MediaCollectionRepository.cs @@ -30,8 +30,10 @@ namespace ErsatzTV.Infrastructure.Data.Repositories } - public async Task AddMediaItem(int collectionId, int mediaItemId) + public async Task AddMediaItem(int collectionId, int mediaItemId) { + var modified = false; + Option maybeCollection = await _dbContext.Collections .Include(c => c.MediaItems) .OrderBy(c => c.Id) @@ -52,12 +54,12 @@ namespace ErsatzTV.Infrastructure.Data.Repositories async mediaItem => { collection.MediaItems.Add(mediaItem); - await _dbContext.SaveChangesAsync(); + modified = await _dbContext.SaveChangesAsync() > 0; }); } }); - return Unit.Default; + return modified; } public Task> Get(int id) => @@ -121,10 +123,10 @@ namespace ErsatzTV.Infrastructure.Data.Repositories public Task>> GetItems(int id) => Get(id).MapT(GetItemsForCollection).Bind(x => x.Sequence()); - public Task Update(Collection collection) + public Task Update(Collection collection) { _dbContext.Collections.Update(collection); - return _dbContext.SaveChangesAsync(); + return _dbContext.SaveChangesAsync().Map(result => result > 0); } public async Task Delete(int collectionId) @@ -134,6 +136,16 @@ namespace ErsatzTV.Infrastructure.Data.Repositories await _dbContext.SaveChangesAsync(); } + public Task> PlayoutIdsUsingCollection(int collectionId) => + _dbConnection.QueryAsync( + @"SELECT DISTINCT p.Id + FROM Playout p + INNER JOIN ProgramSchedule PS on p.ProgramScheduleId = PS.Id + INNER JOIN ProgramScheduleItem PSI on p.Anchor_NextScheduleItemId = PSI.Id + WHERE PSI.CollectionId = @CollectionId", + new { CollectionId = collectionId }) + .Map(result => result.ToList()); + private async Task> GetItemsForCollection(Collection collection) { var result = new List(); diff --git a/ErsatzTV.Infrastructure/Data/Repositories/MediaSourceRepository.cs b/ErsatzTV.Infrastructure/Data/Repositories/MediaSourceRepository.cs index fc21f44dd..bcdf3366c 100644 --- a/ErsatzTV.Infrastructure/Data/Repositories/MediaSourceRepository.cs +++ b/ErsatzTV.Infrastructure/Data/Repositories/MediaSourceRepository.cs @@ -173,7 +173,7 @@ namespace ErsatzTV.Infrastructure.Data.Repositories await _dbConnection.ExecuteAsync( "UPDATE PlexLibrary SET ShouldSyncItems = 0 WHERE Id IN @ids", new { ids = libraryIds }); - + await _dbConnection.ExecuteAsync( "UPDATE Library SET LastScan = null WHERE Id IN @ids", new { ids = libraryIds }); diff --git a/ErsatzTV.Infrastructure/Data/Repositories/MovieRepository.cs b/ErsatzTV.Infrastructure/Data/Repositories/MovieRepository.cs index f6b007c8a..ad20a7293 100644 --- a/ErsatzTV.Infrastructure/Data/Repositories/MovieRepository.cs +++ b/ErsatzTV.Infrastructure/Data/Repositories/MovieRepository.cs @@ -122,7 +122,10 @@ namespace ErsatzTV.Infrastructure.Data.Repositories } } - private async Task> AddPlexMovie(TvContext context, PlexLibrary library, PlexMovie item) + private async Task> AddPlexMovie( + TvContext context, + PlexLibrary library, + PlexMovie item) { try { diff --git a/ErsatzTV.Infrastructure/Plex/PlexServerApiClient.cs b/ErsatzTV.Infrastructure/Plex/PlexServerApiClient.cs index 0447915bb..650d75a16 100644 --- a/ErsatzTV.Infrastructure/Plex/PlexServerApiClient.cs +++ b/ErsatzTV.Infrastructure/Plex/PlexServerApiClient.cs @@ -18,10 +18,8 @@ namespace ErsatzTV.Infrastructure.Plex { private readonly IFallbackMetadataProvider _fallbackMetadataProvider; - public PlexServerApiClient(IFallbackMetadataProvider fallbackMetadataProvider) - { + public PlexServerApiClient(IFallbackMetadataProvider fallbackMetadataProvider) => _fallbackMetadataProvider = fallbackMetadataProvider; - } public async Task>> GetLibraries( PlexConnection connection, @@ -150,7 +148,7 @@ namespace ErsatzTV.Infrastructure.Plex } private static string ConvertToSAR(double aspectRatio) => "1:1"; - // TODO: fix this with more detailed stats pull from plex for each item - // Math.Abs(aspectRatio - 1) < 0.01 ? "1:1" : $"{(int) (aspectRatio * 100)}:100"; + // TODO: fix this with more detailed stats pull from plex for each item + // Math.Abs(aspectRatio - 1) < 0.01 ? "1:1" : $"{(int) (aspectRatio * 100)}:100"; } } diff --git a/ErsatzTV/Extensions/HostExtensions.cs b/ErsatzTV/Extensions/HostExtensions.cs index bce49bcbb..1bc1a6763 100644 --- a/ErsatzTV/Extensions/HostExtensions.cs +++ b/ErsatzTV/Extensions/HostExtensions.cs @@ -36,7 +36,10 @@ namespace ErsatzTV.Extensions .IfFail( ex => { - LogException(ex, "Error occured while migrating database; shutting down.", scope.ServiceProvider); + LogException( + ex, + "Error occured while migrating database; shutting down.", + scope.ServiceProvider); Environment.Exit(13); return unit; }); diff --git a/ErsatzTV/Pages/CollectionItems.razor b/ErsatzTV/Pages/CollectionItems.razor index 2e97f80d7..aca84e664 100644 --- a/ErsatzTV/Pages/CollectionItems.razor +++ b/ErsatzTV/Pages/CollectionItems.razor @@ -7,6 +7,7 @@ @inject ILogger Logger @inject ISnackbar Snackbar @inject IDialogService Dialog +@inject ChannelWriter Channel
@_data.Name diff --git a/ErsatzTV/Pages/MovieList.razor b/ErsatzTV/Pages/MovieList.razor index e312f82d5..c3cd5e405 100644 --- a/ErsatzTV/Pages/MovieList.razor +++ b/ErsatzTV/Pages/MovieList.razor @@ -10,6 +10,7 @@ @inject IMediator Mediator @inject IDialogService Dialog @inject NavigationManager NavigationManager +@inject ChannelWriter Channel diff --git a/ErsatzTV/Pages/Search.razor b/ErsatzTV/Pages/Search.razor index e18b378fe..f17c338d8 100644 --- a/ErsatzTV/Pages/Search.razor +++ b/ErsatzTV/Pages/Search.razor @@ -11,6 +11,7 @@ @inject ILogger Logger @inject ISnackbar Snackbar @inject IDialogService Dialog +@inject ChannelWriter Channel
diff --git a/ErsatzTV/Pages/TelevisionEpisodeList.razor b/ErsatzTV/Pages/TelevisionEpisodeList.razor index 430d83b55..f1f93102e 100644 --- a/ErsatzTV/Pages/TelevisionEpisodeList.razor +++ b/ErsatzTV/Pages/TelevisionEpisodeList.razor @@ -7,12 +7,13 @@ @using ErsatzTV.Application.MediaCollections.Commands @using ErsatzTV.Application.ProgramSchedules @using ErsatzTV.Application.ProgramSchedules.Commands -@using Unit=LanguageExt.Unit; +@using Unit = LanguageExt.Unit @inject IMediator Mediator @inject ILogger Logger @inject ISnackbar Snackbar @inject IDialogService Dialog @inject NavigationManager NavigationManager +@inject ChannelWriter Channel @@ -122,7 +123,7 @@ NavigationManager.NavigateTo($"/schedules/{schedule.Id}/items"); } } - + private async Task AddEpisodeToCollection(MediaCardViewModel card) { if (card is TelevisionEpisodeCardViewModel episode) diff --git a/ErsatzTV/Pages/TelevisionSeasonList.razor b/ErsatzTV/Pages/TelevisionSeasonList.razor index 64dfd2569..f6442b66e 100644 --- a/ErsatzTV/Pages/TelevisionSeasonList.razor +++ b/ErsatzTV/Pages/TelevisionSeasonList.razor @@ -7,12 +7,13 @@ @using ErsatzTV.Application.MediaCollections.Commands @using ErsatzTV.Application.ProgramSchedules @using ErsatzTV.Application.ProgramSchedules.Commands -@using Unit=LanguageExt.Unit; +@using Unit = LanguageExt.Unit @inject IMediator Mediator @inject ILogger Logger @inject ISnackbar Snackbar @inject IDialogService Dialog @inject NavigationManager NavigationManager +@inject ChannelWriter Channel @@ -116,7 +117,7 @@ NavigationManager.NavigateTo($"/schedules/{schedule.Id}/items"); } } - + private async Task AddSeasonToCollection(MediaCardViewModel card) { if (card is TelevisionSeasonCardViewModel season) diff --git a/ErsatzTV/Pages/TelevisionShowList.razor b/ErsatzTV/Pages/TelevisionShowList.razor index 2924ce570..a6845766a 100644 --- a/ErsatzTV/Pages/TelevisionShowList.razor +++ b/ErsatzTV/Pages/TelevisionShowList.razor @@ -8,6 +8,7 @@ @inject ISnackbar Snackbar @inject IMediator Mediator @inject IDialogService Dialog +@inject ChannelWriter Channel diff --git a/ErsatzTV/Shared/MainLayout.razor b/ErsatzTV/Shared/MainLayout.razor index 1ade69772..5dbe09036 100644 --- a/ErsatzTV/Shared/MainLayout.razor +++ b/ErsatzTV/Shared/MainLayout.razor @@ -67,7 +67,7 @@ private static readonly string InfoVersion = Assembly.GetEntryAssembly().GetCustomAttribute()?.InformationalVersion ?? "unknown"; private MudTextField _textField; - + private MudTheme _ersatzTvTheme { get diff --git a/ErsatzTV/Shared/MediaCard.razor b/ErsatzTV/Shared/MediaCard.razor index 6f78a7e2a..4ef1d8cb4 100644 --- a/ErsatzTV/Shared/MediaCard.razor +++ b/ErsatzTV/Shared/MediaCard.razor @@ -21,7 +21,7 @@ { } @if (DeleteClicked.HasDelegate) diff --git a/ErsatzTV/wwwroot/browserconfig.xml b/ErsatzTV/wwwroot/browserconfig.xml index b3930d0f0..c6f1bea66 100644 --- a/ErsatzTV/wwwroot/browserconfig.xml +++ b/ErsatzTV/wwwroot/browserconfig.xml @@ -1,9 +1,10 @@ + - + #da532c - + \ No newline at end of file diff --git a/ErsatzTV/wwwroot/css/site.css b/ErsatzTV/wwwroot/css/site.css index 9d0ae74bb..29d0d7136 100644 --- a/ErsatzTV/wwwroot/css/site.css +++ b/ErsatzTV/wwwroot/css/site.css @@ -4,13 +4,9 @@ flex-wrap: wrap; } -.media-card-container { - width: 152px; -} +.media-card-container { width: 152px; } -.media-card-episode-container { - width: 392px; -} +.media-card-episode-container { width: 392px; } .media-card { display: flex; @@ -22,12 +18,9 @@ width: 152px; } -.media-card-episode { - width: 392px; -} +.media-card-episode { width: 392px; } -.media-card:hover { /*filter: brightness(75%);*/ -} +.media-card:hover { /*filter: brightness(75%);*/ } .media-card-title { overflow: hidden; @@ -36,9 +29,7 @@ width: 100%; } -.media-card-poster-placeholder { - font-weight: bold; -} +.media-card-poster-placeholder { font-weight: bold; } .media-card-menu { bottom: 0; @@ -47,9 +38,7 @@ right: 0; } -.media-card:hover .media-card-menu { - display: block; -} +.media-card:hover .media-card-menu { display: block; } .media-card-overlay { background: rgba(0, 0, 0, 0.4); @@ -63,26 +52,20 @@ transition: opacity 0.2s; } -.media-card-overlay:hover { - opacity: 1; -} +.media-card-overlay:hover { opacity: 1; } -.search-bar .mud-input { - height: 42px; -} +.search-bar .mud-input { height: 42px; } .search-bar { background-color: rgba(255, 255, 255, .15); - margin-bottom: 5px; - height: 42px; border-radius: 4px; + height: 42px; + margin-bottom: 5px; } -.search-bar div .mud-input-root { - color: #fafafa; -} +.search-bar div .mud-input-root { color: #fafafa; } .search-bar .mud-input.mud-input-outlined .mud-input-outlined-border { border: none; border-radius: 4px; -} +} \ No newline at end of file