mirror of https://github.com/ErsatzTV/ErsatzTV.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
208 lines
8.3 KiB
208 lines
8.3 KiB
@page "/search" |
|
@using ErsatzTV.Application.MediaCards |
|
@using ErsatzTV.Application.MediaCollections |
|
@using ErsatzTV.Application.MediaCollections.Commands |
|
@using ErsatzTV.Application.Search.Queries |
|
@using Microsoft.AspNetCore.WebUtilities |
|
@using Microsoft.Extensions.Primitives |
|
@using Unit = LanguageExt.Unit |
|
@inherits MultiSelectBase<Search> |
|
@inject NavigationManager NavigationManager |
|
@inject ChannelWriter<IBackgroundServiceRequest> Channel |
|
|
|
<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"> |
|
@if (IsSelectMode()) |
|
{ |
|
<MudText Typo="Typo.h6" Color="Color.Primary">@SelectionLabel()</MudText> |
|
<div style="margin-left: auto"> |
|
<MudButton Variant="Variant.Filled" |
|
Color="Color.Primary" |
|
StartIcon="@Icons.Material.Filled.Add" |
|
OnClick="@(_ => AddSelectionToCollection())"> |
|
Add To Collection |
|
</MudButton> |
|
<MudButton Class="ml-3" |
|
Variant="Variant.Filled" |
|
Color="Color.Secondary" |
|
StartIcon="@Icons.Material.Filled.Check" |
|
OnClick="@(_ => ClearSelection())"> |
|
Clear Selection |
|
</MudButton> |
|
</div> |
|
} |
|
else |
|
{ |
|
<MudText>@_query</MudText> |
|
if (_movies.Count > 0) |
|
{ |
|
<MudLink Class="ml-4" Href="@(NavigationManager.Uri.Split("#").Head() + "#movies")">@_movies.Count Movies</MudLink> |
|
} |
|
else |
|
{ |
|
<MudText Class="ml-4">0 Movies</MudText> |
|
} |
|
|
|
if (_shows.Count > 0) |
|
{ |
|
<MudLink Class="ml-4" Href="@(NavigationManager.Uri.Split("#").Head() + "#shows")">@_shows.Count Shows</MudLink> |
|
} |
|
else |
|
{ |
|
<MudText Class="ml-4">0 Shows</MudText> |
|
} |
|
} |
|
</div> |
|
</MudPaper> |
|
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Style="margin-top: 96px"> |
|
@if (_movies.Count > 0) |
|
{ |
|
<div class="mb-4" style="align-items: baseline; display: flex; flex-direction: row;"> |
|
<MudText Typo="Typo.h4" |
|
Style="scroll-margin-top: 160px" |
|
UserAttributes="@(new Dictionary<string, object> { { "id", "movies" } })"> |
|
Movies |
|
</MudText> |
|
@if (_movies.Count > 50) |
|
{ |
|
<MudLink Href="@GetMoviesLink()" Class="ml-4">See All >></MudLink> |
|
} |
|
</div> |
|
|
|
<MudContainer MaxWidth="MaxWidth.False" Class="media-card-grid"> |
|
@foreach (MovieCardViewModel card in _movies.Cards.OrderBy(m => m.SortTitle)) |
|
{ |
|
<MediaCard Data="@card" |
|
Link="@($"/media/movies/{card.MovieId}")" |
|
AddToCollectionClicked="@AddToCollection" |
|
SelectClicked="@(e => SelectClicked(card, e))" |
|
IsSelected="@IsSelected(card)" |
|
IsSelectMode="@IsSelectMode()"/> |
|
} |
|
</MudContainer> |
|
} |
|
|
|
@if (_shows.Count > 0) |
|
{ |
|
<div class="mb-4" style="align-items: baseline; display: flex; flex-direction: row;"> |
|
<MudText Typo="Typo.h4" |
|
Style="scroll-margin-top: 160px" |
|
UserAttributes="@(new Dictionary<string, object> { { "id", "shows" } })"> |
|
Shows |
|
</MudText> |
|
@if (_shows.Count > 50) |
|
{ |
|
<MudLink Href="@GetShowsLink()" Class="ml-4">See All >></MudLink> |
|
} |
|
</div> |
|
|
|
<MudContainer MaxWidth="MaxWidth.False" Class="media-card-grid"> |
|
@foreach (TelevisionShowCardViewModel card in _shows.Cards.OrderBy(s => s.SortTitle)) |
|
{ |
|
<MediaCard Data="@card" |
|
Link="@($"/media/tv/shows/{card.TelevisionShowId}")" |
|
AddToCollectionClicked="@AddToCollection" |
|
SelectClicked="@(e => SelectClicked(card, e))" |
|
IsSelected="@IsSelected(card)" |
|
IsSelectMode="@IsSelectMode()"/> |
|
} |
|
</MudContainer> |
|
} |
|
</MudContainer> |
|
|
|
@code { |
|
private string _query; |
|
private MovieCardResultsViewModel _movies; |
|
private TelevisionShowCardResultsViewModel _shows; |
|
|
|
protected override async Task OnInitializedAsync() |
|
{ |
|
string query = new Uri(NavigationManager.Uri).Query; |
|
|
|
if (QueryHelpers.ParseQuery(query).TryGetValue("query", out StringValues value)) |
|
{ |
|
_query = value; |
|
|
|
_movies = await Mediator.Send(new QuerySearchIndexMovies($"type:movie AND ({_query})", 1, 50)); |
|
_shows = await Mediator.Send(new QuerySearchIndexShows($"type:show AND ({_query})", 1, 50)); |
|
} |
|
} |
|
|
|
private void SelectClicked(MediaCardViewModel card, MouseEventArgs e) |
|
{ |
|
List<MediaCardViewModel> GetSortedItems() |
|
{ |
|
return _movies.Cards.OrderBy(m => m.SortTitle) |
|
.Append<MediaCardViewModel>(_shows.Cards.OrderBy(s => s.SortTitle)) |
|
.ToList(); |
|
} |
|
|
|
SelectClicked(GetSortedItems, card, e); |
|
} |
|
|
|
private async Task AddToCollection(MediaCardViewModel card) |
|
{ |
|
if (card is MovieCardViewModel movie) |
|
{ |
|
var parameters = new DialogParameters { { "EntityType", "movie" }, { "EntityName", movie.Title } }; |
|
var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall }; |
|
|
|
IDialogReference dialog = Dialog.Show<AddToCollectionDialog>("Add To Collection", parameters, options); |
|
DialogResult result = await dialog.Result; |
|
if (!result.Cancelled && result.Data is MediaCollectionViewModel collection) |
|
{ |
|
var request = new AddMovieToCollection(collection.Id, movie.MovieId); |
|
Either<BaseError, Unit> addResult = await Mediator.Send(request); |
|
addResult.Match( |
|
Left: error => |
|
{ |
|
Snackbar.Add($"Unexpected error adding movie to collection: {error.Value}"); |
|
Logger.LogError("Unexpected error adding movie to collection: {Error}", error.Value); |
|
}, |
|
Right: _ => Snackbar.Add($"Added {movie.Title} to collection {collection.Name}", Severity.Success)); |
|
} |
|
} |
|
|
|
if (card is TelevisionShowCardViewModel show) |
|
{ |
|
var parameters = new DialogParameters { { "EntityType", "show" }, { "EntityName", show.Title } }; |
|
var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall }; |
|
|
|
IDialogReference dialog = Dialog.Show<AddToCollectionDialog>("Add To Collection", parameters, options); |
|
DialogResult result = await dialog.Result; |
|
if (!result.Cancelled && result.Data is MediaCollectionViewModel collection) |
|
{ |
|
var request = new AddShowToCollection(collection.Id, show.TelevisionShowId); |
|
Either<BaseError, Unit> addResult = await Mediator.Send(request); |
|
addResult.Match( |
|
Left: error => |
|
{ |
|
Snackbar.Add($"Unexpected error adding show to collection: {error.Value}"); |
|
Logger.LogError("Unexpected error adding show to collection: {Error}", error.Value); |
|
}, |
|
Right: _ => Snackbar.Add($"Added {show.Title} to collection {collection.Name}", Severity.Success)); |
|
} |
|
} |
|
} |
|
|
|
private string GetMoviesLink() |
|
{ |
|
var uri = "/media/movies/page/1"; |
|
if (!string.IsNullOrWhiteSpace(_query)) |
|
{ |
|
uri = QueryHelpers.AddQueryString(uri, "query", _query); |
|
} |
|
return uri; |
|
} |
|
|
|
private string GetShowsLink() |
|
{ |
|
var uri = "/media/tv/shows/page/1"; |
|
if (!string.IsNullOrWhiteSpace(_query)) |
|
{ |
|
uri = QueryHelpers.AddQueryString(uri, "query", _query); |
|
} |
|
return uri; |
|
} |
|
|
|
} |