Merge pull request #1169 from Mbucari/master

12.0.1 Bug Fixes
This commit is contained in:
rmcrackan 2025-03-02 20:33:59 -05:00 committed by GitHub
commit b2af93bed9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 35 additions and 10 deletions

View File

@ -41,7 +41,7 @@ namespace LibationAvalonia.ViewModels
{ {
await Task.WhenAll( await Task.WhenAll(
SetBackupCountsAsync(fullLibrary), SetBackupCountsAsync(fullLibrary),
ProductsDisplay.UpdateGridAsync(fullLibrary)); Task.Run(() => ProductsDisplay.UpdateGridAsync(fullLibrary)));
} }
private static string menufyText(string header) => Configuration.IsMacOs ? header : $"_{header}"; private static string menufyText(string header) => Configuration.IsMacOs ? header : $"_{header}";

View File

@ -11,6 +11,7 @@ using ReactiveUI;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -102,16 +103,17 @@ namespace LibationAvalonia.ViewModels
internal async Task BindToGridAsync(List<LibraryBook> dbBooks) internal async Task BindToGridAsync(List<LibraryBook> dbBooks)
{ {
GridEntries = new(SOURCE) { Filter = CollectionFilter }; var sc = await Dispatcher.UIThread.InvokeAsync(() => AvaloniaSynchronizationContext.Current);
AvaloniaSynchronizationContext.SetSynchronizationContext(sc);
var geList = await LibraryBookEntry<AvaloniaEntryStatus>.GetAllProductsAsync(dbBooks); var geList = await LibraryBookEntry<AvaloniaEntryStatus>.GetAllProductsAsync(dbBooks);
var seriesEntries = await SeriesEntry<AvaloniaEntryStatus>.GetAllSeriesEntriesAsync(dbBooks); var seriesEntries = await SeriesEntry<AvaloniaEntryStatus>.GetAllSeriesEntriesAsync(dbBooks);
//Create the filtered-in list before adding entries to avoid a refresh //Create the filtered-in list before adding entries to avoid a refresh
FilteredInGridEntries = geList.Union(seriesEntries.SelectMany(s => s.Children)).FilterEntries(FilterString); FilteredInGridEntries = geList.Union(seriesEntries.SelectMany(s => s.Children)).FilterEntries(FilterString);
//Adding entries to the Source list will invoke CollectionFilter //Adding entries to the Source list will invoke CollectionFilter
SOURCE.AddRange(geList.Concat(seriesEntries).OrderDescending(new RowComparer(null))); //Perform on UI thread for safety
await Dispatcher.UIThread.InvokeAsync(() => SOURCE.AddRange(geList.Concat(seriesEntries).OrderDescending(new RowComparer(null))));
//Add all children beneath their parent //Add all children beneath their parent
foreach (var series in seriesEntries) foreach (var series in seriesEntries)
@ -121,6 +123,10 @@ namespace LibationAvalonia.ViewModels
SOURCE.Insert(++seriesIndex, child); SOURCE.Insert(++seriesIndex, child);
} }
// Adding SOURCE to the DataGridViewCollection after building the source
//Saves ~500 ms on a library of ~4500 books.
//Perform on UI thread for safety
await Dispatcher.UIThread.InvokeAsync(() => GridEntries = new(SOURCE) { Filter = CollectionFilter });
GridEntries.CollectionChanged += GridEntries_CollectionChanged; GridEntries.CollectionChanged += GridEntries_CollectionChanged;
GridEntries_CollectionChanged(); GridEntries_CollectionChanged();
} }

View File

@ -63,12 +63,14 @@ namespace LibationAvalonia.Views
public async Task OnLibraryLoadedAsync(List<LibraryBook> initialLibrary) public async Task OnLibraryLoadedAsync(List<LibraryBook> initialLibrary)
{ {
//Get the ViewModel before crossing the await boundary
var vm = ViewModel;
if (QuickFilters.UseDefault) if (QuickFilters.UseDefault)
await ViewModel.PerformFilter(QuickFilters.Filters.FirstOrDefault()); await vm.PerformFilter(QuickFilters.Filters.FirstOrDefault());
await Task.WhenAll( await Task.WhenAll(
ViewModel.SetBackupCountsAsync(initialLibrary), vm.SetBackupCountsAsync(initialLibrary),
ViewModel.ProductsDisplay.BindToGridAsync(initialLibrary)); Task.Run(() => vm.ProductsDisplay.BindToGridAsync(initialLibrary)));
} }
public void ProductsDisplay_LiberateClicked(object _, LibraryBook libraryBook) => ViewModel.LiberateClicked(libraryBook); public void ProductsDisplay_LiberateClicked(object _, LibraryBook libraryBook) => ViewModel.LiberateClicked(libraryBook);

View File

@ -55,8 +55,9 @@ namespace LibationFileManager
{ {
if (!File.Exists(matchingFiles[i].Path)) if (!File.Exists(matchingFiles[i].Path))
{ {
var entryToRemove = matchingFiles[i];
matchingFiles.RemoveAt(i); matchingFiles.RemoveAt(i);
cacheChanged |= Remove(matchingFiles[i]); cacheChanged |= Remove(entryToRemove);
} }
} }
if (cacheChanged) if (cacheChanged)
@ -79,8 +80,9 @@ namespace LibationFileManager
return matchingFiles[i].Path; return matchingFiles[i].Path;
else else
{ {
var entryToRemove = matchingFiles[i];
matchingFiles.RemoveAt(i); matchingFiles.RemoveAt(i);
cacheChanged |= Remove(matchingFiles[i]); cacheChanged |= Remove(entryToRemove);
} }
} }
return null; return null;
@ -141,6 +143,7 @@ namespace LibationFileManager
{ {
[JsonProperty] [JsonProperty]
private readonly ConcurrentDictionary<string, List<TEntry>> Dictionary = new(); private readonly ConcurrentDictionary<string, List<TEntry>> Dictionary = new();
private static object lockObject = new();
public List<TEntry> GetIdEntries(string id) public List<TEntry> GetIdEntries(string id)
{ {
@ -164,7 +167,21 @@ namespace LibationFileManager
} }
public bool Remove(string id, TEntry entry) public bool Remove(string id, TEntry entry)
=> Dictionary.TryGetValue(id, out List<TEntry>? entries) && entries.Remove(entry); {
lock (lockObject)
{
if (Dictionary.TryGetValue(id, out List<TEntry>? entries))
{
var removed = entries?.Remove(entry) ?? false;
if (removed && entries?.Count == 0)
{
Dictionary.Remove(id, out _);
}
return removed;
}
else return false;
}
}
} }
} }
} }