diff --git a/ErsatzTV/Pages/Search.razor b/ErsatzTV/Pages/Search.razor index e14a65b79..22931bedd 100644 --- a/ErsatzTV/Pages/Search.razor +++ b/ErsatzTV/Pages/Search.razor @@ -27,7 +27,10 @@ { + AddToCollectionClicked="@AddToCollection" + SelectClicked="@(e => SelectClicked(card, e))" + IsSelected="@_selectedCards.Contains(card)" + IsSelectMode="@_selectedCards.Any()"/> } } @@ -50,6 +53,8 @@ @code { private string _query; private SearchCardResultsViewModel _data; + private System.Collections.Generic.HashSet _selectedCards; + private MediaCardViewModel _selectedLast; protected override async Task OnInitializedAsync() { @@ -61,6 +66,39 @@ Either maybeResults = await Mediator.Send(new GetSearchCards(_query)); maybeResults.IfRight(results => _data = results); } + + _selectedCards = new System.Collections.Generic.HashSet(); + } + + private async Task SelectClicked(MovieCardViewModel movie, MouseEventArgs e) + { + if (_selectedCards.Contains(movie)) + { + _selectedCards.Remove(movie); + } + else + { + if (e.ShiftKey && _selectedLast is MovieCardViewModel selectedMovie) + { + var sorted = _data.MovieCards.OrderBy(m => m.SortTitle).ToList(); + int start = sorted.IndexOf(selectedMovie); + int finish = sorted.IndexOf(movie); + if (start > finish) + { + int temp = start; + start = finish; + finish = temp; + } + + for (int i = start; i < finish; i++) + { + _selectedCards.Add(sorted[i]); + } + } + + _selectedLast = movie; + _selectedCards.Add(movie); + } } private async Task AddToCollection(MediaCardViewModel card) diff --git a/ErsatzTV/Shared/MainLayout.razor b/ErsatzTV/Shared/MainLayout.razor index df9d734ed..3aac076fc 100644 --- a/ErsatzTV/Shared/MainLayout.razor +++ b/ErsatzTV/Shared/MainLayout.razor @@ -15,7 +15,7 @@ @if (!string.IsNullOrWhiteSpace(Link)) { -
+
@if (string.IsNullOrWhiteSpace(Data.Poster)) { @@ -14,17 +14,34 @@ } + @if (IsSelected) + { +
+ +
+ }
- + - @if (AddToCollectionClicked.HasDelegate) + @if (SelectClicked.HasDelegate) + { + + } + @if (AddToCollectionClicked.HasDelegate && !IsSelectMode) { } - @if (DeleteClicked.HasDelegate) + @if (DeleteClicked.HasDelegate && !IsSelectMode) { AddToCollectionClicked { get; set; } + [Parameter] + public EventCallback SelectClicked { get; set; } + + [Parameter] + public bool IsSelectMode { get; set; } + + [Parameter] + public bool IsSelected { get; set; } + private string GetPlaceholder(string sortTitle) { if (Placeholder != null) diff --git a/ErsatzTV/wwwroot/css/site.css b/ErsatzTV/wwwroot/css/site.css index 8a0726b75..64e0a4d4b 100644 --- a/ErsatzTV/wwwroot/css/site.css +++ b/ErsatzTV/wwwroot/css/site.css @@ -18,6 +18,10 @@ width: 152px; } +.media-card-selected { + box-shadow: 0 0 0 3px #00c000, 0 0 4px rgba(0, 0, 0, 0.3); +} + .media-card-episode { width: 392px; } .media-card:hover { /*filter: brightness(75%);*/ }