feat(ui): stream claude update progress into the footer strip
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
3dc735b2af
commit
2b19c8c49d
@@ -206,6 +206,9 @@ public sealed partial class IslandsShellViewModel : ViewModelBase, IDisposable
|
||||
// paint a good outcome red, which reads as a failure.
|
||||
public void FlashFooterSuccess(string message) => FlashFooter(message, WorkerLogLevel.Success);
|
||||
|
||||
// Same strip, for neutral in-progress text (e.g. a CLI's progress lines).
|
||||
public void FlashFooterInfo(string message) => FlashFooter(message, WorkerLogLevel.Info);
|
||||
|
||||
private void FlashFooter(string message, WorkerLogLevel level)
|
||||
{
|
||||
if (level == WorkerLogLevel.Error)
|
||||
@@ -749,8 +752,10 @@ public sealed partial class IslandsShellViewModel : ViewModelBase, IDisposable
|
||||
{
|
||||
_updatingClaudeCli = true;
|
||||
UpdateClaudeCliCommand.NotifyCanExecuteChanged();
|
||||
var finished = false;
|
||||
try
|
||||
{
|
||||
FlashFooterInfo(Loc.T("vm.shell.updatingClaudeCli"));
|
||||
var dto = Worker is null ? null : await Worker.GetClaudeBinAsync();
|
||||
if (dto is null)
|
||||
{
|
||||
@@ -758,18 +763,24 @@ public sealed partial class IslandsShellViewModel : ViewModelBase, IDisposable
|
||||
return;
|
||||
}
|
||||
|
||||
var (success, message) = await RunClaudeUpdateAsync(dto);
|
||||
// `finished` is only touched on the UI thread: a queued line can't overwrite the final flash.
|
||||
var (success, message) = await RunClaudeUpdateAsync(dto, line => Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
if (!finished) FlashFooterInfo(line);
|
||||
}));
|
||||
finished = true;
|
||||
if (success) FlashFooterSuccess(message);
|
||||
else FlashFooterError(message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
finished = true;
|
||||
_updatingClaudeCli = false;
|
||||
UpdateClaudeCliCommand.NotifyCanExecuteChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task<(bool Success, string Message)> RunClaudeUpdateAsync(ClaudeBinDto dto)
|
||||
private static async Task<(bool Success, string Message)> RunClaudeUpdateAsync(ClaudeBinDto dto, Action<string> onStdoutLine)
|
||||
{
|
||||
var resolved = ClaudeDo.Data.Environment.ExecutableResolver.Resolve(dto.Value);
|
||||
if (resolved is null) return (false, $"Update failed: '{dto.Value}' not found.");
|
||||
@@ -785,7 +796,12 @@ public sealed partial class IslandsShellViewModel : ViewModelBase, IDisposable
|
||||
using var process = new System.Diagnostics.Process { StartInfo = psi };
|
||||
var stdout = new System.Text.StringBuilder();
|
||||
var stderr = new System.Text.StringBuilder();
|
||||
process.OutputDataReceived += (_, e) => { if (e.Data is not null) stdout.AppendLine(e.Data); };
|
||||
process.OutputDataReceived += (_, e) =>
|
||||
{
|
||||
if (e.Data is null) return;
|
||||
stdout.AppendLine(e.Data);
|
||||
if (!string.IsNullOrWhiteSpace(e.Data)) onStdoutLine(e.Data.Trim());
|
||||
};
|
||||
process.ErrorDataReceived += (_, e) => { if (e.Data is not null) stderr.AppendLine(e.Data); };
|
||||
|
||||
try { process.Start(); }
|
||||
|
||||
Reference in New Issue
Block a user