Browse Source

add all search results to collection (#150)

pull/151/head
Jason Dove 5 years ago committed by GitHub
parent
commit
436c9119fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 7
      ErsatzTV.Application/Search/Queries/QuerySearchIndex.cs
  2. 6
      ErsatzTV.Application/Search/Queries/QuerySearchIndexAllItems.cs
  3. 32
      ErsatzTV.Application/Search/Queries/QuerySearchIndexAllItemsHandler.cs
  4. 18
      ErsatzTV.Application/Search/Queries/QuerySearchIndexHandler.cs
  5. 6
      ErsatzTV.Application/Search/SearchResultAllItemsViewModel.cs
  6. 14
      ErsatzTV.Infrastructure/Search/SearchIndex.cs
  7. 23
      ErsatzTV/Pages/MultiSelectBase.cs
  8. 29
      ErsatzTV/Pages/Search.razor
  9. 2
      ErsatzTV/Shared/AddToCollectionDialog.razor

7
ErsatzTV.Application/Search/Queries/QuerySearchIndex.cs

@ -1,7 +0,0 @@ @@ -1,7 +0,0 @@
using ErsatzTV.Core.Search;
using MediatR;
namespace ErsatzTV.Application.Search.Queries
{
public record QuerySearchIndex(string Query) : IRequest<SearchResult>;
}

6
ErsatzTV.Application/Search/Queries/QuerySearchIndexAllItems.cs

@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
using MediatR;
namespace ErsatzTV.Application.Search.Queries
{
public record QuerySearchIndexAllItems(string Query) : IRequest<SearchResultAllItemsViewModel>;
}

32
ErsatzTV.Application/Search/Queries/QuerySearchIndexAllItemsHandler.cs

@ -0,0 +1,32 @@ @@ -0,0 +1,32 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using ErsatzTV.Core.Interfaces.Search;
using LanguageExt;
using MediatR;
namespace ErsatzTV.Application.Search.Queries
{
public class
QuerySearchIndexAllItemsHandler : IRequestHandler<QuerySearchIndexAllItems, SearchResultAllItemsViewModel>
{
private readonly ISearchIndex _searchIndex;
public QuerySearchIndexAllItemsHandler(ISearchIndex searchIndex) => _searchIndex = searchIndex;
public async Task<SearchResultAllItemsViewModel> Handle(
QuerySearchIndexAllItems request,
CancellationToken cancellationToken)
{
List<int> movieIds = await _searchIndex.Search($"type:movie AND ({request.Query})", 0, 0)
.Map(result => result.Items.Map(i => i.Id).ToList());
List<int> showIds = await _searchIndex.Search($"type:show AND ({request.Query})", 0, 0)
.Map(result => result.Items.Map(i => i.Id).ToList());
List<int> musicVideoIds = await _searchIndex.Search($"type:music_video AND ({request.Query})", 0, 0)
.Map(result => result.Items.Map(i => i.Id).ToList());
return new SearchResultAllItemsViewModel(movieIds, showIds, musicVideoIds);
}
}
}

18
ErsatzTV.Application/Search/Queries/QuerySearchIndexHandler.cs

@ -1,18 +0,0 @@ @@ -1,18 +0,0 @@
using System.Threading;
using System.Threading.Tasks;
using ErsatzTV.Core.Interfaces.Search;
using ErsatzTV.Core.Search;
using MediatR;
namespace ErsatzTV.Application.Search.Queries
{
public class QuerySearchIndexHandler : IRequestHandler<QuerySearchIndex, SearchResult>
{
private readonly ISearchIndex _searchIndex;
public QuerySearchIndexHandler(ISearchIndex searchIndex) => _searchIndex = searchIndex;
public Task<SearchResult> Handle(QuerySearchIndex request, CancellationToken cancellationToken) =>
_searchIndex.Search(request.Query, 0, 100);
}
}

6
ErsatzTV.Application/Search/SearchResultAllItemsViewModel.cs

@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
using System.Collections.Generic;
namespace ErsatzTV.Application.Search
{
public record SearchResultAllItemsViewModel(List<int> MovieIds, List<int> ShowIds, List<int> MusicVideoIds);
}

14
ErsatzTV.Infrastructure/Search/SearchIndex.cs

@ -138,7 +138,7 @@ namespace ErsatzTV.Infrastructure.Search @@ -138,7 +138,7 @@ namespace ErsatzTV.Infrastructure.Search
using DirectoryReader reader = _writer.GetReader(true);
var searcher = new IndexSearcher(reader);
int hitsLimit = skip + limit;
int hitsLimit = limit == 0 ? searcher.IndexReader.MaxDoc : skip + limit;
using var analyzer = new StandardAnalyzer(AppLuceneVersion);
QueryParser parser = !string.IsNullOrWhiteSpace(searchField)
? new QueryParser(AppLuceneVersion, searchField, analyzer)
@ -148,13 +148,21 @@ namespace ErsatzTV.Infrastructure.Search @@ -148,13 +148,21 @@ namespace ErsatzTV.Infrastructure.Search
var filter = new DuplicateFilter(TitleAndYearField);
var sort = new Sort(new SortField(SortTitleField, SortFieldType.STRING));
TopFieldDocs topDocs = searcher.Search(query, filter, hitsLimit, sort, true, true);
IEnumerable<ScoreDoc> selectedHits = topDocs.ScoreDocs.Skip(skip).Take(limit);
IEnumerable<ScoreDoc> selectedHits = topDocs.ScoreDocs.Skip(skip);
if (limit > 0)
{
selectedHits = selectedHits.Take(limit);
}
var searchResult = new SearchResult(
selectedHits.Map(d => ProjectToSearchItem(searcher.Doc(d.Doc))).ToList(),
topDocs.TotalHits);
searchResult.PageMap = GetSearchPageMap(searcher, query, filter, sort, limit);
if (limit > 0)
{
searchResult.PageMap = GetSearchPageMap(searcher, query, filter, sort, limit);
}
return searchResult.AsTask();
}

23
ErsatzTV/Pages/MultiSelectBase.cs

@ -94,21 +94,28 @@ namespace ErsatzTV.Pages @@ -94,21 +94,28 @@ namespace ErsatzTV.Pages
}
}
protected async Task AddSelectionToCollection()
protected Task AddSelectionToCollection() => AddItemsToCollection(
_selectedItems.OfType<MovieCardViewModel>().Map(m => m.MovieId).ToList(),
_selectedItems.OfType<TelevisionShowCardViewModel>().Map(s => s.TelevisionShowId).ToList(),
_selectedItems.OfType<MusicVideoCardViewModel>().Map(mv => mv.MusicVideoId).ToList());
protected async Task AddItemsToCollection(
List<int> movieIds,
List<int> showIds,
List<int> musicVideoIds,
string entityName = "selected items")
{
int count = movieIds.Count + showIds.Count + musicVideoIds.Count;
var parameters = new DialogParameters
{ { "EntityType", _selectedItems.Count.ToString() }, { "EntityName", "selected items" } };
{ { "EntityType", count.ToString() }, { "EntityName", entityName } };
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 AddItemsToCollection(
collection.Id,
_selectedItems.OfType<MovieCardViewModel>().Map(m => m.MovieId).ToList(),
_selectedItems.OfType<TelevisionShowCardViewModel>().Map(s => s.TelevisionShowId).ToList(),
_selectedItems.OfType<MusicVideoCardViewModel>().Map(mv => mv.MusicVideoId).ToList());
var request = new AddItemsToCollection(collection.Id, movieIds, showIds, musicVideoIds);
Either<BaseError, Unit> addResult = await Mediator.Send(request);
addResult.Match(
@ -120,7 +127,7 @@ namespace ErsatzTV.Pages @@ -120,7 +127,7 @@ namespace ErsatzTV.Pages
Right: _ =>
{
Snackbar.Add(
$"Added {_selectedItems.Count} items to collection {collection.Name}",
$"Added {count} items to collection {collection.Name}",
Severity.Success);
ClearSelection();
});

29
ErsatzTV/Pages/Search.razor

@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
@using ErsatzTV.Application.MediaCards
@using ErsatzTV.Application.MediaCollections
@using ErsatzTV.Application.MediaCollections.Commands
@using ErsatzTV.Application.Search
@using ErsatzTV.Application.Search.Queries
@using Microsoft.AspNetCore.WebUtilities
@using Microsoft.Extensions.Primitives
@ -33,33 +34,41 @@ @@ -33,33 +34,41 @@
}
else
{
<MudText>@_query</MudText>
<MudText Style="margin-bottom: auto; margin-top: auto">@_query</MudText>
if (_movies.Count > 0)
{
<MudLink Class="ml-4" Href="@(NavigationManager.Uri.Split("#").Head() + "#movies")">@_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>
}
else
{
<MudText Class="ml-4">0 Movies</MudText>
<MudText Class="ml-4" Style="margin-bottom: auto; margin-top: auto">0 Movies</MudText>
}
if (_shows.Count > 0)
{
<MudLink Class="ml-4" Href="@(NavigationManager.Uri.Split("#").Head() + "#shows")">@_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>
}
else
{
<MudText Class="ml-4">0 Shows</MudText>
<MudText Class="ml-4" Style="margin-bottom: auto; margin-top: auto">0 Shows</MudText>
}
if (_musicVideos.Count > 0)
{
<MudLink Class="ml-4" Href="@(NavigationManager.Uri.Split("#").Head() + "#music_videos")">@_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>
}
else
{
<MudText Class="ml-4">0 Music Videos</MudText>
<MudText Class="ml-4" Style="margin-bottom: auto; margin-top: auto">0 Music Videos</MudText>
}
<div style="margin-left: auto">
<MudButton Variant="Variant.Filled"
Color="Color.Primary"
StartIcon="@Icons.Material.Filled.Add"
OnClick="@AddAllToCollection">
Add All To Collection
</MudButton>
</div>
}
</div>
</MudPaper>
@ -276,4 +285,10 @@ @@ -276,4 +285,10 @@
return uri;
}
private async Task AddAllToCollection(MouseEventArgs _)
{
SearchResultAllItemsViewModel results = await Mediator.Send(new QuerySearchIndexAllItems(_query));
await AddItemsToCollection(results.MovieIds, results.ShowIds, results.MusicVideoIds, "search results");
}
}

2
ErsatzTV/Shared/AddToCollectionDialog.razor

@ -70,7 +70,7 @@ @@ -70,7 +70,7 @@
if (MemoryCache.TryGetValue("AddToCollectionDialog.SelectedCollectionId", out int id))
{
_selectedCollection = _collections.SingleOrDefault(c => c.Id == id);
_selectedCollection = _collections.SingleOrDefault(c => c.Id == id) ?? _newCollection;
}
else
{

Loading…
Cancel
Save