Files
FCP-Mod-Updater/UI/ProgressReporter.cs
T
2026-02-04 11:44:21 +08:00

97 lines
3.2 KiB
C#

using Spectre.Console;
namespace FCPModUpdater.UI;
public static class ProgressReporter
{
public static async Task<T> WithStatusAsync<T>(string status, Func<Task<T>> action)
{
return await AnsiConsole.Status()
.Spinner(Spinner.Known.Dots)
.SpinnerStyle(Style.Parse("blue"))
.StartAsync(status, async _ => await action());
}
public static async Task WithStatusAsync(string status, Func<Task> action)
{
await AnsiConsole.Status()
.Spinner(Spinner.Known.Dots)
.SpinnerStyle(Style.Parse("blue"))
.StartAsync(status, async _ => await action());
}
public static async Task WithProgressAsync(
string description,
IEnumerable<(string Name, Func<ProgressTask, Task> Action)> tasks)
{
await AnsiConsole.Progress()
.Columns(
new TaskDescriptionColumn(),
new ProgressBarColumn(),
new PercentageColumn(),
new SpinnerColumn())
.StartAsync(async ctx =>
{
var taskList = tasks.ToList();
var progressTasks = taskList
.Select(t => (Task: ctx.AddTask(t.Name), t.Action))
.ToList();
foreach ((ProgressTask task, var action) in progressTasks)
{
await action(task);
task.Value = 100;
}
});
}
public static async Task<IReadOnlyList<(string Name, bool Success, string? Error)>> WithBatchProgressAsync<T>(
string description,
IReadOnlyList<T> items,
Func<T, string> nameSelector,
Func<T, IProgress<double>, Task<(bool Success, string? Error)>> action)
{
var results = new List<(string Name, bool Success, string? Error)>();
await AnsiConsole.Progress()
.Columns(
new TaskDescriptionColumn(),
new ProgressBarColumn(),
new PercentageColumn(),
new SpinnerColumn())
.StartAsync(async ctx =>
{
ProgressTask overallTask = ctx.AddTask($"[bold]{description}[/]", maxValue: items.Count);
foreach (T item in items)
{
var name = nameSelector(item);
ProgressTask itemTask = ctx.AddTask($" {name}");
var progress = new Progress<double>(p => itemTask.Value = p);
try
{
var (success, error) = await action(item, progress);
results.Add((name, success, error));
itemTask.Value = 100;
itemTask.Description = success
? $" [green]{name}[/]"
: $" [red]{name}[/]";
}
catch (Exception ex)
{
results.Add((name, false, ex.Message));
itemTask.Value = 100;
itemTask.Description = $" [red]{name}[/]";
}
overallTask.Increment(1);
}
});
return results;
}
}