Make Form1 MVVM
This commit is contained in:
parent
7b7e1d8574
commit
180d591b0a
15 changed files with 402 additions and 369 deletions
|
|
@ -1,17 +1,236 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using ApplicationServices;
|
||||
using Dinah.Core;
|
||||
using LibationFileManager;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace LibationWinForms.AvaloniaUI.ViewModels
|
||||
{
|
||||
public class MainWindowViewModel : ViewModelBase
|
||||
{
|
||||
private string _filterString;
|
||||
private string _removeBooksButtonText = "Remove # Books from Libation";
|
||||
private bool _autoScanChecked = true;
|
||||
private bool _firstFilterIsDefault = true;
|
||||
private bool _removeButtonsVisible = true;
|
||||
private int _numAccountsScanning = 2;
|
||||
private int _accountsCount = 0;
|
||||
private bool _queueOpen = true;
|
||||
private int _visibleCount = 1;
|
||||
private LibraryCommands.LibraryStats _libraryStats;
|
||||
private int _visibleNotLiberated = 1;
|
||||
|
||||
/// <summary> The Process Queue's viewmodel </summary>
|
||||
public ProcessQueueViewModel ProcessQueueViewModel { get; } = new ProcessQueueViewModel();
|
||||
|
||||
|
||||
/// <summary> Library filterting query </summary>
|
||||
public string FilterString { get => _filterString; set => this.RaiseAndSetIfChanged(ref _filterString, value); }
|
||||
|
||||
|
||||
/// <summary> Display text for the "Remove # Books from Libation" button </summary>
|
||||
public string RemoveBooksButtonText { get => _removeBooksButtonText; set => this.RaiseAndSetIfChanged(ref _removeBooksButtonText, value); }
|
||||
public bool RemoveButtonsVisible { get => _removeButtonsVisible; set => this.RaiseAndSetIfChanged(ref _removeButtonsVisible, value); }
|
||||
|
||||
|
||||
/// <summary> Auto scanning accounts is enables </summary>
|
||||
public bool AutoScanChecked
|
||||
{
|
||||
get => _autoScanChecked;
|
||||
set
|
||||
{
|
||||
if (value != _autoScanChecked)
|
||||
Configuration.Instance.AutoScan = value;
|
||||
this.RaiseAndSetIfChanged(ref _autoScanChecked, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary> Indicates that the first quick filter is the default filter </summary>
|
||||
public bool FirstFilterIsDefault
|
||||
{
|
||||
get => _firstFilterIsDefault;
|
||||
set
|
||||
{
|
||||
if (value != _firstFilterIsDefault)
|
||||
QuickFilters.UseDefault = value;
|
||||
this.RaiseAndSetIfChanged(ref _firstFilterIsDefault, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary> Indicates if the "Remove # Books from Libation" and "Done Removing" buttons shouls be visible </summary>
|
||||
public bool RemoveButtonsVisible
|
||||
{
|
||||
get => _removeButtonsVisible;
|
||||
set
|
||||
{
|
||||
this.RaiseAndSetIfChanged(ref _removeButtonsVisible, value);
|
||||
this.RaisePropertyChanged(nameof(RemoveMenuItemsEnabled));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary> The number of accounts currently being scanned </summary>
|
||||
public int NumAccountsScanning
|
||||
{
|
||||
get => _numAccountsScanning;
|
||||
set
|
||||
{
|
||||
this.RaiseAndSetIfChanged(ref _numAccountsScanning, value);
|
||||
this.RaisePropertyChanged(nameof(ActivelyScanning));
|
||||
this.RaisePropertyChanged(nameof(RemoveMenuItemsEnabled));
|
||||
this.RaisePropertyChanged(nameof(ScanningText));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Indicates that Libation is currently scanning account(s) </summary>
|
||||
public bool ActivelyScanning => _numAccountsScanning > 0;
|
||||
/// <summary> Indicates if the "Remove Books" menu items are enabled</summary>
|
||||
public bool RemoveMenuItemsEnabled => !RemoveButtonsVisible && !ActivelyScanning;
|
||||
/// <summary> The library scanning status text </summary>
|
||||
public string ScanningText => _numAccountsScanning == 1 ? "Scanning..." : $"Scanning {_numAccountsScanning} accounts...";
|
||||
|
||||
|
||||
|
||||
/// <summary> The number of accounts added to Libation </summary>
|
||||
public int AccountsCount
|
||||
{
|
||||
get => _accountsCount;
|
||||
set
|
||||
{
|
||||
this.RaiseAndSetIfChanged(ref _accountsCount, value);
|
||||
this.RaisePropertyChanged(nameof(ZeroAccounts));
|
||||
this.RaisePropertyChanged(nameof(AnyAccounts));
|
||||
this.RaisePropertyChanged(nameof(OneAccount));
|
||||
this.RaisePropertyChanged(nameof(MultipleAccounts));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> There are no Audible accounts </summary>
|
||||
public bool ZeroAccounts => _accountsCount == 0;
|
||||
/// <summary> There is at least one Audible account </summary>
|
||||
public bool AnyAccounts => _accountsCount > 0;
|
||||
/// <summary> There is exactly one Audible account </summary>
|
||||
public bool OneAccount => _accountsCount == 1;
|
||||
/// <summary> There are more than 1 Audible accounts </summary>
|
||||
public bool MultipleAccounts => _accountsCount > 1;
|
||||
|
||||
|
||||
|
||||
/// <summary> The Process Queue panel is open </summary>
|
||||
public bool QueueOpen
|
||||
{
|
||||
get => _queueOpen;
|
||||
set
|
||||
{
|
||||
this.RaiseAndSetIfChanged(ref _queueOpen, value);
|
||||
QueueHideButtonText = _queueOpen? "❱❱❱" : "❰❰❰";
|
||||
this.RaisePropertyChanged(nameof(QueueHideButtonText));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> The Process Queue's Expand/Collapse button display text </summary>
|
||||
public string QueueHideButtonText { get; private set; }
|
||||
|
||||
|
||||
|
||||
/// <summary> The number of books visible in the Product Display </summary>
|
||||
public int VisibleCount
|
||||
{
|
||||
get => _visibleCount;
|
||||
set
|
||||
{
|
||||
this.RaiseAndSetIfChanged(ref _visibleCount, value);
|
||||
this.RaisePropertyChanged(nameof(VisibleCountText));
|
||||
this.RaisePropertyChanged(nameof(VisibleCountMenuItemText));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> The Bottom-right visible book count status text </summary>
|
||||
public string VisibleCountText => $"Visible: {VisibleCount}";
|
||||
/// <summary> The Visible Books menu item header text </summary>
|
||||
public string VisibleCountMenuItemText => $"_Visible Books {VisibleCount}";
|
||||
|
||||
|
||||
|
||||
/// <summary> The user's library statistics </summary>
|
||||
public LibraryCommands.LibraryStats LibraryStats
|
||||
{
|
||||
get => _libraryStats;
|
||||
set
|
||||
{
|
||||
this.RaiseAndSetIfChanged(ref _libraryStats, value);
|
||||
|
||||
var backupsCountText
|
||||
= !LibraryStats.HasBookResults ? "No books. Begin by importing your library"
|
||||
: !LibraryStats.HasPendingBooks ? $"All {"book".PluralizeWithCount(LibraryStats.booksFullyBackedUp)} backed up"
|
||||
: $"BACKUPS: No progress: {LibraryStats.booksNoProgress} In process: {LibraryStats.booksDownloadedOnly} Fully backed up: {LibraryStats.booksFullyBackedUp} {(LibraryStats.booksError > 0 ? $" Errors : {LibraryStats.booksError}" : "")}";
|
||||
|
||||
var pdfCountText
|
||||
= !LibraryStats.HasPdfResults ? ""
|
||||
: LibraryStats.pdfsNotDownloaded == 0 ? $" | All {LibraryStats.pdfsDownloaded} PDFs downloaded"
|
||||
: $" | PDFs: NOT d/l'ed: {LibraryStats.pdfsNotDownloaded} Downloaded: {LibraryStats.pdfsDownloaded}";
|
||||
|
||||
StatusCountText = backupsCountText + pdfCountText;
|
||||
|
||||
BookBackupsToolStripText
|
||||
= LibraryStats.HasPendingBooks
|
||||
? $"Begin _Book and PDF Backups: {LibraryStats.PendingBooks} remaining"
|
||||
: "All books have been liberated";
|
||||
|
||||
PdfBackupsToolStripText
|
||||
= LibraryStats.pdfsNotDownloaded > 0
|
||||
? $"Begin _PDF Only Backups: {LibraryStats.pdfsNotDownloaded} remaining"
|
||||
: "All PDFs have been downloaded";
|
||||
|
||||
|
||||
this.RaisePropertyChanged(nameof(HasBookResults));
|
||||
this.RaisePropertyChanged(nameof(StatusCountText));
|
||||
this.RaisePropertyChanged(nameof(BookBackupsToolStripText));
|
||||
this.RaisePropertyChanged(nameof(PdfBackupsToolStripText));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Indicates whether the library contains any books </summary>
|
||||
public bool HasBookResults => LibraryStats?.HasBookResults ?? false;
|
||||
/// <summary> Bottom-left library statistics display text </summary>
|
||||
public string StatusCountText { get; private set; } = "[Calculating backed up book quantities] | [Calculating backed up PDFs]";
|
||||
/// <summary> The "Begin Book and PDF Backup" menu item header text </summary>
|
||||
public string BookBackupsToolStripText { get; private set; } = "Begin _Book and PDF Backups: 0";
|
||||
/// <summary> The "Begin PDF Only Backup" menu item header text </summary>
|
||||
public string PdfBackupsToolStripText { get; private set; } = "Begin _PDF Only Backups: 0";
|
||||
|
||||
|
||||
|
||||
/// <summary> The number of books visible in the Products Display that have not yet been liberated </summary>
|
||||
public int VisibleNotLiberated
|
||||
{
|
||||
get => _visibleNotLiberated;
|
||||
set
|
||||
{
|
||||
this.RaiseAndSetIfChanged(ref _visibleNotLiberated, value);
|
||||
|
||||
LiberateVisibleToolStripText
|
||||
= AnyVisibleNotLiberated
|
||||
? $"Liberate _Visible Books: {VisibleNotLiberated}"
|
||||
: "All visible books are liberated";
|
||||
|
||||
LiberateVisibleToolStripText_2
|
||||
= AnyVisibleNotLiberated
|
||||
? $"_Liberate: {VisibleNotLiberated}"
|
||||
: "All visible books are liberated";
|
||||
|
||||
this.RaisePropertyChanged(nameof(AnyVisibleNotLiberated));
|
||||
this.RaisePropertyChanged(nameof(LiberateVisibleToolStripText));
|
||||
this.RaisePropertyChanged(nameof(LiberateVisibleToolStripText_2));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Indicates if any of the books visible in the Products Display haven't been liberated </summary>
|
||||
public bool AnyVisibleNotLiberated => VisibleNotLiberated > 0;
|
||||
/// <summary> The "Liberate Visible Books" menu item header text (submenu item of the "Liberate Menu" menu item) </summary>
|
||||
public string LiberateVisibleToolStripText { get; private set; } = "Liberate _Visible Books: 0";
|
||||
/// <summary> The "Liberate" menu item header text (submenu item of the "Visible Books" menu item) </summary>
|
||||
public string LiberateVisibleToolStripText_2 { get; private set; } = "_Liberate: 0";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using ApplicationServices;
|
||||
using Avalonia.Threading;
|
||||
using DataLayer;
|
||||
using ReactiveUI;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
|
@ -19,10 +20,13 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
|
|||
public Task QueueRunner { get; private set; }
|
||||
public bool Running => !QueueRunner?.IsCompleted ?? false;
|
||||
|
||||
private readonly ProcessQueue.LogMe Logger;
|
||||
|
||||
public ProcessQueueViewModel()
|
||||
{
|
||||
Queue.QueuededCountChanged += Queue_QueuededCountChanged;
|
||||
Queue.CompletedCountChanged += Queue_CompletedCountChanged;
|
||||
Logger = ProcessQueue.LogMe.RegisterForm(this);
|
||||
}
|
||||
|
||||
private int _completedCount;
|
||||
|
|
@ -66,6 +70,73 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
|
|||
}));
|
||||
}
|
||||
|
||||
|
||||
#region Add Books to Queue
|
||||
|
||||
private bool isBookInQueue(LibraryBook libraryBook)
|
||||
=> Queue.Any(b => b?.LibraryBook?.Book?.AudibleProductId == libraryBook.Book.AudibleProductId);
|
||||
|
||||
public void AddDownloadPdf(LibraryBook libraryBook)
|
||||
=> AddDownloadPdf(new List<LibraryBook>() { libraryBook });
|
||||
|
||||
public void AddDownloadDecrypt(LibraryBook libraryBook)
|
||||
=> AddDownloadDecrypt(new List<LibraryBook>() { libraryBook });
|
||||
|
||||
public void AddConvertMp3(LibraryBook libraryBook)
|
||||
=> AddConvertMp3(new List<LibraryBook>() { libraryBook });
|
||||
|
||||
public void AddDownloadPdf(IEnumerable<LibraryBook> entries)
|
||||
{
|
||||
List<ProcessBook2> procs = new();
|
||||
foreach (var entry in entries)
|
||||
{
|
||||
if (isBookInQueue(entry))
|
||||
continue;
|
||||
|
||||
ProcessBook2 pbook = new(entry, Logger);
|
||||
pbook.AddDownloadPdf();
|
||||
procs.Add(pbook);
|
||||
}
|
||||
|
||||
Serilog.Log.Logger.Information("Queueing {count} books", procs.Count);
|
||||
AddToQueue(procs);
|
||||
}
|
||||
|
||||
public void AddDownloadDecrypt(IEnumerable<LibraryBook> entries)
|
||||
{
|
||||
List<ProcessBook2> procs = new();
|
||||
foreach (var entry in entries)
|
||||
{
|
||||
if (isBookInQueue(entry))
|
||||
continue;
|
||||
|
||||
ProcessBook2 pbook = new(entry, Logger);
|
||||
pbook.AddDownloadDecryptBook();
|
||||
pbook.AddDownloadPdf();
|
||||
procs.Add(pbook);
|
||||
}
|
||||
|
||||
Serilog.Log.Logger.Information("Queueing {count} books", procs.Count);
|
||||
AddToQueue(procs);
|
||||
}
|
||||
|
||||
public void AddConvertMp3(IEnumerable<LibraryBook> entries)
|
||||
{
|
||||
List<ProcessBook2> procs = new();
|
||||
foreach (var entry in entries)
|
||||
{
|
||||
if (isBookInQueue(entry))
|
||||
continue;
|
||||
|
||||
ProcessBook2 pbook = new(entry, Logger);
|
||||
pbook.AddConvertToMp3();
|
||||
procs.Add(pbook);
|
||||
}
|
||||
|
||||
Serilog.Log.Logger.Information("Queueing {count} books", procs.Count);
|
||||
AddToQueue(procs);
|
||||
}
|
||||
|
||||
public void AddToQueue(IEnumerable<ProcessBook2> pbook)
|
||||
{
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
|
|
@ -76,6 +147,8 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
|
|||
});
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
DateTime StartingTime;
|
||||
private async Task QueueLoop()
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue