Files

65 lines
2.6 KiB
C#

using CommunityToolkit.Mvvm.ComponentModel;
using FluidExplorer.Models;
using FluidExplorer.Services.Operations;
namespace FluidExplorer.ViewModels;
/// <summary>
/// 操作队列面板里的一行。作业对象是在后台线程上更新并抛 PropertyChanged 的,
/// 直接绑定会跨线程更新 UI 而崩溃,因此这里在 UI 线程维护一份快照,由定时器按 250ms 刷新。
/// </summary>
public sealed partial class JobRowViewModel : ObservableObject
{
[ObservableProperty] private string _title = string.Empty;
[ObservableProperty] private string _stateText = string.Empty;
[ObservableProperty] private string _progressText = string.Empty;
[ObservableProperty] private string _currentItem = string.Empty;
[ObservableProperty] private double _progress;
[ObservableProperty] private bool _isIndeterminate;
[ObservableProperty] private bool _canPause;
[ObservableProperty] private bool _canCancel;
[ObservableProperty] private bool _isFinished;
[ObservableProperty] private string _pauseGlyph = "\uE769";
public JobRowViewModel(FileOperationJob job)
{
Job = job;
Refresh();
}
public FileOperationJob Job { get; }
public void Refresh()
{
Title = Job.Title;
StateText = Job.State switch
{
JobState.Queued => "排队中",
JobState.Running => "进行中",
JobState.Paused => "已暂停",
JobState.Completed => "已完成",
JobState.CompletedWithErrors => "已完成(部分出错)",
JobState.Cancelled => "已取消",
JobState.Failed => "失败",
_ => Job.State.ToString()
};
var parts = new List<string> { $"{Job.CompletedItems:N0} / {Job.TotalItems:N0} 个项目" };
if (Job.TotalBytes > 0)
parts.Add($"{FileEntry.FormatSize(Job.CompletedBytes)} / {FileEntry.FormatSize(Job.TotalBytes)}");
if (Job.BytesPerSecond > 1) parts.Add($"{FileEntry.FormatSize((long)Job.BytesPerSecond)}/s");
if (Job.Eta is { } eta && eta.TotalSeconds > 1 && eta.TotalHours < 24) parts.Add($"剩余 {eta:mm\\:ss}");
ProgressText = string.Join(" · ", parts);
CurrentItem = Job.CurrentItem ?? string.Empty;
if (!string.IsNullOrEmpty(Job.Error)) CurrentItem = Job.Error!;
Progress = Job.Progress;
IsIndeterminate = Job.IsIndeterminate;
CanPause = Job.CanPause;
CanCancel = Job.CanCancel;
IsFinished = Job.IsFinished;
PauseGlyph = Job.State == JobState.Paused ? "\uE768" : "\uE769";
}
}