diff --git a/src/ViewModels/LauncherPage.cs b/src/ViewModels/LauncherPage.cs index db5e0241b..29e8f2757 100644 --- a/src/ViewModels/LauncherPage.cs +++ b/src/ViewModels/LauncherPage.cs @@ -107,9 +107,15 @@ public async Task ProcessPopupAsync() public void CancelPopup() { - if (_popup == null || _popup.InProgress) + if (_popup == null) return; + if (_popup.InProgress) + { + _popup.Cancel(); + return; + } + _popup?.Cleanup(); Popup = null; } diff --git a/src/ViewModels/Popup.cs b/src/ViewModels/Popup.cs index 9d800c50c..0213a4b39 100644 --- a/src/ViewModels/Popup.cs +++ b/src/ViewModels/Popup.cs @@ -34,7 +34,7 @@ public void OnReceiveCommandLog(string data) ProgressDescription = desc; } - public void Cleanup() + public virtual void Cleanup() { _log?.Unsubscribe(this); } @@ -44,6 +44,18 @@ public virtual bool CanStartDirectly() return true; } + /// + /// Indicates the in-progress operation of this popup can be interrupted. + /// + public virtual bool CanCancel => false; + + /// + /// Interrupts the in-progress operation of this popup. + /// + public virtual void Cancel() + { + } + public virtual Task Sure() { return null; diff --git a/src/ViewModels/Push.cs b/src/ViewModels/Push.cs index b4d9029a9..0a2d43dfb 100644 --- a/src/ViewModels/Push.cs +++ b/src/ViewModels/Push.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; +using System.Threading; using System.Threading.Tasks; namespace SourceGit.ViewModels @@ -190,6 +191,9 @@ public override async Task Sure() { using var lockWatcher = _repo.LockWatcher(); + _cts?.Cancel(); + _cts = new CancellationTokenSource(); + var remoteBranchName = _selectedRemoteBranch.Name; ProgressDescription = $"Push {_selectedLocalBranch.Name} -> {_selectedRemote.Name}/{remoteBranchName} ..."; @@ -204,12 +208,26 @@ public override async Task Sure() PushAllTags, _repo.Submodules.Count > 0 && CheckSubmodules, _isSetTrackOptionVisible && _tracking, - ForcePush).Use(log).RunAsync(); + ForcePush).Use(log).WithCancellation(_cts.Token).RunAsync(); log.Complete(); return succ; } + public override bool CanCancel => true; + + public override void Cancel() + { + _cts?.Cancel(); + } + + public override void Cleanup() + { + base.Cleanup(); + _cts?.Dispose(); + _cts = null; + } + private void AutoSelectBranchByRemote() { if (_selectedRemote == null || _selectedLocalBranch == null) @@ -266,5 +284,6 @@ private void AutoSelectBranchByRemote() private Models.Branch _selectedRemoteBranch = null; private bool _isSetTrackOptionVisible = false; private bool _tracking = true; + private CancellationTokenSource _cts = null; } } diff --git a/src/Views/LauncherPage.axaml b/src/Views/LauncherPage.axaml index bcbecbeca..4b2075b97 100644 --- a/src/Views/LauncherPage.axaml +++ b/src/Views/LauncherPage.axaml @@ -113,8 +113,8 @@ + CanCancel="{Binding CanCancel}" + IsVisible="{Binding InProgress}"/> diff --git a/src/Views/PopupRunningStatus.axaml b/src/Views/PopupRunningStatus.axaml index 6a0dbdb42..1deafc782 100644 --- a/src/Views/PopupRunningStatus.axaml +++ b/src/Views/PopupRunningStatus.axaml @@ -13,6 +13,15 @@ +