Browse Source

Add download notifications, improve cleanup

pull/109/head
Ionite 1 year ago
parent
commit
85795b4a70
No known key found for this signature in database
  1. 40
      StabilityMatrix.Avalonia/ViewModels/ProgressManagerViewModel.cs
  2. 44
      StabilityMatrix.Core/Models/TrackedDownload.cs

40
StabilityMatrix.Avalonia/ViewModels/ProgressManagerViewModel.cs

@ -3,8 +3,10 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Avalonia.Collections;
using Avalonia.Controls.Notifications;
using CommunityToolkit.Mvvm.ComponentModel;
using FluentAvalonia.UI.Controls;
using Polly;
using StabilityMatrix.Avalonia.Models;
using StabilityMatrix.Avalonia.Services;
using StabilityMatrix.Avalonia.ViewModels.Base;
@ -22,13 +24,19 @@ namespace StabilityMatrix.Avalonia.ViewModels;
[View(typeof(ProgressManagerPage))]
public partial class ProgressManagerViewModel : PageViewModelBase
{
private readonly INotificationService notificationService;
public override string Title => "Download Manager";
public override IconSource IconSource => new SymbolIconSource {Symbol = Symbol.ArrowCircleDown, IsFilled = true};
public AvaloniaList<ProgressItemViewModelBase> ProgressItems { get; } = new();
public ProgressManagerViewModel(ITrackedDownloadService trackedDownloadService)
public ProgressManagerViewModel(
ITrackedDownloadService trackedDownloadService,
INotificationService notificationService)
{
this.notificationService = notificationService;
// Attach to the event
trackedDownloadService.DownloadAdded += TrackedDownloadService_OnDownloadAdded;
}
@ -36,6 +44,31 @@ public partial class ProgressManagerViewModel : PageViewModelBase
private void TrackedDownloadService_OnDownloadAdded(object? sender, TrackedDownload e)
{
var vm = new DownloadProgressItemViewModel(e);
// Attach notification handlers
e.ProgressStateChanged += (s, state) =>
{
var download = s as TrackedDownload;
switch (state)
{
case ProgressState.Success:
notificationService.Show("Download Completed", $"Download of {e.FileName} completed successfully.", NotificationType.Success);
break;
case ProgressState.Failed:
var msg = "";
if (download?.Exception is { } exception)
{
msg = $"({exception.GetType().Name}) {exception.Message}";
}
notificationService.ShowPersistent("Download Failed", $"Download of {e.FileName} failed: {msg}", NotificationType.Error);
break;
case ProgressState.Cancelled:
notificationService.Show("Download Cancelled", $"Download of {e.FileName} was cancelled.", NotificationType.Warning);
break;
}
};
ProgressItems.Add(vm);
}
@ -52,6 +85,11 @@ public partial class ProgressManagerViewModel : PageViewModelBase
}
}
private void ShowFailedNotification(string title, string message)
{
notificationService.ShowPersistent(title, message, NotificationType.Error);
}
public void StartEventListener()
{
EventManager.Instance.ProgressChanged += OnProgressChanged;

44
StabilityMatrix.Core/Models/TrackedDownload.cs

@ -48,8 +48,11 @@ public class TrackedDownload
public bool ValidateHash { get; init; }
[JsonConverter(typeof(JsonStringEnumConverter))]
public ProgressState ProgressState { get; set; } = ProgressState.Inactive;
public List<string> ExtraCleanupFileNames { get; init; } = new();
// Used for restoring progress on load
public long DownloadedBytes { get; set; }
public long TotalBytes { get; set; }
@ -207,17 +210,37 @@ public class TrackedDownload
// Otherwise handle it manually
else
{
// Delete the temp file
DoCleanup();
ProgressState = ProgressState.Cancelled;
OnProgressStateChanged(ProgressState);
}
}
/// <summary>
/// Deletes the temp file and any extra cleanup files
/// </summary>
private void DoCleanup()
{
try
{
DownloadDirectory.JoinFile(TempFileName).Delete();
}
catch (IOException)
{
Logger.Warn("Failed to delete temp file {TempFile}", TempFileName);
}
foreach (var extraFile in ExtraCleanupFileNames)
{
try
{
DownloadDirectory.JoinFile(TempFileName).Delete();
DownloadDirectory.JoinFile(extraFile).Delete();
}
catch (IOException)
{
Logger.Warn("Failed to delete extra cleanup file {ExtraFile}", extraFile);
}
ProgressState = ProgressState.Cancelled;
OnProgressStateChanged(ProgressState);
}
}
@ -258,17 +281,10 @@ public class TrackedDownload
ProgressState = ProgressState.Success;
}
// For failed or cancelled, delete the temp file
// For failed or cancelled, delete the temp files
if (ProgressState is ProgressState.Failed or ProgressState.Cancelled)
{
// Delete the temp file
try
{
DownloadDirectory.JoinFile(TempFileName).Delete();
}
catch (IOException)
{
}
DoCleanup();
}
else if (ProgressState == ProgressState.Success)
{

Loading…
Cancel
Save