Skip to content

Commit 944d27a

Browse files
committed
feat: add Retry button for failed model downloads in download manager
1 parent 3283355 commit 944d27a

4 files changed

Lines changed: 51 additions & 1 deletion

File tree

StabilityMatrix.Avalonia/ViewModels/Base/PausableProgressItemViewModelBase.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ public abstract partial class PausableProgressItemViewModelBase : ProgressItemVi
1414
nameof(IsPaused),
1515
nameof(IsCompleted),
1616
nameof(CanPauseResume),
17-
nameof(CanCancel)
17+
nameof(CanCancel),
18+
nameof(CanRetry)
1819
)]
1920
private ProgressState state = ProgressState.Inactive;
2021

@@ -33,9 +34,20 @@ public abstract partial class PausableProgressItemViewModelBase : ProgressItemVi
3334
public virtual bool SupportsPauseResume => true;
3435
public virtual bool SupportsCancel => true;
3536

37+
/// <summary>
38+
/// Override to true in subclasses that support manual retry after failure.
39+
/// Defaults to false so unrelated progress item types are never affected.
40+
/// </summary>
41+
public virtual bool SupportsRetry => false;
42+
3643
public bool CanPauseResume => SupportsPauseResume && !IsCompleted && !IsPending;
3744
public bool CanCancel => SupportsCancel && !IsCompleted;
3845

46+
/// <summary>
47+
/// True only when this item supports retry AND is in the Failed state.
48+
/// </summary>
49+
public bool CanRetry => SupportsRetry && State == ProgressState.Failed;
50+
3951
private AsyncRelayCommand? pauseCommand;
4052
public IAsyncRelayCommand PauseCommand => pauseCommand ??= new AsyncRelayCommand(Pause);
4153

@@ -51,6 +63,11 @@ public abstract partial class PausableProgressItemViewModelBase : ProgressItemVi
5163

5264
public virtual Task Cancel() => Task.CompletedTask;
5365

66+
private AsyncRelayCommand? retryCommand;
67+
public IAsyncRelayCommand RetryCommand => retryCommand ??= new AsyncRelayCommand(Retry);
68+
69+
public virtual Task Retry() => Task.CompletedTask;
70+
5471
[RelayCommand]
5572
private Task TogglePauseResume()
5673
{

StabilityMatrix.Avalonia/ViewModels/Progress/DownloadProgressItemViewModel.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ private void OnProgressStateChanged(ProgressState state)
7171
}
7272
}
7373

74+
/// <summary>
75+
/// Downloads support manual retry when they reach the Failed state.
76+
/// </summary>
77+
public override bool SupportsRetry => true;
78+
7479
/// <inheritdoc />
7580
public override Task Cancel()
7681
{
@@ -91,4 +96,13 @@ public override Task Resume()
9196
{
9297
return downloadService.TryResumeDownload(download);
9398
}
99+
100+
/// <inheritdoc />
101+
/// Resets the internal retry counter so the user gets a fresh 3-attempt budget,
102+
/// then re-queues the download exactly as if it were being resumed from pause.
103+
public override Task Retry()
104+
{
105+
download.ResetAttempts();
106+
return downloadService.TryResumeDownload(download);
107+
}
94108
}

StabilityMatrix.Avalonia/Views/ProgressManagerPage.axaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,15 @@
113113
IsVisible="{Binding CanCancel}">
114114
<ui:SymbolIcon Symbol="Cancel" />
115115
</Button>
116+
117+
<!-- Retry button: only visible when download is in Failed state -->
118+
<Button
119+
Classes="transparent-full"
120+
Command="{Binding RetryCommand}"
121+
IsVisible="{Binding CanRetry}"
122+
ToolTip.Tip="Retry download">
123+
<ui:SymbolIcon Symbol="ArrowCounterclockwise" />
124+
</Button>
116125
</StackPanel>
117126

118127
<ProgressBar

StabilityMatrix.Core/Models/TrackedDownload.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,16 @@ private void OnDownloadTaskCompleted(Task task)
423423
downloadPauseTokenSource = null;
424424
}
425425

426+
/// <summary>
427+
/// Resets the internal retry attempt counter back to zero.
428+
/// Call this before a user-initiated retry so the download gets
429+
/// a fresh budget of automatic retries on the new attempt.
430+
/// </summary>
431+
public void ResetAttempts()
432+
{
433+
attempts = 0;
434+
}
435+
426436
public void SetDownloadService(IDownloadService service)
427437
{
428438
downloadService = service;

0 commit comments

Comments
 (0)