This commit is contained in:
Jason Dove
2021-05-23 03:27:20 -05:00
parent 50529ee6ad
commit 9afec19888
34 changed files with 289 additions and 307 deletions
@@ -17,7 +17,5 @@ namespace ErsatzTV.Application.MediaCards
Title, Title,
$"Episode {Episode}", $"Episode {Episode}",
$"Episode {Episode}", $"Episode {Episode}",
Poster) Poster);
{
}
} }
@@ -14,7 +14,5 @@
Title, Title,
Subtitle, Subtitle,
SortTitle, SortTitle,
Poster) Poster);
{
}
} }
@@ -6,7 +6,5 @@
Title, Title,
Subtitle, Subtitle,
SortTitle, SortTitle,
Poster) Poster);
{
}
} }
+15 -15
View File
@@ -7,11 +7,11 @@
@using ErsatzTV.Application.MediaCollections.Commands @using ErsatzTV.Application.MediaCollections.Commands
@using System.Globalization @using System.Globalization
@using Unit = LanguageExt.Unit @using Unit = LanguageExt.Unit
@inject IMediator Mediator @inject IMediator _mediator
@inject IDialogService Dialog @inject IDialogService _dialog
@inject NavigationManager NavigationManager @inject NavigationManager _navigationManager
@inject ILogger<Artist> Logger @inject ILogger<Artist> _logger
@inject ISnackbar Snackbar @inject ISnackbar _snackbar
<MudContainer MaxWidth="MaxWidth.False" Style="padding: 0" Class="fanart-container"> <MudContainer MaxWidth="MaxWidth.False" Style="padding: 0" Class="fanart-container">
<div class="fanart-tint"></div> <div class="fanart-tint"></div>
@@ -161,7 +161,7 @@
private async Task RefreshData() private async Task RefreshData()
{ {
await Mediator.Send(new GetArtistById(ArtistId)).IfSomeAsync(vm => await _mediator.Send(new GetArtistById(ArtistId)).IfSomeAsync(vm =>
{ {
_artist = vm; _artist = vm;
_sortedLanguages = _artist.Languages.OrderBy(ci => ci.EnglishName).ToList(); _sortedLanguages = _artist.Languages.OrderBy(ci => ci.EnglishName).ToList();
@@ -170,7 +170,7 @@
_sortedMoods = _artist.Moods.OrderBy(m => m).ToList(); _sortedMoods = _artist.Moods.OrderBy(m => m).ToList();
}); });
_musicVideos = await Mediator.Send(new GetMusicVideoCards(ArtistId, 1, 100)); _musicVideos = await _mediator.Send(new GetMusicVideoCards(ArtistId, 1, 100));
} }
private async Task AddToCollection() private async Task AddToCollection()
@@ -178,12 +178,12 @@
var parameters = new DialogParameters { { "EntityType", "artist" }, { "EntityName", _artist.Name } }; var parameters = new DialogParameters { { "EntityType", "artist" }, { "EntityName", _artist.Name } };
var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall }; var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall };
IDialogReference dialog = Dialog.Show<AddToCollectionDialog>("Add To Collection", parameters, options); IDialogReference dialog = _dialog.Show<AddToCollectionDialog>("Add To Collection", parameters, options);
DialogResult result = await dialog.Result; DialogResult result = await dialog.Result;
if (!result.Cancelled && result.Data is MediaCollectionViewModel collection) if (!result.Cancelled && result.Data is MediaCollectionViewModel collection)
{ {
await Mediator.Send(new AddArtistToCollection(collection.Id, ArtistId)); await _mediator.Send(new AddArtistToCollection(collection.Id, ArtistId));
NavigationManager.NavigateTo($"/media/collections/{collection.Id}"); _navigationManager.NavigateTo($"/media/collections/{collection.Id}");
} }
} }
@@ -192,19 +192,19 @@
var parameters = new DialogParameters { { "EntityType", "music video" }, { "EntityName", musicVideo.Title } }; var parameters = new DialogParameters { { "EntityType", "music video" }, { "EntityName", musicVideo.Title } };
var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall }; var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall };
IDialogReference dialog = Dialog.Show<AddToCollectionDialog>("Add To Collection", parameters, options); IDialogReference dialog = _dialog.Show<AddToCollectionDialog>("Add To Collection", parameters, options);
DialogResult result = await dialog.Result; DialogResult result = await dialog.Result;
if (!result.Cancelled && result.Data is MediaCollectionViewModel collection) if (!result.Cancelled && result.Data is MediaCollectionViewModel collection)
{ {
var request = new AddMusicVideoToCollection(collection.Id, musicVideo.MusicVideoId); var request = new AddMusicVideoToCollection(collection.Id, musicVideo.MusicVideoId);
Either<BaseError, Unit> addResult = await Mediator.Send(request); Either<BaseError, Unit> addResult = await _mediator.Send(request);
addResult.Match( addResult.Match(
Left: error => Left: error =>
{ {
Snackbar.Add($"Unexpected error adding music video to collection: {error.Value}"); _snackbar.Add($"Unexpected error adding music video to collection: {error.Value}");
Logger.LogError("Unexpected error adding music video to collection: {Error}", 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)); Right: _ => _snackbar.Add($"Added {musicVideo.Title} to collection {collection.Name}", Severity.Success));
} }
} }
+5 -5
View File
@@ -9,8 +9,8 @@
@using ErsatzTV.Application.Search.Queries @using ErsatzTV.Application.Search.Queries
@using Unit = LanguageExt.Unit @using Unit = LanguageExt.Unit
@inherits MultiSelectBase<MusicVideoList> @inherits MultiSelectBase<MusicVideoList>
@inject NavigationManager NavigationManager @inject NavigationManager _navigationManager
@inject ChannelWriter<IBackgroundServiceRequest> Channel @inject ChannelWriter<IBackgroundServiceRequest> _channel
<MudPaper Square="true" Style="display: flex; height: 64px; left: 240px; padding: 0; position: fixed; right: 0; z-index: 100;"> <MudPaper Square="true" Style="display: flex; height: 64px; left: 240px; padding: 0; position: fixed; right: 0; z-index: 100;">
<div style="display: flex; flex-direction: row; margin-bottom: auto; margin-top: auto; width: 100%" class="ml-6 mr-6"> <div style="display: flex; flex-direction: row; margin-bottom: auto; margin-top: auto; width: 100%" class="ml-6 mr-6">
@@ -90,7 +90,7 @@
PageNumber = 1; PageNumber = 1;
} }
string query = new Uri(NavigationManager.Uri).Query; string query = new Uri(_navigationManager.Uri).Query;
if (QueryHelpers.ParseQuery(query).TryGetValue("query", out StringValues value)) if (QueryHelpers.ParseQuery(query).TryGetValue("query", out StringValues value))
{ {
_query = value; _query = value;
@@ -116,7 +116,7 @@
{ {
uri = QueryHelpers.AddQueryString(uri, "query", _query); uri = QueryHelpers.AddQueryString(uri, "query", _query);
} }
NavigationManager.NavigateTo(uri); _navigationManager.NavigateTo(uri);
} }
private void NextPage() private void NextPage()
@@ -126,7 +126,7 @@
{ {
uri = QueryHelpers.AddQueryString(uri, "query", _query); uri = QueryHelpers.AddQueryString(uri, "query", _query);
} }
NavigationManager.NavigateTo(uri); _navigationManager.NavigateTo(uri);
} }
private void SelectClicked(MediaCardViewModel card, MouseEventArgs e) private void SelectClicked(MediaCardViewModel card, MouseEventArgs e)
+18 -18
View File
@@ -8,10 +8,10 @@
@using System.Globalization @using System.Globalization
@using ErsatzTV.Application.Channels @using ErsatzTV.Application.Channels
@using ErsatzTV.Application.Channels.Queries @using ErsatzTV.Application.Channels.Queries
@inject NavigationManager NavigationManager @inject NavigationManager _navigationManager
@inject ILogger<ChannelEditor> Logger @inject ILogger<ChannelEditor> _logger
@inject ISnackbar Snackbar @inject ISnackbar _snackbar
@inject IMediator Mediator @inject IMediator _mediator
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8"> <MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8">
<div style="max-width: 400px;"> <div style="max-width: 400px;">
@@ -87,11 +87,11 @@
protected override async Task OnParametersSetAsync() protected override async Task OnParametersSetAsync()
{ {
await LoadFFmpegProfilesAsync(); await LoadFFmpegProfilesAsync();
_availableCultures = await Mediator.Send(new GetAllLanguageCodes()); _availableCultures = await _mediator.Send(new GetAllLanguageCodes());
if (Id.HasValue) if (Id.HasValue)
{ {
Option<ChannelViewModel> maybeChannel = await Mediator.Send(new GetChannelById(Id.Value)); Option<ChannelViewModel> maybeChannel = await _mediator.Send(new GetChannelById(Id.Value));
maybeChannel.Match( maybeChannel.Match(
channelViewModel => channelViewModel =>
{ {
@@ -103,14 +103,14 @@
_model.StreamingMode = channelViewModel.StreamingMode; _model.StreamingMode = channelViewModel.StreamingMode;
_model.PreferredLanguageCode = channelViewModel.PreferredLanguageCode; _model.PreferredLanguageCode = channelViewModel.PreferredLanguageCode;
}, },
() => NavigationManager.NavigateTo("404")); () => _navigationManager.NavigateTo("404"));
} }
else else
{ {
FFmpegSettingsViewModel ffmpegSettings = await Mediator.Send(new GetFFmpegSettings()); FFmpegSettingsViewModel ffmpegSettings = await _mediator.Send(new GetFFmpegSettings());
// TODO: command for new channel // TODO: command for new channel
IEnumerable<int> channelNumbers = await Mediator.Send(new GetAllChannels()) IEnumerable<int> channelNumbers = await _mediator.Send(new GetAllChannels())
.Map(list => list.Map(c => int.TryParse(c.Number.Split(".").Head(), out int result) ? result : 0)); .Map(list => list.Map(c => int.TryParse(c.Number.Split(".").Head(), out int result) ? result : 0));
int maxNumber = Optional(channelNumbers).Flatten().DefaultIfEmpty(0).Max(); int maxNumber = Optional(channelNumbers).Flatten().DefaultIfEmpty(0).Max();
_model.Number = (maxNumber + 1).ToString(); _model.Number = (maxNumber + 1).ToString();
@@ -129,7 +129,7 @@
private bool IsEdit => Id.HasValue; private bool IsEdit => Id.HasValue;
private async Task LoadFFmpegProfilesAsync() => private async Task LoadFFmpegProfilesAsync() =>
_ffmpegProfiles = await Mediator.Send(new GetAllFFmpegProfiles()); _ffmpegProfiles = await _mediator.Send(new GetAllFFmpegProfiles());
private async Task HandleSubmitAsync() private async Task HandleSubmitAsync()
{ {
@@ -137,16 +137,16 @@
if (_editContext.Validate()) if (_editContext.Validate())
{ {
Seq<BaseError> errorMessage = IsEdit ? Seq<BaseError> errorMessage = IsEdit ?
(await Mediator.Send(_model.ToUpdate())).LeftToSeq() : (await _mediator.Send(_model.ToUpdate())).LeftToSeq() :
(await Mediator.Send(_model.ToCreate())).LeftToSeq(); (await _mediator.Send(_model.ToCreate())).LeftToSeq();
errorMessage.HeadOrNone().Match( errorMessage.HeadOrNone().Match(
error => error =>
{ {
Snackbar.Add(error.Value, Severity.Error); _snackbar.Add(error.Value, Severity.Error);
Logger.LogError("Unexpected error saving channel: {Error}", error.Value); _logger.LogError("Unexpected error saving channel: {Error}", error.Value);
}, },
() => NavigationManager.NavigateTo("/channels")); () => _navigationManager.NavigateTo("/channels"));
} }
} }
@@ -154,7 +154,7 @@
{ {
var buffer = new byte[e.File.Size]; var buffer = new byte[e.File.Size];
await e.File.OpenReadStream().ReadAsync(buffer); await e.File.OpenReadStream().ReadAsync(buffer);
Either<BaseError, string> maybeCacheFileName = await Mediator.Send(new SaveArtworkToDisk(buffer, ArtworkKind.Logo)); Either<BaseError, string> maybeCacheFileName = await _mediator.Send(new SaveArtworkToDisk(buffer, ArtworkKind.Logo));
maybeCacheFileName.Match( maybeCacheFileName.Match(
relativeFileName => relativeFileName =>
{ {
@@ -163,8 +163,8 @@
}, },
error => error =>
{ {
Snackbar.Add($"Unexpected error saving channel logo: {error.Value}", Severity.Error); _snackbar.Add($"Unexpected error saving channel logo: {error.Value}", Severity.Error);
Logger.LogError("Unexpected error saving channel logo: {Error}", error.Value); _logger.LogError("Unexpected error saving channel logo: {Error}", error.Value);
}); });
} }
+6 -6
View File
@@ -5,8 +5,8 @@
@using ErsatzTV.Application.FFmpegProfiles @using ErsatzTV.Application.FFmpegProfiles
@using ErsatzTV.Application.FFmpegProfiles.Queries @using ErsatzTV.Application.FFmpegProfiles.Queries
@using System.Globalization @using System.Globalization
@inject IDialogService Dialog @inject IDialogService _dialog
@inject IMediator Mediator @inject IMediator _mediator
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8"> <MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8">
<MudTable Hover="true" Items="_channels"> <MudTable Hover="true" Items="_channels">
@@ -82,7 +82,7 @@
protected override async Task OnParametersSetAsync() protected override async Task OnParametersSetAsync()
{ {
_ffmpegProfiles = await Mediator.Send(new GetAllFFmpegProfiles()); _ffmpegProfiles = await _mediator.Send(new GetAllFFmpegProfiles());
await LoadChannelsAsync(); await LoadChannelsAsync();
} }
@@ -91,18 +91,18 @@
var parameters = new DialogParameters { { "EntityType", "channel" }, { "EntityName", channel.Name } }; var parameters = new DialogParameters { { "EntityType", "channel" }, { "EntityName", channel.Name } };
var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall }; var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall };
IDialogReference dialog = Dialog.Show<DeleteDialog>("Delete Channel", parameters, options); IDialogReference dialog = _dialog.Show<DeleteDialog>("Delete Channel", parameters, options);
DialogResult result = await dialog.Result; DialogResult result = await dialog.Result;
if (!result.Cancelled) if (!result.Cancelled)
{ {
await Mediator.Send(new DeleteChannel(channel.Id)); await _mediator.Send(new DeleteChannel(channel.Id));
await LoadChannelsAsync(); await LoadChannelsAsync();
} }
} }
private async Task LoadChannelsAsync() private async Task LoadChannelsAsync()
{ {
List<ChannelViewModel> channels = await Mediator.Send(new GetAllChannels()); List<ChannelViewModel> channels = await _mediator.Send(new GetAllChannels());
IOrderedEnumerable<ChannelViewModel> sorted = channels.OrderBy(c => decimal.Parse(c.Number)); IOrderedEnumerable<ChannelViewModel> sorted = channels.OrderBy(c => decimal.Parse(c.Number));
CultureInfo[] allCultures = CultureInfo.GetCultures(CultureTypes.NeutralCultures); CultureInfo[] allCultures = CultureInfo.GetCultures(CultureTypes.NeutralCultures);
+10 -10
View File
@@ -3,10 +3,10 @@
@using ErsatzTV.Application.MediaCollections @using ErsatzTV.Application.MediaCollections
@using ErsatzTV.Application.MediaCollections.Commands @using ErsatzTV.Application.MediaCollections.Commands
@using ErsatzTV.Application.MediaCollections.Queries @using ErsatzTV.Application.MediaCollections.Queries
@inject NavigationManager NavigationManager @inject NavigationManager _navigationManager
@inject ILogger<CollectionEditor> Logger @inject ILogger<CollectionEditor> _logger
@inject ISnackbar Snackbar @inject ISnackbar _snackbar
@inject IMediator Mediator @inject IMediator _mediator
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8"> <MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8">
<div style="max-width: 400px;"> <div style="max-width: 400px;">
@@ -41,7 +41,7 @@
{ {
if (IsEdit) if (IsEdit)
{ {
Option<MediaCollectionViewModel> maybeCollection = await Mediator.Send(new GetCollectionById(Id)); Option<MediaCollectionViewModel> maybeCollection = await _mediator.Send(new GetCollectionById(Id));
maybeCollection.IfSome(collection => maybeCollection.IfSome(collection =>
{ {
_model.Id = collection.Id; _model.Id = collection.Id;
@@ -68,16 +68,16 @@
if (_editContext.Validate()) if (_editContext.Validate())
{ {
Seq<BaseError> errorMessage = IsEdit ? Seq<BaseError> errorMessage = IsEdit ?
(await Mediator.Send(new UpdateCollection(Id, _model.Name))).LeftToSeq() : (await _mediator.Send(new UpdateCollection(Id, _model.Name))).LeftToSeq() :
(await Mediator.Send(new CreateCollection(_model.Name))).LeftToSeq(); (await _mediator.Send(new CreateCollection(_model.Name))).LeftToSeq();
errorMessage.HeadOrNone().Match( errorMessage.HeadOrNone().Match(
error => error =>
{ {
Snackbar.Add(error.Value, Severity.Error); _snackbar.Add(error.Value, Severity.Error);
Logger.LogError("Error saving collection: {Error}", error.Value); _logger.LogError("Error saving collection: {Error}", error.Value);
}, },
() => NavigationManager.NavigateTo(_model.Id > 0 ? $"/media/collections/{_model.Id}" : "/media/collections")); () => _navigationManager.NavigateTo(_model.Id > 0 ? $"/media/collections/{_model.Id}" : "/media/collections"));
} }
} }
+13 -13
View File
@@ -3,9 +3,9 @@
@using ErsatzTV.Application.MediaCards.Queries @using ErsatzTV.Application.MediaCards.Queries
@using ErsatzTV.Application.MediaCollections.Commands @using ErsatzTV.Application.MediaCollections.Commands
@inherits MultiSelectBase<CollectionItems> @inherits MultiSelectBase<CollectionItems>
@inject NavigationManager NavigationManager @inject NavigationManager _navigationManager
@inject ChannelWriter<IBackgroundServiceRequest> Channel @inject ChannelWriter<IBackgroundServiceRequest> _channel
@inject IJSRuntime JsRuntime @inject IJSRuntime _jsRuntime
<MudPaper Square="true" Style="display: flex; height: 64px; left: 240px; padding: 0; position: fixed; right: 0; z-index: 100;"> <MudPaper Square="true" Style="display: flex; height: 64px; left: 240px; padding: 0; position: fixed; right: 0; z-index: 100;">
<div style="align-items: center; display: flex; flex-direction: row; margin-bottom: auto; margin-top: auto; width: 100%;" class="ml-6 mr-6"> <div style="align-items: center; display: flex; flex-direction: row; margin-bottom: auto; margin-top: auto; width: 100%;" class="ml-6 mr-6">
@@ -38,27 +38,27 @@
</div> </div>
@if (_data.MovieCards.Any()) @if (_data.MovieCards.Any())
{ {
<MudLink Class="ml-4" Href="@(NavigationManager.Uri.Split("#").Head() + "#movies")">@_data.MovieCards.Count Movies</MudLink> <MudLink Class="ml-4" Href="@(_navigationManager.Uri.Split("#").Head() + "#movies")">@_data.MovieCards.Count Movies</MudLink>
} }
@if (_data.ShowCards.Any()) @if (_data.ShowCards.Any())
{ {
<MudLink Class="ml-4" Href="@(NavigationManager.Uri.Split("#").Head() + "#shows")">@_data.ShowCards.Count Shows</MudLink> <MudLink Class="ml-4" Href="@(_navigationManager.Uri.Split("#").Head() + "#shows")">@_data.ShowCards.Count Shows</MudLink>
} }
@if (_data.SeasonCards.Any()) @if (_data.SeasonCards.Any())
{ {
<MudLink Class="ml-4" Href="@(NavigationManager.Uri.Split("#").Head() + "#seasons")">@_data.SeasonCards.Count Seasons</MudLink> <MudLink Class="ml-4" Href="@(_navigationManager.Uri.Split("#").Head() + "#seasons")">@_data.SeasonCards.Count Seasons</MudLink>
} }
@if (_data.EpisodeCards.Any()) @if (_data.EpisodeCards.Any())
{ {
<MudLink Class="ml-4" Href="@(NavigationManager.Uri.Split("#").Head() + "#episodes")">@_data.EpisodeCards.Count Episodes</MudLink> <MudLink Class="ml-4" Href="@(_navigationManager.Uri.Split("#").Head() + "#episodes")">@_data.EpisodeCards.Count Episodes</MudLink>
} }
@if (_data.ArtistCards.Any()) @if (_data.ArtistCards.Any())
{ {
<MudLink Class="ml-4" Href="@(NavigationManager.Uri.Split("#").Head() + "#artists")">@_data.ArtistCards.Count Artists</MudLink> <MudLink Class="ml-4" Href="@(_navigationManager.Uri.Split("#").Head() + "#artists")">@_data.ArtistCards.Count Artists</MudLink>
} }
@if (_data.MusicVideoCards.Any()) @if (_data.MusicVideoCards.Any())
{ {
<MudLink Class="ml-4" Href="@(NavigationManager.Uri.Split("#").Head() + "#music_videos")">@_data.MusicVideoCards.Count Music Videos</MudLink> <MudLink Class="ml-4" Href="@(_navigationManager.Uri.Split("#").Head() + "#music_videos")">@_data.MusicVideoCards.Count Music Videos</MudLink>
} }
@if (SupportsCustomOrdering()) @if (SupportsCustomOrdering())
{ {
@@ -242,7 +242,7 @@
maybeResult.Match( maybeResult.Match(
result => _data = result, result => _data = result,
error => NavigationManager.NavigateTo("404")); error => _navigationManager.NavigateTo("404"));
} }
private IOrderedEnumerable<MovieCardViewModel> OrderMovies(List<MovieCardViewModel> movies) private IOrderedEnumerable<MovieCardViewModel> OrderMovies(List<MovieCardViewModel> movies)
@@ -257,14 +257,14 @@
protected override async Task OnAfterRenderAsync(bool firstRender) protected override async Task OnAfterRenderAsync(bool firstRender)
{ {
await JsRuntime.InvokeVoidAsync("sortableCollection", Id); await _jsRuntime.InvokeVoidAsync("sortableCollection", Id);
if (_data.UseCustomPlaybackOrder) if (_data.UseCustomPlaybackOrder)
{ {
await JsRuntime.InvokeVoidAsync("enableSorting"); await _jsRuntime.InvokeVoidAsync("enableSorting");
} }
else else
{ {
await JsRuntime.InvokeVoidAsync("disableSorting"); await _jsRuntime.InvokeVoidAsync("disableSorting");
} }
await base.OnAfterRenderAsync(firstRender); await base.OnAfterRenderAsync(firstRender);
} }
+7 -7
View File
@@ -5,8 +5,8 @@
@using ErsatzTV.Application.Configuration.Queries @using ErsatzTV.Application.Configuration.Queries
@using ErsatzTV.Application.MediaCards @using ErsatzTV.Application.MediaCards
@using ErsatzTV.Application.Configuration.Commands @using ErsatzTV.Application.Configuration.Commands
@inject IDialogService Dialog @inject IDialogService _dialog
@inject IMediator Mediator @inject IMediator _mediator
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8"> <MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8">
<MudTable Hover="true" <MudTable Hover="true"
@@ -56,7 +56,7 @@
private int _rowsPerPage; private int _rowsPerPage;
protected override async Task OnParametersSetAsync() => _rowsPerPage = await Mediator.Send(new GetConfigElementByKey(ConfigElementKey.CollectionsPageSize)) protected override async Task OnParametersSetAsync() => _rowsPerPage = await _mediator.Send(new GetConfigElementByKey(ConfigElementKey.CollectionsPageSize))
.Map(maybeRows => maybeRows.Match(ce => int.TryParse(ce.Value, out int rows) ? rows : 10, () => 10)); .Map(maybeRows => maybeRows.Match(ce => int.TryParse(ce.Value, out int rows) ? rows : 10, () => 10));
private async Task DeleteMediaCollection(MediaCardViewModel vm) private async Task DeleteMediaCollection(MediaCardViewModel vm)
@@ -66,11 +66,11 @@
var parameters = new DialogParameters { { "EntityType", "collection" }, { "EntityName", collection.Name } }; var parameters = new DialogParameters { { "EntityType", "collection" }, { "EntityName", collection.Name } };
var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall }; var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall };
IDialogReference dialog = Dialog.Show<DeleteDialog>("Delete Collection", parameters, options); IDialogReference dialog = _dialog.Show<DeleteDialog>("Delete Collection", parameters, options);
DialogResult result = await dialog.Result; DialogResult result = await dialog.Result;
if (!result.Cancelled) if (!result.Cancelled)
{ {
await Mediator.Send(new DeleteCollection(collection.Id)); await _mediator.Send(new DeleteCollection(collection.Id));
await _table.ReloadServerData(); await _table.ReloadServerData();
} }
} }
@@ -79,9 +79,9 @@
private async Task<TableData<MediaCollectionViewModel>> ServerReload(TableState state) private async Task<TableData<MediaCollectionViewModel>> ServerReload(TableState state)
{ {
await Mediator.Send(new SaveConfigElementByKey(ConfigElementKey.CollectionsPageSize, state.PageSize.ToString())); await _mediator.Send(new SaveConfigElementByKey(ConfigElementKey.CollectionsPageSize, state.PageSize.ToString()));
PagedMediaCollectionsViewModel data = await Mediator.Send(new GetPagedCollections(state.Page, state.PageSize)); PagedMediaCollectionsViewModel data = await _mediator.Send(new GetPagedCollections(state.Page, state.PageSize));
return new TableData<MediaCollectionViewModel> { TotalItems = data.TotalCount, Items = data.Page }; return new TableData<MediaCollectionViewModel> { TotalItems = data.TotalCount, Items = data.Page };
} }
+13 -13
View File
@@ -5,10 +5,10 @@
@using ErsatzTV.Application.FFmpegProfiles @using ErsatzTV.Application.FFmpegProfiles
@using ErsatzTV.Application.FFmpegProfiles.Commands @using ErsatzTV.Application.FFmpegProfiles.Commands
@using ErsatzTV.Application.FFmpegProfiles.Queries @using ErsatzTV.Application.FFmpegProfiles.Queries
@inject NavigationManager NavigationManager @inject NavigationManager _navigationManager
@inject ILogger<FFmpegEditor> Logger @inject ILogger<FFmpegEditor> _logger
@inject ISnackbar Snackbar @inject ISnackbar _snackbar
@inject IMediator Mediator @inject IMediator _mediator
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8"> <MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8">
<EditForm EditContext="_editContext" OnSubmit="@HandleSubmitAsync"> <EditForm EditContext="_editContext" OnSubmit="@HandleSubmitAsync">
@@ -113,18 +113,18 @@
protected override async Task OnParametersSetAsync() protected override async Task OnParametersSetAsync()
{ {
_resolutions = await Mediator.Send(new GetAllResolutions()); _resolutions = await _mediator.Send(new GetAllResolutions());
if (IsEdit) if (IsEdit)
{ {
Option<FFmpegProfileViewModel> profile = await Mediator.Send(new GetFFmpegProfileById(Id)); Option<FFmpegProfileViewModel> profile = await _mediator.Send(new GetFFmpegProfileById(Id));
profile.Match( profile.Match(
ffmpegProfileViewModel => _model = new FFmpegProfileEditViewModel(ffmpegProfileViewModel), ffmpegProfileViewModel => _model = new FFmpegProfileEditViewModel(ffmpegProfileViewModel),
() => NavigationManager.NavigateTo("404")); () => _navigationManager.NavigateTo("404"));
} }
else else
{ {
_model = new FFmpegProfileEditViewModel(await Mediator.Send(new NewFFmpegProfile())); _model = new FFmpegProfileEditViewModel(await _mediator.Send(new NewFFmpegProfile()));
} }
_editContext = new EditContext(_model); _editContext = new EditContext(_model);
@@ -139,16 +139,16 @@
if (_editContext.Validate()) if (_editContext.Validate())
{ {
Seq<BaseError> errorMessage = IsEdit ? Seq<BaseError> errorMessage = IsEdit ?
(await Mediator.Send(_model.ToUpdate())).LeftToSeq() : (await _mediator.Send(_model.ToUpdate())).LeftToSeq() :
(await Mediator.Send(_model.ToCreate())).LeftToSeq(); (await _mediator.Send(_model.ToCreate())).LeftToSeq();
errorMessage.HeadOrNone().Match( errorMessage.HeadOrNone().Match(
error => error =>
{ {
Snackbar.Add("Unexpected error saving ffmpeg profile"); _snackbar.Add("Unexpected error saving ffmpeg profile");
Logger.LogError("Unexpected error saving ffmpeg profile: {Error}", error.Value); _logger.LogError("Unexpected error saving ffmpeg profile: {Error}", error.Value);
}, },
() => NavigationManager.NavigateTo("/ffmpeg")); () => _navigationManager.NavigateTo("/ffmpeg"));
} }
} }
+20 -20
View File
@@ -11,13 +11,13 @@
@using ErsatzTV.Application.Emby @using ErsatzTV.Application.Emby
@using ErsatzTV.Application.Emby.Commands @using ErsatzTV.Application.Emby.Commands
@implements IDisposable @implements IDisposable
@inject IMediator Mediator @inject IMediator _mediator
@inject IEntityLocker Locker @inject IEntityLocker _locker
@inject ChannelWriter<IBackgroundServiceRequest> WorkerChannel @inject ChannelWriter<IBackgroundServiceRequest> _workerChannel
@inject ChannelWriter<IPlexBackgroundServiceRequest> PlexWorkerChannel @inject ChannelWriter<IPlexBackgroundServiceRequest> _plexWorkerChannel
@inject ChannelWriter<IJellyfinBackgroundServiceRequest> JellyfinWorkerChannel @inject ChannelWriter<IJellyfinBackgroundServiceRequest> _jellyfinWorkerChannel
@inject ChannelWriter<IEmbyBackgroundServiceRequest> EmbyWorkerChannel @inject ChannelWriter<IEmbyBackgroundServiceRequest> _embyWorkerChannel
@inject ICourier Courier @inject ICourier _courier
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8"> <MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8">
<MudTable Hover="true" Items="_libraries" Dense="true"> <MudTable Hover="true" Items="_libraries" Dense="true">
@@ -42,7 +42,7 @@
<MudTd DataLabel="Media Kind">@context.MediaKind</MudTd> <MudTd DataLabel="Media Kind">@context.MediaKind</MudTd>
<MudTd> <MudTd>
<div style="align-items: center; display: flex;"> <div style="align-items: center; display: flex;">
@if (Locker.IsLibraryLocked(context.Id)) @if (_locker.IsLibraryLocked(context.Id))
{ {
<div style="width: 48px"> <div style="width: 48px">
@if (_progressByLibrary[context.Id] > 0) @if (_progressByLibrary[context.Id] > 0)
@@ -61,7 +61,7 @@
<div style="width: 48px"></div> <div style="width: 48px"></div>
<MudTooltip Text="Scan Library"> <MudTooltip Text="Scan Library">
<MudIconButton Icon="@Icons.Material.Filled.Refresh" <MudIconButton Icon="@Icons.Material.Filled.Refresh"
Disabled="@Locker.IsLibraryLocked(context.Id)" Disabled="@_locker.IsLibraryLocked(context.Id)"
OnClick="@(_ => ScanLibrary(context))"> OnClick="@(_ => ScanLibrary(context))">
</MudIconButton> </MudIconButton>
</MudTooltip> </MudTooltip>
@@ -75,7 +75,7 @@
{ {
<MudTooltip Text="Edit Library"> <MudTooltip Text="Edit Library">
<MudIconButton Icon="@Icons.Material.Filled.Edit" <MudIconButton Icon="@Icons.Material.Filled.Edit"
Disabled="@Locker.IsLibraryLocked(context.Id)" Disabled="@_locker.IsLibraryLocked(context.Id)"
Link="@($"/media/libraries/local/{context.Id}")"> Link="@($"/media/libraries/local/{context.Id}")">
</MudIconButton> </MudIconButton>
</MudTooltip> </MudTooltip>
@@ -92,35 +92,35 @@
protected override void OnInitialized() protected override void OnInitialized()
{ {
Locker.OnLibraryChanged += LockChanged; _locker.OnLibraryChanged += LockChanged;
Courier.Subscribe<LibraryScanProgress>(HandleScanProgress); _courier.Subscribe<LibraryScanProgress>(HandleScanProgress);
} }
protected override async Task OnParametersSetAsync() => await LoadLibraries(); protected override async Task OnParametersSetAsync() => await LoadLibraries();
private async Task LoadLibraries() private async Task LoadLibraries()
{ {
_libraries = await Mediator.Send(new GetAllLibraries()); _libraries = await _mediator.Send(new GetAllLibraries());
_progressByLibrary = _libraries.ToDictionary(vm => vm.Id, _ => 0); _progressByLibrary = _libraries.ToDictionary(vm => vm.Id, _ => 0);
} }
private async Task ScanLibrary(LibraryViewModel library) private async Task ScanLibrary(LibraryViewModel library)
{ {
if (Locker.LockLibrary(library.Id)) if (_locker.LockLibrary(library.Id))
{ {
switch (library) switch (library)
{ {
case LocalLibraryViewModel: case LocalLibraryViewModel:
await WorkerChannel.WriteAsync(new ForceScanLocalLibrary(library.Id)); await _workerChannel.WriteAsync(new ForceScanLocalLibrary(library.Id));
break; break;
case PlexLibraryViewModel: case PlexLibraryViewModel:
await PlexWorkerChannel.WriteAsync(new ForceSynchronizePlexLibraryById(library.Id)); await _plexWorkerChannel.WriteAsync(new ForceSynchronizePlexLibraryById(library.Id));
break; break;
case JellyfinLibraryViewModel: case JellyfinLibraryViewModel:
await JellyfinWorkerChannel.WriteAsync(new ForceSynchronizeJellyfinLibraryById(library.Id)); await _jellyfinWorkerChannel.WriteAsync(new ForceSynchronizeJellyfinLibraryById(library.Id));
break; break;
case EmbyLibraryViewModel: case EmbyLibraryViewModel:
await EmbyWorkerChannel.WriteAsync(new ForceSynchronizeEmbyLibraryById(library.Id)); await _embyWorkerChannel.WriteAsync(new ForceSynchronizeEmbyLibraryById(library.Id));
break; break;
} }
@@ -149,8 +149,8 @@
void IDisposable.Dispose() void IDisposable.Dispose()
{ {
Locker.OnLibraryChanged -= LockChanged; _locker.OnLibraryChanged -= LockChanged;
Courier.UnSubscribe<LibraryScanProgress>(HandleScanProgress); _courier.UnSubscribe<LibraryScanProgress>(HandleScanProgress);
} }
} }
+6 -6
View File
@@ -2,8 +2,8 @@
@using ErsatzTV.Application.Libraries @using ErsatzTV.Application.Libraries
@using ErsatzTV.Application.Libraries.Commands @using ErsatzTV.Application.Libraries.Commands
@using ErsatzTV.Application.Libraries.Queries @using ErsatzTV.Application.Libraries.Queries
@inject IDialogService Dialog @inject IDialogService _dialog
@inject IMediator Mediator @inject IMediator _mediator
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8"> <MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8">
<MudTable Hover="true" Items="_libraryPaths" Dense="true"> <MudTable Hover="true" Items="_libraryPaths" Dense="true">
@@ -47,11 +47,11 @@
protected override async Task OnParametersSetAsync() => await LoadLibraryPaths(); protected override async Task OnParametersSetAsync() => await LoadLibraryPaths();
private async Task LoadLibraryPaths() => private async Task LoadLibraryPaths() =>
_libraryPaths = await Mediator.Send(new GetLocalLibraryPaths(Id)); _libraryPaths = await _mediator.Send(new GetLocalLibraryPaths(Id));
private async Task DeleteLibraryPath(LocalLibraryPathViewModel libraryPath) private async Task DeleteLibraryPath(LocalLibraryPathViewModel libraryPath)
{ {
int count = await Mediator.Send(new CountMediaItemsByLibraryPath(libraryPath.Id)); int count = await _mediator.Send(new CountMediaItemsByLibraryPath(libraryPath.Id));
var parameters = new DialogParameters var parameters = new DialogParameters
{ {
@@ -62,11 +62,11 @@
}; };
var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall }; var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall };
IDialogReference dialog = Dialog.Show<DeleteDialog>("Delete Library Path", parameters, options); IDialogReference dialog = _dialog.Show<DeleteDialog>("Delete Library Path", parameters, options);
DialogResult result = await dialog.Result; DialogResult result = await dialog.Result;
if (!result.Cancelled) if (!result.Cancelled)
{ {
await Mediator.Send(new DeleteLocalLibraryPath(libraryPath.Id)); await _mediator.Send(new DeleteLocalLibraryPath(libraryPath.Id));
await LoadLibraryPaths(); await LoadLibraryPaths();
} }
} }
+14 -14
View File
@@ -3,12 +3,12 @@
@using ErsatzTV.Application.Libraries.Commands @using ErsatzTV.Application.Libraries.Commands
@using ErsatzTV.Application.Libraries.Queries @using ErsatzTV.Application.Libraries.Queries
@using ErsatzTV.Application.MediaSources.Commands @using ErsatzTV.Application.MediaSources.Commands
@inject NavigationManager NavigationManager @inject NavigationManager _navigationManager
@inject ILogger<LocalLibraryPathEditor> Logger @inject ILogger<LocalLibraryPathEditor> _logger
@inject ISnackbar Snackbar @inject ISnackbar _snackbar
@inject IMediator Mediator @inject IMediator _mediator
@inject IEntityLocker Locker @inject IEntityLocker _locker
@inject ChannelWriter<IBackgroundServiceRequest> Channel @inject ChannelWriter<IBackgroundServiceRequest> _channel
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8"> <MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8">
<MudText Typo="Typo.h4" Class="mb-4">@_library.Name - Add Local Library Path</MudText> <MudText Typo="Typo.h4" Class="mb-4">@_library.Name - Add Local Library Path</MudText>
@@ -44,10 +44,10 @@
protected override async Task OnParametersSetAsync() protected override async Task OnParametersSetAsync()
{ {
Option<LocalLibraryViewModel> maybeLibrary = await Mediator.Send(new GetLocalLibraryById(Id)); Option<LocalLibraryViewModel> maybeLibrary = await _mediator.Send(new GetLocalLibraryById(Id));
maybeLibrary.Match( maybeLibrary.Match(
library => _library = library, library => _library = library,
() => NavigationManager.NavigateTo("404")); () => _navigationManager.NavigateTo("404"));
} }
protected override void OnInitialized() protected override void OnInitialized()
@@ -62,20 +62,20 @@
if (_editContext.Validate()) if (_editContext.Validate())
{ {
var command = new CreateLocalLibraryPath(_library.Id, _model.Path); var command = new CreateLocalLibraryPath(_library.Id, _model.Path);
Either<BaseError, LocalLibraryPathViewModel> result = await Mediator.Send(command); Either<BaseError, LocalLibraryPathViewModel> result = await _mediator.Send(command);
await result.Match( await result.Match(
Left: error => Left: error =>
{ {
Snackbar.Add(error.Value, Severity.Error); _snackbar.Add(error.Value, Severity.Error);
Logger.LogError("Unexpected error saving local library path: {Error}", error.Value); _logger.LogError("Unexpected error saving local library path: {Error}", error.Value);
return Task.CompletedTask; return Task.CompletedTask;
}, },
Right: async _ => Right: async _ =>
{ {
if (Locker.LockLibrary(_library.Id)) if (_locker.LockLibrary(_library.Id))
{ {
await Channel.WriteAsync(new ScanLocalLibraryIfNeeded(_library.Id)); await _channel.WriteAsync(new ScanLocalLibraryIfNeeded(_library.Id));
NavigationManager.NavigateTo("/media/libraries"); _navigationManager.NavigateTo("/media/libraries");
} }
}); });
} }
+2 -2
View File
@@ -1,7 +1,7 @@
@page "/system/logs" @page "/system/logs"
@using ErsatzTV.Application.Logs @using ErsatzTV.Application.Logs
@using ErsatzTV.Application.Logs.Queries @using ErsatzTV.Application.Logs.Queries
@inject IMediator Mediator @inject IMediator _mediator
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8"> <MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8">
<MudTable FixedHeader="true" Dense="true" Items="_logEntries"> <MudTable FixedHeader="true" Dense="true" Items="_logEntries">
@@ -32,6 +32,6 @@
@code { @code {
private List<LogEntryViewModel> _logEntries; private List<LogEntryViewModel> _logEntries;
protected override async Task OnInitializedAsync() => _logEntries = await Mediator.Send(new GetRecentLogEntries()); protected override async Task OnInitializedAsync() => _logEntries = await _mediator.Send(new GetRecentLogEntries());
} }
+7 -7
View File
@@ -5,9 +5,9 @@
@using ErsatzTV.Application.MediaCards @using ErsatzTV.Application.MediaCards
@using ErsatzTV.Application.MediaCollections @using ErsatzTV.Application.MediaCollections
@using ErsatzTV.Application.MediaCollections.Commands @using ErsatzTV.Application.MediaCollections.Commands
@inject IMediator Mediator @inject IMediator _mediator
@inject IDialogService Dialog @inject IDialogService _dialog
@inject NavigationManager NavigationManager @inject NavigationManager _navigationManager
<MudContainer MaxWidth="MaxWidth.False" Style="padding: 0" Class="fanart-container"> <MudContainer MaxWidth="MaxWidth.False" Style="padding: 0" Class="fanart-container">
<div class="fanart-tint"></div> <div class="fanart-tint"></div>
@@ -144,7 +144,7 @@
protected override Task OnParametersSetAsync() => RefreshData(); protected override Task OnParametersSetAsync() => RefreshData();
private Task RefreshData() => private Task RefreshData() =>
Mediator.Send(new GetMovieById(MovieId)).IfSomeAsync(vm => _mediator.Send(new GetMovieById(MovieId)).IfSomeAsync(vm =>
{ {
_movie = vm; _movie = vm;
_sortedLanguages = _movie.Languages.OrderBy(ci => ci.EnglishName).ToList(); _sortedLanguages = _movie.Languages.OrderBy(ci => ci.EnglishName).ToList();
@@ -158,12 +158,12 @@
var parameters = new DialogParameters { { "EntityType", "movie" }, { "EntityName", _movie.Title } }; var parameters = new DialogParameters { { "EntityType", "movie" }, { "EntityName", _movie.Title } };
var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall }; var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall };
IDialogReference dialog = Dialog.Show<AddToCollectionDialog>("Add To Collection", parameters, options); IDialogReference dialog = _dialog.Show<AddToCollectionDialog>("Add To Collection", parameters, options);
DialogResult result = await dialog.Result; DialogResult result = await dialog.Result;
if (!result.Cancelled && result.Data is MediaCollectionViewModel collection) if (!result.Cancelled && result.Data is MediaCollectionViewModel collection)
{ {
await Mediator.Send(new AddMovieToCollection(collection.Id, MovieId)); await _mediator.Send(new AddMovieToCollection(collection.Id, MovieId));
NavigationManager.NavigateTo($"/media/collections/{collection.Id}"); _navigationManager.NavigateTo($"/media/collections/{collection.Id}");
} }
} }
+5 -5
View File
@@ -9,8 +9,8 @@
@using ErsatzTV.Application.Search.Queries @using ErsatzTV.Application.Search.Queries
@using Unit = LanguageExt.Unit @using Unit = LanguageExt.Unit
@inherits MultiSelectBase<MovieList> @inherits MultiSelectBase<MovieList>
@inject NavigationManager NavigationManager @inject NavigationManager _navigationManager
@inject ChannelWriter<IBackgroundServiceRequest> Channel @inject ChannelWriter<IBackgroundServiceRequest> _channel
<MudPaper Square="true" Style="display: flex; height: 64px; left: 240px; padding: 0; position: fixed; right: 0; z-index: 100;"> <MudPaper Square="true" Style="display: flex; height: 64px; left: 240px; padding: 0; position: fixed; right: 0; z-index: 100;">
<div style="display: flex; flex-direction: row; margin-bottom: auto; margin-top: auto; width: 100%" class="ml-6 mr-6"> <div style="display: flex; flex-direction: row; margin-bottom: auto; margin-top: auto; width: 100%" class="ml-6 mr-6">
@@ -89,7 +89,7 @@
PageNumber = 1; PageNumber = 1;
} }
string query = new Uri(NavigationManager.Uri).Query; string query = new Uri(_navigationManager.Uri).Query;
if (QueryHelpers.ParseQuery(query).TryGetValue("query", out StringValues value)) if (QueryHelpers.ParseQuery(query).TryGetValue("query", out StringValues value))
{ {
_query = value; _query = value;
@@ -115,7 +115,7 @@
{ {
uri = QueryHelpers.AddQueryString(uri, "query", _query); uri = QueryHelpers.AddQueryString(uri, "query", _query);
} }
NavigationManager.NavigateTo(uri); _navigationManager.NavigateTo(uri);
} }
private void NextPage() private void NextPage()
@@ -125,7 +125,7 @@
{ {
uri = QueryHelpers.AddQueryString(uri, "query", _query); uri = QueryHelpers.AddQueryString(uri, "query", _query);
} }
NavigationManager.NavigateTo(uri); _navigationManager.NavigateTo(uri);
} }
private void SelectClicked(MediaCardViewModel card, MouseEventArgs e) private void SelectClicked(MediaCardViewModel card, MouseEventArgs e)
+5 -5
View File
@@ -9,8 +9,8 @@
@using ErsatzTV.Application.Search.Queries @using ErsatzTV.Application.Search.Queries
@using Unit = LanguageExt.Unit @using Unit = LanguageExt.Unit
@inherits MultiSelectBase<MusicVideoList> @inherits MultiSelectBase<MusicVideoList>
@inject NavigationManager NavigationManager @inject NavigationManager _navigationManager
@inject ChannelWriter<IBackgroundServiceRequest> Channel @inject ChannelWriter<IBackgroundServiceRequest> _channel
<MudPaper Square="true" Style="display: flex; height: 64px; left: 240px; padding: 0; position: fixed; right: 0; z-index: 100;"> <MudPaper Square="true" Style="display: flex; height: 64px; left: 240px; padding: 0; position: fixed; right: 0; z-index: 100;">
<div style="display: flex; flex-direction: row; margin-bottom: auto; margin-top: auto; width: 100%" class="ml-6 mr-6"> <div style="display: flex; flex-direction: row; margin-bottom: auto; margin-top: auto; width: 100%" class="ml-6 mr-6">
@@ -90,7 +90,7 @@
PageNumber = 1; PageNumber = 1;
} }
string query = new Uri(NavigationManager.Uri).Query; string query = new Uri(_navigationManager.Uri).Query;
if (QueryHelpers.ParseQuery(query).TryGetValue("query", out StringValues value)) if (QueryHelpers.ParseQuery(query).TryGetValue("query", out StringValues value))
{ {
_query = value; _query = value;
@@ -116,7 +116,7 @@
{ {
uri = QueryHelpers.AddQueryString(uri, "query", _query); uri = QueryHelpers.AddQueryString(uri, "query", _query);
} }
NavigationManager.NavigateTo(uri); _navigationManager.NavigateTo(uri);
} }
private void NextPage() private void NextPage()
@@ -126,7 +126,7 @@
{ {
uri = QueryHelpers.AddQueryString(uri, "query", _query); uri = QueryHelpers.AddQueryString(uri, "query", _query);
} }
NavigationManager.NavigateTo(uri); _navigationManager.NavigateTo(uri);
} }
private void SelectClicked(MediaCardViewModel card, MouseEventArgs e) private void SelectClicked(MediaCardViewModel card, MouseEventArgs e)
+10 -10
View File
@@ -3,10 +3,10 @@
@using ErsatzTV.Application.Channels.Queries @using ErsatzTV.Application.Channels.Queries
@using ErsatzTV.Application.ProgramSchedules @using ErsatzTV.Application.ProgramSchedules
@using ErsatzTV.Application.ProgramSchedules.Queries @using ErsatzTV.Application.ProgramSchedules.Queries
@inject NavigationManager NavigationManager @inject NavigationManager _navigationManager
@inject ILogger<PlayoutEditor> Logger @inject ILogger<PlayoutEditor> _logger
@inject ISnackbar Snackbar @inject ISnackbar _snackbar
@inject IMediator Mediator @inject IMediator _mediator
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8"> <MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8">
<div style="max-width: 400px;"> <div style="max-width: 400px;">
@@ -40,9 +40,9 @@
protected override async Task OnParametersSetAsync() protected override async Task OnParametersSetAsync()
{ {
_channels = await Mediator.Send(new GetAllChannels()) _channels = await _mediator.Send(new GetAllChannels())
.Map(list => list.OrderBy(vm => decimal.Parse(vm.Number)).ToList()); .Map(list => list.OrderBy(vm => decimal.Parse(vm.Number)).ToList());
_programSchedules = await Mediator.Send(new GetAllProgramSchedules()) _programSchedules = await _mediator.Send(new GetAllProgramSchedules())
.Map(list => list.OrderBy(vm => vm.Name).ToList()); .Map(list => list.OrderBy(vm => vm.Name).ToList());
} }
@@ -64,15 +64,15 @@
_messageStore.Clear(); _messageStore.Clear();
if (_editContext.Validate()) if (_editContext.Validate())
{ {
Seq<BaseError> errorMessage = (await Mediator.Send(_model.ToCreate())).LeftToSeq(); Seq<BaseError> errorMessage = (await _mediator.Send(_model.ToCreate())).LeftToSeq();
errorMessage.HeadOrNone().Match( errorMessage.HeadOrNone().Match(
error => error =>
{ {
Snackbar.Add(error.Value, Severity.Error); _snackbar.Add(error.Value, Severity.Error);
Logger.LogError("Unexpected error saving playout: {Error}", error.Value); _logger.LogError("Unexpected error saving playout: {Error}", error.Value);
}, },
() => NavigationManager.NavigateTo("/playouts")); () => _navigationManager.NavigateTo("/playouts"));
} }
} }
+7 -7
View File
@@ -2,8 +2,8 @@
@using ErsatzTV.Application.Playouts @using ErsatzTV.Application.Playouts
@using ErsatzTV.Application.Playouts.Commands @using ErsatzTV.Application.Playouts.Commands
@using ErsatzTV.Application.Playouts.Queries @using ErsatzTV.Application.Playouts.Queries
@inject IDialogService Dialog @inject IDialogService _dialog
@inject IMediator Mediator @inject IMediator _mediator
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8"> <MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8">
<MudTable Hover="true" Dense="true" Items="_playouts" SelectedItemChanged="@(async (PlayoutViewModel x) => await PlayoutSelected(x))"> <MudTable Hover="true" Dense="true" Items="_playouts" SelectedItemChanged="@(async (PlayoutViewModel x) => await PlayoutSelected(x))">
@@ -90,7 +90,7 @@
private async Task PlayoutSelected(PlayoutViewModel playout) private async Task PlayoutSelected(PlayoutViewModel playout)
{ {
_selectedPlayoutId = playout.Id; _selectedPlayoutId = playout.Id;
_selectedPlayoutItems = await Mediator.Send(new GetPlayoutItemsById(playout.Id)); _selectedPlayoutItems = await _mediator.Send(new GetPlayoutItemsById(playout.Id));
} }
private async Task DeletePlayout(PlayoutViewModel playout) private async Task DeletePlayout(PlayoutViewModel playout)
@@ -98,18 +98,18 @@
var parameters = new DialogParameters { { "EntityType", "playout" }, { "EntityName", $"{playout.ProgramSchedule.Name} on {playout.Channel.Number} - {playout.Channel.Name}" } }; var parameters = new DialogParameters { { "EntityType", "playout" }, { "EntityName", $"{playout.ProgramSchedule.Name} on {playout.Channel.Number} - {playout.Channel.Name}" } };
var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall }; var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall };
IDialogReference dialog = Dialog.Show<DeleteDialog>("Delete Playout", parameters, options); IDialogReference dialog = _dialog.Show<DeleteDialog>("Delete Playout", parameters, options);
DialogResult result = await dialog.Result; DialogResult result = await dialog.Result;
if (!result.Cancelled) if (!result.Cancelled)
{ {
await Mediator.Send(new DeletePlayout(playout.Id)); await _mediator.Send(new DeletePlayout(playout.Id));
await LoadAllPlayouts(); await LoadAllPlayouts();
} }
} }
private async Task RebuildPlayout(PlayoutViewModel playout) private async Task RebuildPlayout(PlayoutViewModel playout)
{ {
await Mediator.Send(new BuildPlayout(playout.Id, true)); await _mediator.Send(new BuildPlayout(playout.Id, true));
await LoadAllPlayouts(); await LoadAllPlayouts();
if (_selectedPlayoutId == playout.Id) if (_selectedPlayoutId == playout.Id)
{ {
@@ -118,7 +118,7 @@
} }
private async Task LoadAllPlayouts() => private async Task LoadAllPlayouts() =>
_playouts = await Mediator.Send(new GetAllPlayouts()) _playouts = await _mediator.Send(new GetAllPlayouts())
.Map(list => list.OrderBy(x => decimal.Parse(x.Channel.Number)).ToList()); .Map(list => list.OrderBy(x => decimal.Parse(x.Channel.Number)).ToList());
+23 -23
View File
@@ -4,13 +4,13 @@
@using ErsatzTV.Application.Plex.Commands @using ErsatzTV.Application.Plex.Commands
@using ErsatzTV.Application.Plex.Queries @using ErsatzTV.Application.Plex.Queries
@implements IDisposable @implements IDisposable
@inject IDialogService Dialog @inject IDialogService _dialog
@inject IMediator Mediator @inject IMediator _mediator
@inject IEntityLocker Locker @inject IEntityLocker _locker
@inject ISnackbar Snackbar @inject ISnackbar _snackbar
@inject ILogger<PlexMediaSources> Logger @inject ILogger<PlexMediaSources> _logger
@inject IJSRuntime JsRuntime @inject IJSRuntime _jsRuntime
@inject IPlexSecretStore PlexSecretStore @inject IPlexSecretStore _plexSecretStore
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8"> <MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8">
<MudTable Hover="true" Dense="true" Items="_mediaSources"> <MudTable Hover="true" Dense="true" Items="_mediaSources">
@@ -51,7 +51,7 @@
<MudButton Variant="Variant.Filled" <MudButton Variant="Variant.Filled"
Color="Color.Error" Color="Color.Error"
OnClick="@(_ => SignOutOfPlex())" OnClick="@(_ => SignOutOfPlex())"
Disabled="@Locker.IsPlexLocked()" Disabled="@_locker.IsPlexLocked()"
Class="mt-4"> Class="mt-4">
Sign out of plex Sign out of plex
</MudButton> </MudButton>
@@ -61,7 +61,7 @@
<MudButton Variant="Variant.Filled" <MudButton Variant="Variant.Filled"
Color="Color.Primary" Color="Color.Primary"
OnClick="@(_ => AddPlexMediaSource())" OnClick="@(_ => AddPlexMediaSource())"
Disabled="@Locker.IsPlexLocked()" Disabled="@_locker.IsPlexLocked()"
Class="mt-4"> Class="mt-4">
Sign in to plex Sign in to plex
</MudButton> </MudButton>
@@ -72,7 +72,7 @@
<MudButton Variant="Variant.Filled" <MudButton Variant="Variant.Filled"
Color="Color.Secondary" Color="Color.Secondary"
OnClick="@(_ => AddPlexMediaSource())" OnClick="@(_ => AddPlexMediaSource())"
Disabled="@Locker.IsPlexLocked()" Disabled="@_locker.IsPlexLocked()"
Class="ml-4 mt-4"> Class="ml-4 mt-4">
Fix Plex Credentials Fix Plex Credentials
</MudButton> </MudButton>
@@ -88,24 +88,24 @@
protected override async Task OnParametersSetAsync() => await LoadMediaSources(); protected override async Task OnParametersSetAsync() => await LoadMediaSources();
protected override void OnInitialized() => protected override void OnInitialized() =>
Locker.OnPlexChanged += PlexChanged; _locker.OnPlexChanged += PlexChanged;
private async Task LoadMediaSources() private async Task LoadMediaSources()
{ {
_isAuthorized = await PlexSecretStore.GetUserAuthTokens().Map(list => Prelude.Optional(list).Flatten().Any()); _isAuthorized = await _plexSecretStore.GetUserAuthTokens().Map(list => Prelude.Optional(list).Flatten().Any());
_mediaSources = await Mediator.Send(new GetAllPlexMediaSources()); _mediaSources = await _mediator.Send(new GetAllPlexMediaSources());
} }
private async Task SignOutOfPlex() private async Task SignOutOfPlex()
{ {
var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.Small }; var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.Small };
IDialogReference dialog = Dialog.Show<SignOutOfPlexDialog>("Sign out of Plex", options); IDialogReference dialog = _dialog.Show<SignOutOfPlexDialog>("Sign out of Plex", options);
DialogResult result = await dialog.Result; DialogResult result = await dialog.Result;
if (!result.Cancelled) if (!result.Cancelled)
{ {
if (Locker.LockPlex()) if (_locker.LockPlex())
{ {
await Mediator.Send(new SignOutOfPlex()); await _mediator.Send(new SignOutOfPlex());
await LoadMediaSources(); await LoadMediaSources();
} }
} }
@@ -113,16 +113,16 @@
private async Task AddPlexMediaSource() private async Task AddPlexMediaSource()
{ {
if (Locker.LockPlex()) if (_locker.LockPlex())
{ {
Either<BaseError, string> maybeUrl = await Mediator.Send(new StartPlexPinFlow()); Either<BaseError, string> maybeUrl = await _mediator.Send(new StartPlexPinFlow());
await maybeUrl.Match( await maybeUrl.Match(
async url => await JsRuntime.InvokeAsync<object>("open", new object[] { url, "_blank" }), async url => await _jsRuntime.InvokeAsync<object>("open", new object[] { url, "_blank" }),
error => error =>
{ {
Locker.UnlockPlex(); _locker.UnlockPlex();
Snackbar.Add(error.Value, Severity.Error); _snackbar.Add(error.Value, Severity.Error);
Logger.LogError("Unexpected error generating plex auth app url: {Error}", error.Value); _logger.LogError("Unexpected error generating plex auth app url: {Error}", error.Value);
return Task.CompletedTask; return Task.CompletedTask;
}); });
} }
@@ -134,6 +134,6 @@
await InvokeAsync(StateHasChanged); await InvokeAsync(StateHasChanged);
} }
void IDisposable.Dispose() => Locker.OnPlexChanged -= PlexChanged; void IDisposable.Dispose() => _locker.OnPlexChanged -= PlexChanged;
} }
+11 -11
View File
@@ -2,10 +2,10 @@
@page "/schedules/add" @page "/schedules/add"
@using ErsatzTV.Application.ProgramSchedules @using ErsatzTV.Application.ProgramSchedules
@using ErsatzTV.Application.ProgramSchedules.Queries @using ErsatzTV.Application.ProgramSchedules.Queries
@inject NavigationManager NavigationManager @inject NavigationManager _navigationManager
@inject ILogger<ScheduleEditor> Logger @inject ILogger<ScheduleEditor> _logger
@inject ISnackbar Snackbar @inject ISnackbar _snackbar
@inject IMediator Mediator @inject IMediator _mediator
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8"> <MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8">
<div style="max-width: 400px;"> <div style="max-width: 400px;">
@@ -52,7 +52,7 @@
{ {
if (IsEdit) if (IsEdit)
{ {
Option<ProgramScheduleViewModel> maybeProgramSchedule = await Mediator.Send(new GetProgramScheduleById(Id)); Option<ProgramScheduleViewModel> maybeProgramSchedule = await _mediator.Send(new GetProgramScheduleById(Id));
maybeProgramSchedule.Match( maybeProgramSchedule.Match(
viewModel => viewModel =>
{ {
@@ -61,7 +61,7 @@
_model.MediaCollectionPlaybackOrder = viewModel.MediaCollectionPlaybackOrder; _model.MediaCollectionPlaybackOrder = viewModel.MediaCollectionPlaybackOrder;
_model.KeepMultiPartEpisodesTogether = viewModel.KeepMultiPartEpisodesTogether; _model.KeepMultiPartEpisodesTogether = viewModel.KeepMultiPartEpisodesTogether;
}, },
() => NavigationManager.NavigateTo("404")); () => _navigationManager.NavigateTo("404"));
} }
else else
{ {
@@ -84,19 +84,19 @@
if (_editContext.Validate()) if (_editContext.Validate())
{ {
Either<BaseError, ProgramScheduleViewModel> result = IsEdit ? Either<BaseError, ProgramScheduleViewModel> result = IsEdit ?
await Mediator.Send(_model.ToUpdate()) : await _mediator.Send(_model.ToUpdate()) :
await Mediator.Send(_model.ToCreate()); await _mediator.Send(_model.ToCreate());
result.Match( result.Match(
programSchedule => programSchedule =>
{ {
string destination = IsEdit ? "/schedules" : $"/schedules/{programSchedule.Id}/items"; string destination = IsEdit ? "/schedules" : $"/schedules/{programSchedule.Id}/items";
NavigationManager.NavigateTo(destination); _navigationManager.NavigateTo(destination);
}, },
error => error =>
{ {
Snackbar.Add(error.Value, Severity.Error); _snackbar.Add(error.Value, Severity.Error);
Logger.LogError("Unexpected error saving schedule: {Error}", error.Value); _logger.LogError("Unexpected error saving schedule: {Error}", error.Value);
}); });
} }
} }
+13 -13
View File
@@ -6,10 +6,10 @@
@using ErsatzTV.Application.ProgramSchedules.Commands @using ErsatzTV.Application.ProgramSchedules.Commands
@using ErsatzTV.Application.ProgramSchedules.Queries @using ErsatzTV.Application.ProgramSchedules.Queries
@using ErsatzTV.Application.Television.Queries @using ErsatzTV.Application.Television.Queries
@inject NavigationManager NavigationManager @inject NavigationManager _navigationManager
@inject ILogger<ScheduleItemsEditor> Logger @inject ILogger<ScheduleItemsEditor> _logger
@inject ISnackbar Snackbar @inject ISnackbar _snackbar
@inject IMediator Mediator @inject IMediator _mediator
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8"> <MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8">
<MudTable Hover="true" Items="_schedule.Items.OrderBy(i => i.Index)" Dense="true" @bind-SelectedItem="_selectedItem"> <MudTable Hover="true" Items="_schedule.Items.OrderBy(i => i.Index)" Dense="true" @bind-SelectedItem="_selectedItem">
@@ -184,15 +184,15 @@
private async Task LoadScheduleItems() private async Task LoadScheduleItems()
{ {
_mediaCollections = await Mediator.Send(new GetAllCollections()); _mediaCollections = await _mediator.Send(new GetAllCollections());
_televisionShows = await Mediator.Send(new GetAllTelevisionShows()); _televisionShows = await _mediator.Send(new GetAllTelevisionShows());
_televisionSeasons = await Mediator.Send(new GetAllTelevisionSeasons()); _televisionSeasons = await _mediator.Send(new GetAllTelevisionSeasons());
string name = string.Empty; string name = string.Empty;
Option<ProgramScheduleViewModel> maybeSchedule = await Mediator.Send(new GetProgramScheduleById(Id)); Option<ProgramScheduleViewModel> maybeSchedule = await _mediator.Send(new GetProgramScheduleById(Id));
maybeSchedule.IfSome(vm => name = vm.Name); maybeSchedule.IfSome(vm => name = vm.Name);
Option<IEnumerable<ProgramScheduleItemViewModel>> maybeResults = await Mediator.Send(new GetProgramScheduleItems(Id)); Option<IEnumerable<ProgramScheduleItemViewModel>> maybeResults = await _mediator.Send(new GetProgramScheduleItems(Id));
maybeResults.IfSome(items => _schedule = new ProgramScheduleItemsEditViewModel maybeResults.IfSome(items => _schedule = new ProgramScheduleItemsEditViewModel
{ {
Name = name, Name = name,
@@ -291,15 +291,15 @@
item.PlayoutMode == PlayoutMode.Duration ? item.OfflineTail.IfNone(false) : null, item.PlayoutMode == PlayoutMode.Duration ? item.OfflineTail.IfNone(false) : null,
item.CustomTitle)).ToList(); item.CustomTitle)).ToList();
Seq<BaseError> errorMessages = await Mediator.Send(new ReplaceProgramScheduleItems(Id, items)).Map(e => e.LeftToSeq()); Seq<BaseError> errorMessages = await _mediator.Send(new ReplaceProgramScheduleItems(Id, items)).Map(e => e.LeftToSeq());
errorMessages.HeadOrNone().Match( errorMessages.HeadOrNone().Match(
error => error =>
{ {
Snackbar.Add($"Unexpected error saving schedule: {error.Value}", Severity.Error); _snackbar.Add($"Unexpected error saving schedule: {error.Value}", Severity.Error);
Logger.LogError("Unexpected error saving schedule: {Error}", error.Value); _logger.LogError("Unexpected error saving schedule: {Error}", error.Value);
}, },
() => NavigationManager.NavigateTo("/schedules")); () => _navigationManager.NavigateTo("/schedules"));
} }
} }
+6 -6
View File
@@ -2,8 +2,8 @@
@using ErsatzTV.Application.ProgramSchedules @using ErsatzTV.Application.ProgramSchedules
@using ErsatzTV.Application.ProgramSchedules.Commands @using ErsatzTV.Application.ProgramSchedules.Commands
@using ErsatzTV.Application.ProgramSchedules.Queries @using ErsatzTV.Application.ProgramSchedules.Queries
@inject IDialogService Dialog @inject IDialogService _dialog
@inject IMediator Mediator @inject IMediator _mediator
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8"> <MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8">
<MudTable Hover="true" Items="_schedules" Dense="true" SelectedItemChanged="@(async (ProgramScheduleViewModel x) => await ScheduleSelected(x))"> <MudTable Hover="true" Items="_schedules" Dense="true" SelectedItemChanged="@(async (ProgramScheduleViewModel x) => await ScheduleSelected(x))">
@@ -91,7 +91,7 @@
private async Task ScheduleSelected(ProgramScheduleViewModel schedule) private async Task ScheduleSelected(ProgramScheduleViewModel schedule)
{ {
_selectedSchedule = schedule; _selectedSchedule = schedule;
await Mediator.Send(new GetProgramScheduleItems(schedule.Id)) await _mediator.Send(new GetProgramScheduleItems(schedule.Id))
.IterT(results => _selectedScheduleItems = results.OrderBy(x => x.Name).ToList()); .IterT(results => _selectedScheduleItems = results.OrderBy(x => x.Name).ToList());
} }
@@ -100,16 +100,16 @@
var parameters = new DialogParameters { { "EntityType", "schedule" }, { "EntityName", programSchedule.Name } }; var parameters = new DialogParameters { { "EntityType", "schedule" }, { "EntityName", programSchedule.Name } };
var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall }; var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall };
IDialogReference dialog = Dialog.Show<DeleteDialog>("Delete Schedule", parameters, options); IDialogReference dialog = _dialog.Show<DeleteDialog>("Delete Schedule", parameters, options);
DialogResult result = await dialog.Result; DialogResult result = await dialog.Result;
if (!result.Cancelled) if (!result.Cancelled)
{ {
await Mediator.Send(new DeleteProgramSchedule(programSchedule.Id)); await _mediator.Send(new DeleteProgramSchedule(programSchedule.Id));
await LoadSchedules(); await LoadSchedules();
} }
} }
private async Task LoadSchedules() => private async Task LoadSchedules() =>
_schedules = await Mediator.Send(new GetAllProgramSchedules()).Map(list => list.OrderBy(vm => vm.Name).ToList()); _schedules = await _mediator.Send(new GetAllProgramSchedules()).Map(list => list.OrderBy(vm => vm.Name).ToList());
} }
+7 -7
View File
@@ -8,8 +8,8 @@
@using Microsoft.Extensions.Primitives @using Microsoft.Extensions.Primitives
@using Unit = LanguageExt.Unit @using Unit = LanguageExt.Unit
@inherits MultiSelectBase<Search> @inherits MultiSelectBase<Search>
@inject NavigationManager NavigationManager @inject NavigationManager _navigationManager
@inject ChannelWriter<IBackgroundServiceRequest> Channel @inject ChannelWriter<IBackgroundServiceRequest> _channel
<MudPaper Square="true" Style="display: flex; height: 64px; left: 240px; padding: 0; position: fixed; right: 0; z-index: 100;"> <MudPaper Square="true" Style="display: flex; height: 64px; left: 240px; padding: 0; position: fixed; right: 0; z-index: 100;">
<div style="display: flex; flex-direction: row; margin-bottom: auto; margin-top: auto; width: 100%" class="ml-6 mr-6"> <div style="display: flex; flex-direction: row; margin-bottom: auto; margin-top: auto; width: 100%" class="ml-6 mr-6">
@@ -37,22 +37,22 @@
<MudText Style="margin-bottom: auto; margin-top: auto">@_query</MudText> <MudText Style="margin-bottom: auto; margin-top: auto">@_query</MudText>
if (_movies.Count > 0) if (_movies.Count > 0)
{ {
<MudLink Class="ml-4" Href="@(NavigationManager.Uri.Split("#").Head() + "#movies")" Style="margin-bottom: auto; margin-top: auto">@_movies.Count Movies</MudLink> <MudLink Class="ml-4" Href="@(_navigationManager.Uri.Split("#").Head() + "#movies")" Style="margin-bottom: auto; margin-top: auto">@_movies.Count Movies</MudLink>
} }
if (_shows.Count > 0) if (_shows.Count > 0)
{ {
<MudLink Class="ml-4" Href="@(NavigationManager.Uri.Split("#").Head() + "#shows")" Style="margin-bottom: auto; margin-top: auto">@_shows.Count Shows</MudLink> <MudLink Class="ml-4" Href="@(_navigationManager.Uri.Split("#").Head() + "#shows")" Style="margin-bottom: auto; margin-top: auto">@_shows.Count Shows</MudLink>
} }
if (_artists.Count > 0) if (_artists.Count > 0)
{ {
<MudLink Class="ml-4" Href="@(NavigationManager.Uri.Split("#").Head() + "#artists")" Style="margin-bottom: auto; margin-top: auto">@_artists.Count Artists</MudLink> <MudLink Class="ml-4" Href="@(_navigationManager.Uri.Split("#").Head() + "#artists")" Style="margin-bottom: auto; margin-top: auto">@_artists.Count Artists</MudLink>
} }
if (_musicVideos.Count > 0) if (_musicVideos.Count > 0)
{ {
<MudLink Class="ml-4" Href="@(NavigationManager.Uri.Split("#").Head() + "#music_videos")" Style="margin-bottom: auto; margin-top: auto">@_musicVideos.Count Music Videos</MudLink> <MudLink Class="ml-4" Href="@(_navigationManager.Uri.Split("#").Head() + "#music_videos")" Style="margin-bottom: auto; margin-top: auto">@_musicVideos.Count Music Videos</MudLink>
} }
<div style="margin-left: auto"> <div style="margin-left: auto">
<MudButton Variant="Variant.Filled" <MudButton Variant="Variant.Filled"
@@ -186,7 +186,7 @@
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
string query = new Uri(NavigationManager.Uri).Query; string query = new Uri(_navigationManager.Uri).Query;
if (QueryHelpers.ParseQuery(query).TryGetValue("query", out StringValues value)) if (QueryHelpers.ParseQuery(query).TryGetValue("query", out StringValues value))
{ {
+21 -21
View File
@@ -9,13 +9,13 @@
@using ErsatzTV.Application.ProgramSchedules @using ErsatzTV.Application.ProgramSchedules
@using ErsatzTV.Application.ProgramSchedules.Commands @using ErsatzTV.Application.ProgramSchedules.Commands
@using Unit = LanguageExt.Unit @using Unit = LanguageExt.Unit
@inject IMediator Mediator @inject IMediator _mediator
@inject ILogger<TelevisionEpisodeList> Logger @inject ILogger<TelevisionEpisodeList> _logger
@inject ISnackbar Snackbar @inject ISnackbar _snackbar
@inject IDialogService Dialog @inject IDialogService _dialog
@inject NavigationManager NavigationManager @inject NavigationManager _navigationManager
@inject ChannelWriter<IBackgroundServiceRequest> Channel @inject ChannelWriter<IBackgroundServiceRequest> _channel
@inject IJSRuntime JsRuntime @inject IJSRuntime _jsRuntime
<MudContainer MaxWidth="MaxWidth.False" Style="padding: 0" Class="fanart-container"> <MudContainer MaxWidth="MaxWidth.False" Style="padding: 0" Class="fanart-container">
<div class="fanart-tint"></div> <div class="fanart-tint"></div>
@@ -126,7 +126,7 @@
{ {
if (firstRender) if (firstRender)
{ {
await NavigationManager.NavigateToFragmentAsync(JsRuntime); await _navigationManager.NavigateToFragmentAsync(_jsRuntime);
} }
} }
@@ -134,10 +134,10 @@
private async Task RefreshData() private async Task RefreshData()
{ {
await Mediator.Send(new GetTelevisionSeasonById(SeasonId)) await _mediator.Send(new GetTelevisionSeasonById(SeasonId))
.IfSomeAsync(vm => _season = vm); .IfSomeAsync(vm => _season = vm);
_data = await Mediator.Send(new GetTelevisionEpisodeCards(SeasonId, _pageNumber, _pageSize)); _data = await _mediator.Send(new GetTelevisionEpisodeCards(SeasonId, _pageNumber, _pageSize));
} }
private async Task AddToCollection() private async Task AddToCollection()
@@ -145,12 +145,12 @@
var parameters = new DialogParameters { { "EntityType", "season" }, { "EntityName", $"{_season.Title} - {_season.Name}" } }; var parameters = new DialogParameters { { "EntityType", "season" }, { "EntityName", $"{_season.Title} - {_season.Name}" } };
var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall }; var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall };
IDialogReference dialog = Dialog.Show<AddToCollectionDialog>("Add To Collection", parameters, options); IDialogReference dialog = _dialog.Show<AddToCollectionDialog>("Add To Collection", parameters, options);
DialogResult result = await dialog.Result; DialogResult result = await dialog.Result;
if (!result.Cancelled && result.Data is MediaCollectionViewModel collection) if (!result.Cancelled && result.Data is MediaCollectionViewModel collection)
{ {
await Mediator.Send(new AddSeasonToCollection(collection.Id, SeasonId)); await _mediator.Send(new AddSeasonToCollection(collection.Id, SeasonId));
NavigationManager.NavigateTo($"/media/collections/{collection.Id}"); _navigationManager.NavigateTo($"/media/collections/{collection.Id}");
} }
} }
@@ -160,12 +160,12 @@
var parameters = new DialogParameters { { "EntityType", "season" }, { "EntityName", $"{_season.Title} - {_season.Name}" } }; var parameters = new DialogParameters { { "EntityType", "season" }, { "EntityName", $"{_season.Title} - {_season.Name}" } };
var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall }; var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall };
IDialogReference dialog = Dialog.Show<AddToScheduleDialog>("Add To Schedule", parameters, options); IDialogReference dialog = _dialog.Show<AddToScheduleDialog>("Add To Schedule", parameters, options);
DialogResult result = await dialog.Result; DialogResult result = await dialog.Result;
if (!result.Cancelled && result.Data is ProgramScheduleViewModel schedule) if (!result.Cancelled && result.Data is ProgramScheduleViewModel schedule)
{ {
await Mediator.Send(new AddProgramScheduleItem(schedule.Id, StartType.Dynamic, null, PlayoutMode.One, ProgramScheduleItemCollectionType.TelevisionSeason, null, SeasonId, null, null, null, null)); await _mediator.Send(new AddProgramScheduleItem(schedule.Id, StartType.Dynamic, null, PlayoutMode.One, ProgramScheduleItemCollectionType.TelevisionSeason, null, SeasonId, null, null, null, null));
NavigationManager.NavigateTo($"/schedules/{schedule.Id}/items"); _navigationManager.NavigateTo($"/schedules/{schedule.Id}/items");
} }
} }
@@ -174,19 +174,19 @@
var parameters = new DialogParameters { { "EntityType", "episode" }, { "EntityName", episode.Title } }; var parameters = new DialogParameters { { "EntityType", "episode" }, { "EntityName", episode.Title } };
var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall }; var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall };
IDialogReference dialog = Dialog.Show<AddToCollectionDialog>("Add To Collection", parameters, options); IDialogReference dialog = _dialog.Show<AddToCollectionDialog>("Add To Collection", parameters, options);
DialogResult result = await dialog.Result; DialogResult result = await dialog.Result;
if (!result.Cancelled && result.Data is MediaCollectionViewModel collection) if (!result.Cancelled && result.Data is MediaCollectionViewModel collection)
{ {
var request = new AddEpisodeToCollection(collection.Id, episode.EpisodeId); var request = new AddEpisodeToCollection(collection.Id, episode.EpisodeId);
Either<BaseError, Unit> addResult = await Mediator.Send(request); Either<BaseError, Unit> addResult = await _mediator.Send(request);
addResult.Match( addResult.Match(
Left: error => Left: error =>
{ {
Snackbar.Add($"Unexpected error adding episode to collection: {error.Value}"); _snackbar.Add($"Unexpected error adding episode to collection: {error.Value}");
Logger.LogError("Unexpected error adding episode to collection: {Error}", error.Value); _logger.LogError("Unexpected error adding episode to collection: {Error}", error.Value);
}, },
Right: _ => Snackbar.Add($"Added {episode.Title} to collection {collection.Name}", Severity.Success)); Right: _ => _snackbar.Add($"Added {episode.Title} to collection {collection.Name}", Severity.Success));
} }
} }
+19 -19
View File
@@ -9,12 +9,12 @@
@using ErsatzTV.Application.ProgramSchedules @using ErsatzTV.Application.ProgramSchedules
@using ErsatzTV.Application.ProgramSchedules.Commands @using ErsatzTV.Application.ProgramSchedules.Commands
@using Unit = LanguageExt.Unit @using Unit = LanguageExt.Unit
@inject IMediator Mediator @inject IMediator _mediator
@inject ILogger<TelevisionSeasonList> Logger @inject ILogger<TelevisionSeasonList> _logger
@inject ISnackbar Snackbar @inject ISnackbar _snackbar
@inject IDialogService Dialog @inject IDialogService _dialog
@inject NavigationManager NavigationManager @inject NavigationManager _navigationManager
@inject ChannelWriter<IBackgroundServiceRequest> Channel @inject ChannelWriter<IBackgroundServiceRequest> _channel
<MudContainer MaxWidth="MaxWidth.False" Style="padding: 0" Class="fanart-container"> <MudContainer MaxWidth="MaxWidth.False" Style="padding: 0" Class="fanart-container">
<div class="fanart-tint"></div> <div class="fanart-tint"></div>
@@ -175,7 +175,7 @@
private async Task RefreshData() private async Task RefreshData()
{ {
await Mediator.Send(new GetTelevisionShowById(ShowId)) await _mediator.Send(new GetTelevisionShowById(ShowId))
.IfSomeAsync(vm => .IfSomeAsync(vm =>
{ {
_show = vm; _show = vm;
@@ -185,7 +185,7 @@
_sortedTags = _show.Tags.OrderBy(t => t).ToList(); _sortedTags = _show.Tags.OrderBy(t => t).ToList();
}); });
_data = await Mediator.Send(new GetTelevisionSeasonCards(ShowId, _pageNumber, _pageSize)); _data = await _mediator.Send(new GetTelevisionSeasonCards(ShowId, _pageNumber, _pageSize));
} }
private async Task AddToCollection() private async Task AddToCollection()
@@ -193,12 +193,12 @@
var parameters = new DialogParameters { { "EntityType", "show" }, { "EntityName", _show.Title } }; var parameters = new DialogParameters { { "EntityType", "show" }, { "EntityName", _show.Title } };
var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall }; var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall };
IDialogReference dialog = Dialog.Show<AddToCollectionDialog>("Add To Collection", parameters, options); IDialogReference dialog = _dialog.Show<AddToCollectionDialog>("Add To Collection", parameters, options);
DialogResult result = await dialog.Result; DialogResult result = await dialog.Result;
if (!result.Cancelled && result.Data is MediaCollectionViewModel collection) if (!result.Cancelled && result.Data is MediaCollectionViewModel collection)
{ {
await Mediator.Send(new AddShowToCollection(collection.Id, ShowId)); await _mediator.Send(new AddShowToCollection(collection.Id, ShowId));
NavigationManager.NavigateTo($"/media/collections/{collection.Id}"); _navigationManager.NavigateTo($"/media/collections/{collection.Id}");
} }
} }
@@ -207,12 +207,12 @@
var parameters = new DialogParameters { { "EntityType", "show" }, { "EntityName", _show.Title } }; var parameters = new DialogParameters { { "EntityType", "show" }, { "EntityName", _show.Title } };
var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall }; var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall };
IDialogReference dialog = Dialog.Show<AddToScheduleDialog>("Add To Schedule", parameters, options); IDialogReference dialog = _dialog.Show<AddToScheduleDialog>("Add To Schedule", parameters, options);
DialogResult result = await dialog.Result; DialogResult result = await dialog.Result;
if (!result.Cancelled && result.Data is ProgramScheduleViewModel schedule) if (!result.Cancelled && result.Data is ProgramScheduleViewModel schedule)
{ {
await Mediator.Send(new AddProgramScheduleItem(schedule.Id, StartType.Dynamic, null, PlayoutMode.One, ProgramScheduleItemCollectionType.TelevisionShow, null, ShowId, null, null, null, null)); await _mediator.Send(new AddProgramScheduleItem(schedule.Id, StartType.Dynamic, null, PlayoutMode.One, ProgramScheduleItemCollectionType.TelevisionShow, null, ShowId, null, null, null, null));
NavigationManager.NavigateTo($"/schedules/{schedule.Id}/items"); _navigationManager.NavigateTo($"/schedules/{schedule.Id}/items");
} }
} }
@@ -223,19 +223,19 @@
var parameters = new DialogParameters { { "EntityType", "season" }, { "EntityName", season.Title } }; var parameters = new DialogParameters { { "EntityType", "season" }, { "EntityName", season.Title } };
var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall }; var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall };
IDialogReference dialog = Dialog.Show<AddToCollectionDialog>("Add To Collection", parameters, options); IDialogReference dialog = _dialog.Show<AddToCollectionDialog>("Add To Collection", parameters, options);
DialogResult result = await dialog.Result; DialogResult result = await dialog.Result;
if (!result.Cancelled && result.Data is MediaCollectionViewModel collection) if (!result.Cancelled && result.Data is MediaCollectionViewModel collection)
{ {
var request = new AddSeasonToCollection(collection.Id, season.TelevisionSeasonId); var request = new AddSeasonToCollection(collection.Id, season.TelevisionSeasonId);
Either<BaseError, Unit> addResult = await Mediator.Send(request); Either<BaseError, Unit> addResult = await _mediator.Send(request);
addResult.Match( addResult.Match(
Left: error => Left: error =>
{ {
Snackbar.Add($"Unexpected error adding season to collection: {error.Value}"); _snackbar.Add($"Unexpected error adding season to collection: {error.Value}");
Logger.LogError("Unexpected error adding season to collection: {Error}", error.Value); _logger.LogError("Unexpected error adding season to collection: {Error}", error.Value);
}, },
Right: _ => Snackbar.Add($"Added {season.Title} to collection {collection.Name}", Severity.Success)); Right: _ => _snackbar.Add($"Added {season.Title} to collection {collection.Name}", Severity.Success));
} }
} }
} }
+5 -5
View File
@@ -9,8 +9,8 @@
@using ErsatzTV.Application.Search.Queries @using ErsatzTV.Application.Search.Queries
@using Unit = LanguageExt.Unit @using Unit = LanguageExt.Unit
@inherits MultiSelectBase<TelevisionShowList> @inherits MultiSelectBase<TelevisionShowList>
@inject NavigationManager NavigationManager @inject NavigationManager _navigationManager
@inject ChannelWriter<IBackgroundServiceRequest> Channel @inject ChannelWriter<IBackgroundServiceRequest> _channel
<MudPaper Square="true" Style="display: flex; height: 64px; left: 240px; padding: 0; position: fixed; right: 0; z-index: 100;"> <MudPaper Square="true" Style="display: flex; height: 64px; left: 240px; padding: 0; position: fixed; right: 0; z-index: 100;">
<div style="display: flex; flex-direction: row; margin-bottom: auto; margin-top: auto; width: 100%" class="ml-6 mr-6"> <div style="display: flex; flex-direction: row; margin-bottom: auto; margin-top: auto; width: 100%" class="ml-6 mr-6">
@@ -89,7 +89,7 @@
PageNumber = 1; PageNumber = 1;
} }
string query = new Uri(NavigationManager.Uri).Query; string query = new Uri(_navigationManager.Uri).Query;
if (QueryHelpers.ParseQuery(query).TryGetValue("query", out StringValues value)) if (QueryHelpers.ParseQuery(query).TryGetValue("query", out StringValues value))
{ {
_query = value; _query = value;
@@ -115,7 +115,7 @@
{ {
uri = QueryHelpers.AddQueryString(uri, "query", _query); uri = QueryHelpers.AddQueryString(uri, "query", _query);
} }
NavigationManager.NavigateTo(uri); _navigationManager.NavigateTo(uri);
} }
private void NextPage() private void NextPage()
@@ -125,7 +125,7 @@
{ {
uri = QueryHelpers.AddQueryString(uri, "query", _query); uri = QueryHelpers.AddQueryString(uri, "query", _query);
} }
NavigationManager.NavigateTo(uri); _navigationManager.NavigateTo(uri);
} }
private void SelectClicked(MediaCardViewModel card, MouseEventArgs e) private void SelectClicked(MediaCardViewModel card, MouseEventArgs e)
+11 -11
View File
@@ -2,10 +2,10 @@
@using ErsatzTV.Application.MediaCollections @using ErsatzTV.Application.MediaCollections
@using ErsatzTV.Application.MediaCollections.Commands @using ErsatzTV.Application.MediaCollections.Commands
@using ErsatzTV.Application.MediaCollections.Queries @using ErsatzTV.Application.MediaCollections.Queries
@inject IMediator Mediator @inject IMediator _mediator
@inject IMemoryCache MemoryCache @inject IMemoryCache _memoryCache
@inject ISnackbar Snackbar @inject ISnackbar _snackbar
@inject ILogger<AddToCollectionDialog> Logger @inject ILogger<AddToCollectionDialog> _logger
<MudDialog> <MudDialog>
<DialogContent> <DialogContent>
@@ -71,10 +71,10 @@
protected override async Task OnParametersSetAsync() protected override async Task OnParametersSetAsync()
{ {
_collections = await Mediator.Send(new GetAllCollections()) _collections = await _mediator.Send(new GetAllCollections())
.Map(list => new[] { _newCollection }.Append(list).ToList()); .Map(list => new[] { _newCollection }.Append(list).ToList());
if (MemoryCache.TryGetValue("AddToCollectionDialog.SelectedCollectionId", out int id)) if (_memoryCache.TryGetValue("AddToCollectionDialog.SelectedCollectionId", out int id))
{ {
_selectedCollection = _collections.SingleOrDefault(c => c.Id == id) ?? _newCollection; _selectedCollection = _collections.SingleOrDefault(c => c.Id == id) ?? _newCollection;
} }
@@ -96,24 +96,24 @@
if (_selectedCollection == _newCollection) if (_selectedCollection == _newCollection)
{ {
Either<BaseError, MediaCollectionViewModel> maybeResult = Either<BaseError, MediaCollectionViewModel> maybeResult =
await Mediator.Send(new CreateCollection(_newCollectionName)); await _mediator.Send(new CreateCollection(_newCollectionName));
maybeResult.Match( maybeResult.Match(
collection => collection =>
{ {
MemoryCache.Set("AddToCollectionDialog.SelectedCollectionId", collection.Id); _memoryCache.Set("AddToCollectionDialog.SelectedCollectionId", collection.Id);
MudDialog.Close(DialogResult.Ok(collection)); MudDialog.Close(DialogResult.Ok(collection));
}, },
error => error =>
{ {
Snackbar.Add(error.Value, Severity.Error); _snackbar.Add(error.Value, Severity.Error);
Logger.LogError("Error creating new collection: {Error}", error.Value); _logger.LogError("Error creating new collection: {Error}", error.Value);
MudDialog.Close(DialogResult.Cancel()); MudDialog.Close(DialogResult.Cancel());
}); });
} }
else else
{ {
MemoryCache.Set("AddToCollectionDialog.SelectedCollectionId", _selectedCollection.Id); _memoryCache.Set("AddToCollectionDialog.SelectedCollectionId", _selectedCollection.Id);
MudDialog.Close(DialogResult.Ok(_selectedCollection)); MudDialog.Close(DialogResult.Ok(_selectedCollection));
} }
} }
+2 -2
View File
@@ -1,6 +1,6 @@
@using ErsatzTV.Application.ProgramSchedules @using ErsatzTV.Application.ProgramSchedules
@using ErsatzTV.Application.ProgramSchedules.Queries @using ErsatzTV.Application.ProgramSchedules.Queries
@inject IMediator Mediator @inject IMediator _mediator
<div @onkeydown="@OnKeyDown"> <div @onkeydown="@OnKeyDown">
<MudDialog> <MudDialog>
@@ -49,7 +49,7 @@
private ProgramScheduleViewModel _selectedSchedule; private ProgramScheduleViewModel _selectedSchedule;
protected override async Task OnParametersSetAsync() => protected override async Task OnParametersSetAsync() =>
_schedules = await Mediator.Send(new GetAllProgramSchedules()); _schedules = await _mediator.Send(new GetAllProgramSchedules());
private string FormatText() => $"Select the schedule to add the {EntityType} {EntityName}"; private string FormatText() => $"Select the schedule to add the {EntityType} {EntityName}";
+3 -13
View File
@@ -3,7 +3,7 @@
@using Microsoft.Extensions.Primitives @using Microsoft.Extensions.Primitives
@using System.Web @using System.Web
@inherits LayoutComponentBase @inherits LayoutComponentBase
@inject NavigationManager NavigationManager @inject NavigationManager _navigationManager
<MudThemeProvider Theme="_ersatzTvTheme"/> <MudThemeProvider Theme="_ersatzTvTheme"/>
<MudDialogProvider DisableBackdropClick="true"/> <MudDialogProvider DisableBackdropClick="true"/>
@@ -107,7 +107,7 @@
{ {
await base.OnParametersSetAsync(); await base.OnParametersSetAsync();
string query = new Uri(NavigationManager.Uri).Query; string query = new Uri(_navigationManager.Uri).Query;
if (QueryHelpers.ParseQuery(query).TryGetValue("query", out StringValues value)) if (QueryHelpers.ParseQuery(query).TryGetValue("query", out StringValues value))
{ {
_query = value; _query = value;
@@ -118,20 +118,10 @@
} }
} }
private void OnSearchKeyDown(KeyboardEventArgs args)
{
if (args.Code == "Enter")
{
string query = HttpUtility.UrlEncode(_query);
NavigationManager.NavigateTo($"/search?query={query}", true);
StateHasChanged();
}
}
private void PerformSearch() private void PerformSearch()
{ {
string query = HttpUtility.UrlEncode(_query); string query = HttpUtility.UrlEncode(_query);
NavigationManager.NavigateTo($"/search?query={query}", true); _navigationManager.NavigateTo($"/search?query={query}", true);
StateHasChanged(); StateHasChanged();
} }
+1 -1
View File
@@ -1,7 +1,7 @@
@using static LanguageExt.Prelude @using static LanguageExt.Prelude
@using ErsatzTV.Application.MediaCards @using ErsatzTV.Application.MediaCards
@using Unit = LanguageExt.Unit @using Unit = LanguageExt.Unit
@inject IMediator Mediator @inject IMediator _mediator
<div class="@((ContainerClass ?? "media-card-container mr-6") + " pb-3")" id="@($"item_{Data.MediaItemId}")"> <div class="@((ContainerClass ?? "media-card-container mr-6") + " pb-3")" id="@($"item_{Data.MediaItemId}")">
@if (SelectClicked.HasDelegate || !string.IsNullOrWhiteSpace(Link)) @if (SelectClicked.HasDelegate || !string.IsNullOrWhiteSpace(Link))
@@ -39,8 +39,6 @@
private EditContext _editContext; private EditContext _editContext;
private ValidationMessageStore _messageStore; private ValidationMessageStore _messageStore;
private bool _isValid;
protected override async Task OnParametersSetAsync() => await LoadSecrets(_model); protected override async Task OnParametersSetAsync() => await LoadSecrets(_model);
protected override void OnInitialized() protected override void OnInitialized()
@@ -1,4 +1,4 @@
@inject IMediator Mediator @inject IMediator _mediator
<div @onkeydown="@OnKeyDown"> <div @onkeydown="@OnKeyDown">
<MudDialog> <MudDialog>