Additional null safety

This commit is contained in:
Michael Bucari-Tovo 2025-03-04 15:11:05 -07:00
parent 7658f21d7c
commit c3938c49a9
29 changed files with 326 additions and 275 deletions

View file

@ -12,15 +12,17 @@ using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
#nullable enable
namespace LibationAvalonia.ViewModels
{
public class ProcessQueueViewModel : ViewModelBase, ILogForm
{
public ObservableCollection<LogEntry> LogEntries { get; } = new();
public AvaloniaList<ProcessBookViewModel> Items { get; } = new();
public TrackedQueue<ProcessBookViewModel> Queue { get; }
public ProcessBookViewModel SelectedItem { get; set; }
public Task QueueRunner { get; private set; }
public ProcessBookViewModel? SelectedItem { get; set; }
public Task? QueueRunner { get; private set; }
public bool Running => !QueueRunner?.IsCompleted ?? false;
private readonly LogMe Logger;
@ -41,14 +43,14 @@ namespace LibationAvalonia.ViewModels
private int _completedCount;
private int _errorCount;
private int _queuedCount;
private string _runningTime;
private string? _runningTime;
private bool _progressBarVisible;
private decimal _speedLimit;
public int CompletedCount { get => _completedCount; private set => Dispatcher.UIThread.Invoke(() => { this.RaiseAndSetIfChanged(ref _completedCount, value); this.RaisePropertyChanged(nameof(AnyCompleted)); }); }
public int QueuedCount { get => _queuedCount; private set => Dispatcher.UIThread.Invoke(() => { this.RaiseAndSetIfChanged(ref _queuedCount, value); this.RaisePropertyChanged(nameof(AnyQueued)); }); }
public int ErrorCount { get => _errorCount; private set => Dispatcher.UIThread.Invoke(() => { this.RaiseAndSetIfChanged(ref _errorCount, value); this.RaisePropertyChanged(nameof(AnyErrors)); }); }
public string RunningTime { get => _runningTime; set => Dispatcher.UIThread.Invoke(() => { this.RaiseAndSetIfChanged(ref _runningTime, value); }); }
public string? RunningTime { get => _runningTime; set => Dispatcher.UIThread.Invoke(() => { this.RaiseAndSetIfChanged(ref _runningTime, value); }); }
public bool ProgressBarVisible { get => _progressBarVisible; set => Dispatcher.UIThread.Invoke(() => { this.RaiseAndSetIfChanged(ref _progressBarVisible, value); }); }
public bool AnyCompleted => CompletedCount > 0;
public bool AnyQueued => QueuedCount > 0;
@ -89,7 +91,7 @@ namespace LibationAvalonia.ViewModels
public decimal SpeedLimitIncrement { get; private set; }
private async void Queue_CompletedCountChanged(object sender, int e)
private async void Queue_CompletedCountChanged(object? sender, int e)
{
int errCount = Queue.Completed.Count(p => p.Result is ProcessBookResult.FailedAbort or ProcessBookResult.FailedSkip or ProcessBookResult.FailedRetry or ProcessBookResult.ValidationFail);
int completeCount = Queue.Completed.Count(p => p.Result is ProcessBookResult.Success);
@ -98,7 +100,7 @@ namespace LibationAvalonia.ViewModels
CompletedCount = completeCount;
await Dispatcher.UIThread.InvokeAsync(() => this.RaisePropertyChanged(nameof(Progress)));
}
private async void Queue_QueuededCountChanged(object sender, int cueCount)
private async void Queue_QueuededCountChanged(object? sender, int cueCount)
{
QueuedCount = cueCount;
await Dispatcher.UIThread.InvokeAsync(() => this.RaisePropertyChanged(nameof(Progress)));
@ -120,7 +122,7 @@ namespace LibationAvalonia.ViewModels
private bool isBookInQueue(LibraryBook libraryBook)
{
var entry = Queue.FirstOrDefault(b => b?.LibraryBook?.Book?.AudibleProductId == libraryBook.Book.AudibleProductId);
if (entry == null)
if (entry == null)
return false;
else if (entry.Status is ProcessBookStatus.Cancelled or ProcessBookStatus.Failed)
return !Queue.RemoveCompleted(entry);
@ -218,13 +220,17 @@ namespace LibationAvalonia.ViewModels
while (Queue.MoveNext())
{
var nextBook = Queue.Current;
if (Queue.Current is not ProcessBookViewModel nextBook)
{
Serilog.Log.Logger.Information("Current queue item is empty.");
continue;
}
Serilog.Log.Logger.Information("Begin processing queued item. {item_LibraryBook}", nextBook?.LibraryBook);
Serilog.Log.Logger.Information("Begin processing queued item. {item_LibraryBook}", nextBook.LibraryBook);
var result = await nextBook.ProcessOneAsync();
Serilog.Log.Logger.Information("Completed processing queued item: {item_LibraryBook}\r\nResult: {result}", nextBook?.LibraryBook, result);
Serilog.Log.Logger.Information("Completed processing queued item: {item_LibraryBook}\r\nResult: {result}", nextBook.LibraryBook, result);
if (result == ProcessBookResult.ValidationFail)
Queue.ClearCurrent();
@ -256,7 +262,7 @@ This error appears to be caused by a temporary interruption of service that some
}
}
private void CounterTimer_Tick(object state)
private void CounterTimer_Tick(object? state)
{
string timeToStr(TimeSpan time)
{
@ -273,6 +279,6 @@ This error appears to be caused by a temporary interruption of service that some
{
public DateTime LogDate { get; init; }
public string LogDateString => LogDate.ToShortTimeString();
public string LogMessage { get; init; }
public string? LogMessage { get; init; }
}
}