File tree Expand file tree Collapse file tree
StabilityMatrix.Core/Models Expand file tree Collapse file tree Original file line number Diff line number Diff 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 {
Original file line number Diff line number Diff 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}
Original file line number Diff line number Diff line change 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
Original file line number Diff line number Diff 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 ;
You can’t perform that action at this time.
0 commit comments