From 6675c2d871ad41346ced715007ae9bb81cf29d9b Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 1 Nov 2026 19:09:33 +0000 Subject: [PATCH] enhance: show real progress of git operations in running popups Git already streams progress lines like `Receiving objects: 45% (450/1000)` (fetch/pull/push/clone/checkout/submodule/LFS are run with `--progress`) and the latest line is shown as the popup's description, but the progress bar was always indeterminate. Parse the `NN%` after the phase name from the current description and use it for a determinate progress bar with a percentage label. Falls back to the indeterminate bar for lines without a percentage. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01KCxH1zwDXLd9kfAAkcf6PZ --- src/Views/PopupRunningStatus.axaml | 21 +++++++++++++----- src/Views/PopupRunningStatus.axaml.cs | 32 ++++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/src/Views/PopupRunningStatus.axaml b/src/Views/PopupRunningStatus.axaml index 6a0dbdb420..a0412cba70 100644 --- a/src/Views/PopupRunningStatus.axaml +++ b/src/Views/PopupRunningStatus.axaml @@ -21,10 +21,21 @@ FontStyle="Italic" Text="{Binding #ThisControl.Description}"/> - + + + + + diff --git a/src/Views/PopupRunningStatus.axaml.cs b/src/Views/PopupRunningStatus.axaml.cs index 72caaed86e..8016191e8a 100644 --- a/src/Views/PopupRunningStatus.axaml.cs +++ b/src/Views/PopupRunningStatus.axaml.cs @@ -1,3 +1,4 @@ +using System.Text.RegularExpressions; using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Shapes; @@ -50,12 +51,17 @@ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs chang else StopAnim(); } + else if (change.Property == DescriptionProperty) + { + if (IsVisible && !_isUnloading) + UpdateProgress(); + } } private void StartAnim() { Icon.Content = new Path() { Classes = { "waiting" } }; - ProgressBar.IsIndeterminate = true; + UpdateProgress(); } private void StopAnim() @@ -64,9 +70,33 @@ private void StopAnim() path.Classes.Clear(); Icon.Content = null; ProgressBar.IsIndeterminate = false; + ProgressBar.Value = 0; + Percentage.IsVisible = false; + } + + private void UpdateProgress() + { + // Git reports the progress of long-running operations as `: NN% (...)`. Only the + // percentage is used here, so it also works with translated phase names. + var match = string.IsNullOrEmpty(_description) ? null : REG_PROGRESS().Match(_description); + if (match is { Success: true } && int.TryParse(match.Groups[1].Value, out var percent) && percent <= 100) + { + ProgressBar.IsIndeterminate = false; + ProgressBar.Value = percent; + Percentage.Text = $"{percent}%"; + Percentage.IsVisible = true; + } + else + { + ProgressBar.IsIndeterminate = true; + Percentage.IsVisible = false; + } } private string _description = string.Empty; private bool _isUnloading = false; + + [GeneratedRegex(@"^[^%]+?:\s+(\d{1,3})%")] + private static partial Regex REG_PROGRESS(); } }