WinForms and Avalonia now share all GridEntry view models
This commit is contained in:
parent
e1cd8b8f94
commit
fb9d062545
41 changed files with 1032 additions and 1704 deletions
|
|
@ -1,15 +1,16 @@
|
|||
using ApplicationServices;
|
||||
using AudibleUtilities;
|
||||
using Avalonia.Collections;
|
||||
using Avalonia.Threading;
|
||||
using DataLayer;
|
||||
using LibationAvalonia.Dialogs.Login;
|
||||
using LibationUiBase.GridView;
|
||||
using ReactiveUI;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using ReactiveUI;
|
||||
using Avalonia.Threading;
|
||||
using ApplicationServices;
|
||||
using AudibleUtilities;
|
||||
using LibationAvalonia.Dialogs.Login;
|
||||
using Avalonia.Collections;
|
||||
|
||||
namespace LibationAvalonia.ViewModels
|
||||
{
|
||||
|
|
@ -20,9 +21,9 @@ namespace LibationAvalonia.ViewModels
|
|||
public event EventHandler<int> RemovableCountChanged;
|
||||
|
||||
/// <summary>Backing list of all grid entries</summary>
|
||||
private readonly AvaloniaList<GridEntry> SOURCE = new();
|
||||
private readonly AvaloniaList<IGridEntry> SOURCE = new();
|
||||
/// <summary>Grid entries included in the filter set. If null, all grid entries are shown</summary>
|
||||
private List<GridEntry> FilteredInGridEntries;
|
||||
private List<IGridEntry> FilteredInGridEntries;
|
||||
public string FilterString { get; private set; }
|
||||
public DataGridCollectionView GridEntries { get; private set; }
|
||||
|
||||
|
|
@ -31,11 +32,11 @@ namespace LibationAvalonia.ViewModels
|
|||
|
||||
public List<LibraryBook> GetVisibleBookEntries()
|
||||
=> GridEntries
|
||||
.OfType<LibraryBookEntry>()
|
||||
.OfType<ILibraryBookEntry>()
|
||||
.Select(lbe => lbe.LibraryBook)
|
||||
.ToList();
|
||||
|
||||
private IEnumerable<LibraryBookEntry> GetAllBookEntries()
|
||||
private IEnumerable<ILibraryBookEntry> GetAllBookEntries()
|
||||
=> SOURCE
|
||||
.BookEntries();
|
||||
|
||||
|
|
@ -92,11 +93,10 @@ namespace LibationAvalonia.ViewModels
|
|||
|
||||
var geList = dbBooks
|
||||
.Where(lb => lb.Book.IsProduct())
|
||||
.Select(b => new LibraryBookEntry(b))
|
||||
.Cast<GridEntry>()
|
||||
.ToList();
|
||||
.Select(b => new LibraryBookEntry<AvaloniaEntryStatus>(b))
|
||||
.ToList<IGridEntry>();
|
||||
|
||||
var episodes = dbBooks.Where(lb => lb.Book.IsEpisodeChild());
|
||||
var episodes = dbBooks.Where(lb => lb.Book.IsEpisodeChild()).ToList();
|
||||
|
||||
var seriesBooks = dbBooks.Where(lb => lb.Book.IsEpisodeParent()).ToList();
|
||||
|
||||
|
|
@ -106,7 +106,7 @@ namespace LibationAvalonia.ViewModels
|
|||
|
||||
if (!seriesEpisodes.Any()) continue;
|
||||
|
||||
var seriesEntry = new SeriesEntry(parent, seriesEpisodes);
|
||||
var seriesEntry = new SeriesEntry<AvaloniaEntryStatus>(parent, seriesEpisodes);
|
||||
seriesEntry.Liberate.Expanded = false;
|
||||
|
||||
geList.Add(seriesEntry);
|
||||
|
|
@ -116,9 +116,10 @@ namespace LibationAvalonia.ViewModels
|
|||
//Create the filtered-in list before adding entries to avoid a refresh
|
||||
FilteredInGridEntries = QueryResults(geList, FilterString);
|
||||
SOURCE.AddRange(geList.OrderByDescending(e => e.DateAdded));
|
||||
VisibleCountChanged?.Invoke(this, GridEntries.OfType<LibraryBookEntry>().Count());
|
||||
GridEntries.CollectionChanged += (_, _)
|
||||
=> VisibleCountChanged?.Invoke(this, GridEntries.OfType<LibraryBookEntry>().Count());
|
||||
=> VisibleCountChanged?.Invoke(this, GridEntries.OfType<ILibraryBookEntry>().Count());
|
||||
|
||||
VisibleCountChanged?.Invoke(this, GridEntries.OfType<ILibraryBookEntry>().Count());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -129,7 +130,7 @@ namespace LibationAvalonia.ViewModels
|
|||
#region Add new or update existing grid entries
|
||||
|
||||
//Add absent entries to grid, or update existing entry
|
||||
var allEntries = SOURCE.BookEntries();
|
||||
var allEntries = SOURCE.BookEntries().ToList();
|
||||
var seriesEntries = SOURCE.SeriesEntries().ToList();
|
||||
var parentedEpisodes = dbBooks.ParentedEpisodes().ToList();
|
||||
|
||||
|
|
@ -163,7 +164,7 @@ namespace LibationAvalonia.ViewModels
|
|||
.ExceptBy(dbBooks.Select(lb => lb.Book.AudibleProductId), ge => ge.AudibleProductId);
|
||||
|
||||
//Remove books in series from their parents' Children list
|
||||
foreach (var removed in removedBooks.Where(b => b.Parent is not null))
|
||||
foreach (var removed in removedBooks.Where(b => b.Liberate.IsEpisode))
|
||||
removed.Parent.RemoveChild(removed);
|
||||
|
||||
//Remove series that have no children
|
||||
|
|
@ -174,11 +175,12 @@ namespace LibationAvalonia.ViewModels
|
|||
#endregion
|
||||
|
||||
await Filter(FilterString);
|
||||
GC.Collect(GC.MaxGeneration, GCCollectionMode.Aggressive, true, true);
|
||||
}
|
||||
|
||||
private void RemoveBooks(IEnumerable<LibraryBookEntry> removedBooks, IEnumerable<SeriesEntry> removedSeries)
|
||||
private void RemoveBooks(IEnumerable<ILibraryBookEntry> removedBooks, IEnumerable<ISeriesEntry> removedSeries)
|
||||
{
|
||||
foreach (var removed in removedBooks.Cast<GridEntry>().Concat(removedSeries).Where(b => b is not null).ToList())
|
||||
foreach (var removed in removedBooks.Cast<IGridEntry>().Concat(removedSeries).Where(b => b is not null).ToList())
|
||||
{
|
||||
if (GridEntries.PassesFilter(removed))
|
||||
GridEntries.Remove(removed);
|
||||
|
|
@ -191,21 +193,21 @@ namespace LibationAvalonia.ViewModels
|
|||
}
|
||||
}
|
||||
|
||||
private void UpsertBook(LibraryBook book, LibraryBookEntry existingBookEntry)
|
||||
private void UpsertBook(LibraryBook book, ILibraryBookEntry existingBookEntry)
|
||||
{
|
||||
if (existingBookEntry is null)
|
||||
// Add the new product to top
|
||||
SOURCE.Insert(0, new LibraryBookEntry(book));
|
||||
SOURCE.Insert(0, new LibraryBookEntry<AvaloniaEntryStatus>(book));
|
||||
else
|
||||
// update existing
|
||||
existingBookEntry.UpdateLibraryBook(book);
|
||||
}
|
||||
|
||||
private void UpsertEpisode(LibraryBook episodeBook, LibraryBookEntry existingEpisodeEntry, List<SeriesEntry> seriesEntries, IEnumerable<LibraryBook> dbBooks)
|
||||
private void UpsertEpisode(LibraryBook episodeBook, ILibraryBookEntry existingEpisodeEntry, List<ISeriesEntry> seriesEntries, IEnumerable<LibraryBook> dbBooks)
|
||||
{
|
||||
if (existingEpisodeEntry is null)
|
||||
{
|
||||
LibraryBookEntry episodeEntry;
|
||||
ILibraryBookEntry episodeEntry;
|
||||
|
||||
var seriesEntry = seriesEntries.FindSeriesParent(episodeBook);
|
||||
|
||||
|
|
@ -223,7 +225,7 @@ namespace LibationAvalonia.ViewModels
|
|||
return;
|
||||
}
|
||||
|
||||
seriesEntry = new SeriesEntry(seriesBook, new[] { episodeBook });
|
||||
seriesEntry = new SeriesEntry<AvaloniaEntryStatus>(seriesBook, episodeBook);
|
||||
seriesEntries.Add(seriesEntry);
|
||||
|
||||
episodeEntry = seriesEntry.Children[0];
|
||||
|
|
@ -233,7 +235,7 @@ namespace LibationAvalonia.ViewModels
|
|||
else
|
||||
{
|
||||
//Series exists. Create and add episode child then update the SeriesEntry
|
||||
episodeEntry = new(episodeBook) { Parent = seriesEntry };
|
||||
episodeEntry = new LibraryBookEntry<AvaloniaEntryStatus>(episodeBook, seriesEntry);
|
||||
seriesEntry.Children.Add(episodeEntry);
|
||||
var seriesBook = dbBooks.Single(lb => lb.Book.AudibleProductId == seriesEntry.LibraryBook.Book.AudibleProductId);
|
||||
seriesEntry.UpdateLibraryBook(seriesBook);
|
||||
|
|
@ -255,7 +257,7 @@ namespace LibationAvalonia.ViewModels
|
|||
await Dispatcher.UIThread.InvokeAsync(GridEntries.Refresh);
|
||||
}
|
||||
|
||||
public async Task ToggleSeriesExpanded(SeriesEntry seriesEntry)
|
||||
public async Task ToggleSeriesExpanded(ISeriesEntry seriesEntry)
|
||||
{
|
||||
seriesEntry.Liberate.Expanded = !seriesEntry.Liberate.Expanded;
|
||||
|
||||
|
|
@ -280,8 +282,8 @@ namespace LibationAvalonia.ViewModels
|
|||
|
||||
private bool CollectionFilter(object item)
|
||||
{
|
||||
if (item is LibraryBookEntry lbe
|
||||
&& lbe.IsEpisode
|
||||
if (item is ILibraryBookEntry lbe
|
||||
&& lbe.Liberate.IsEpisode
|
||||
&& lbe.Parent?.Liberate?.Expanded != true)
|
||||
return false;
|
||||
|
||||
|
|
@ -290,13 +292,13 @@ namespace LibationAvalonia.ViewModels
|
|||
return FilteredInGridEntries.Contains(item);
|
||||
}
|
||||
|
||||
private static List<GridEntry> QueryResults(IEnumerable<GridEntry> entries, string searchString)
|
||||
private static List<IGridEntry> QueryResults(IEnumerable<IGridEntry> entries, string searchString)
|
||||
{
|
||||
if (string.IsNullOrEmpty(searchString)) return null;
|
||||
|
||||
var searchResultSet = SearchEngineCommands.Search(searchString);
|
||||
|
||||
var booksFilteredIn = entries.BookEntries().Join(searchResultSet.Docs, lbe => lbe.AudibleProductId, d => d.ProductId, (lbe, d) => (GridEntry)lbe);
|
||||
var booksFilteredIn = entries.BookEntries().Join(searchResultSet.Docs, lbe => lbe.AudibleProductId, d => d.ProductId, (lbe, d) => (IGridEntry)lbe);
|
||||
|
||||
//Find all series containing children that match the search criteria
|
||||
var seriesFilteredIn = entries.SeriesEntries().Where(s => s.Children.Join(searchResultSet.Docs, lbe => lbe.AudibleProductId, d => d.ProductId, (lbe, d) => lbe).Any());
|
||||
|
|
@ -411,7 +413,7 @@ namespace LibationAvalonia.ViewModels
|
|||
|
||||
private void GridEntry_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == nameof(GridEntry.Remove) && sender is LibraryBookEntry lbEntry)
|
||||
if (e.PropertyName == nameof(IGridEntry.Remove) && sender is ILibraryBookEntry)
|
||||
{
|
||||
int removeCount = GetAllBookEntries().Count(lbe => lbe.Remove is true);
|
||||
RemovableCountChanged?.Invoke(this, removeCount);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue