batch book status updates

bug fixes, esp. threading
This commit is contained in:
Robert McRackan 2021-09-23 14:33:04 -04:00
parent 613c97524a
commit 14e14ba9bd
7 changed files with 64 additions and 19 deletions

View File

@ -3,7 +3,7 @@
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<Version>6.0.5.1</Version>
<Version>6.0.6.1</Version>
</PropertyGroup>
<ItemGroup>

View File

@ -106,6 +106,11 @@ namespace DataLayer
#endregion
#region LiberatedStatuses
/// <summary>
/// Occurs when <see cref="Tags"/>, <see cref="BookStatus"/>, or <see cref="PdfStatus"/> values change.
/// This signals the change of the in-memory value; it does not ensure that the new value has been persisted.
/// </summary>
public static event EventHandler<string> ItemChanged;
private LiberatedStatus _bookStatus;
private LiberatedStatus? _pdfStatus;
@ -132,13 +137,41 @@ namespace DataLayer
ItemChanged?.Invoke(this, nameof(PdfStatus));
}
}
}
#endregion
#region batch changes
public static event EventHandler<string> Batch_ItemChanged;
public void BatchMode_UpdateBookStatus(LiberatedStatus value)
{
if (_bookStatus != value)
{
_bookStatus = value;
batchFlag = true;
}
}
// don't overwrite current with null. Therefore input is "LiberatedStatus" not "LiberatedStatus?"
public void BatchMode_UpdatePdfStatus(LiberatedStatus value)
{
if (_pdfStatus != value)
{
_pdfStatus = value;
batchFlag = true;
}
}
private static bool batchFlag = false;
public static void BatchMode_Finalize()
{
if (batchFlag)
Batch_ItemChanged?.Invoke(null, null);
batchFlag = false;
}
#endregion
/// <summary>
/// Occurs when <see cref="Tags"/>, <see cref="BookStatus"/>, or <see cref="PdfStatus"/> values change.
/// This signals the change of the in-memory value; it does not ensure that the new value has been persisted.
/// </summary>
public static event EventHandler<string> ItemChanged;
public override string ToString() => $"{Book} {Rating} {Tags}";
}
}

View File

@ -315,7 +315,7 @@ namespace LibationSearchEngine
var docs = searcher.Search(query, 1);
var scoreDoc = docs.ScoreDocs.SingleOrDefault();
if (scoreDoc == null)
throw new Exception("document not found");
return;
var document = searcher.Doc(scoreDoc.Doc);

View File

@ -34,6 +34,8 @@ namespace LibationWinForms
this.FormClosing += (_, _) => this.SaveSizeAndLocation(Configuration.Instance);
LibraryCommands.LibrarySizeChanged += reloadGridAndUpdateBottomNumbers;
LibraryCommands.BookUserDefinedItemCommitted += setBackupCounts;
// used by async migrations to update ui when complete
DataLayer.UserDefinedItem.Batch_ItemChanged += reloadGridAndUpdateBottomNumbers;
var format = System.Drawing.Imaging.ImageFormat.Jpeg;
PictureStorage.SetDefaultImage(PictureSize._80x80, Properties.Resources.default_cover_80x80.ToBytes(format));

View File

@ -27,17 +27,16 @@ namespace LibationWinForms
#endregion
public event EventHandler Committed;
private Book Book => LibraryBook.Book;
private Image _cover;
private Action Refilter { get; }
public GridEntry(LibraryBook libraryBook, Action refilterOnChanged = null)
public GridEntry(LibraryBook libraryBook)
{
LibraryBook = libraryBook;
Refilter = refilterOnChanged;
_memberValues = CreateMemberValueDictionary();
//Get cover art. If it's default, subscribe to PictureCached
{
(bool isDefault, byte[] picture) = FileManager.PictureStorage.GetPicture(new FileManager.PictureDefinition(Book.PictureId, FileManager.PictureSize._80x80));
@ -142,7 +141,7 @@ namespace LibationWinForms
Book.UserDefinedItem.BookStatus = displayStatus;
Refilter?.Invoke();
Committed?.Invoke(this, null);
}
#endregion

View File

@ -3,9 +3,9 @@ using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using ApplicationServices;
using DataLayer;
using Dinah.Core;
using Dinah.Core.DataBinding;
using Dinah.Core.Threading;
using Dinah.Core.Windows.Forms;
using LibationWinForms.Dialogs;
@ -130,7 +130,12 @@ namespace LibationWinForms
}
var orderedGridEntries = lib
.Select(lb => new GridEntry(lb, Filter)).ToList()
.Select(lb =>
{
var entry = new GridEntry(lb);
entry.Committed += (_, __) => Filter();
return entry;
}).ToList()
// default load order
.OrderByDescending(ge => (DateTime)ge.GetMemberValue(nameof(ge.PurchaseDate)))
//// more advanced example: sort by author, then series, then title
@ -166,8 +171,11 @@ namespace LibationWinForms
var bindingContext = BindingContext[_dataGridView.DataSource];
bindingContext.SuspendBinding();
{
for (var r = _dataGridView.RowCount - 1; r >= 0; r--)
_dataGridView.Rows[r].Visible = productIds.Contains(getGridEntry(r).AudibleProductId);
this.UIThreadSync(() =>
{
for (var r = _dataGridView.RowCount - 1; r >= 0; r--)
_dataGridView.Rows[r].Visible = productIds.Contains(getGridEntry(r).AudibleProductId);
});
}
//Causes repainting of the DataGridView

View File

@ -259,22 +259,25 @@ namespace LibationWinForms
// assign these strings and enums/ints unconditionally. EFCore will only update if changed
if (fileType == FileType.PDF)
book.UserDefinedItem.PdfStatus = LiberatedStatus.Liberated;
book.UserDefinedItem.BatchMode_UpdatePdfStatus(LiberatedStatus.Liberated);
if (fileType == FileType.Audio)
{
var lhack = libhackFiles.FirstOrDefault(f => f.ContainsInsensitive(asin));
if (lhack is null)
book.UserDefinedItem.BookStatus = LiberatedStatus.Liberated;
book.UserDefinedItem.BatchMode_UpdateBookStatus(LiberatedStatus.Liberated);
else
{
book.UserDefinedItem.BookStatus = LiberatedStatus.Error;
book.UserDefinedItem.BatchMode_UpdateBookStatus(LiberatedStatus.Error);
libhackFilesToDelete.Add(lhack);
}
}
}
// in order: save to db, full reindex from db, refresh ui
context.SaveChanges();
ApplicationServices.SearchEngineCommands.FullReIndex();
UserDefinedItem.BatchMode_Finalize();
// only do this after save changes
foreach (var libhackFile in libhackFilesToDelete)