using System; using System.ComponentModel; using System.Runtime.CompilerServices; using System.Windows; using System.Windows.Input; namespace EmbyToolbox.ViewModels; /// Компактный индикатор прогресса ffprobe-анализа батча файлов. public sealed class AnalysisProgressViewModel : INotifyPropertyChanged { private readonly Action _onCancel; private bool _isPanelVisible; private string _statusLine = string.Empty; private double _analysisPercent; private bool _canCancel = true; public AnalysisProgressViewModel(Action onCancel) { _onCancel = onCancel; CancelCommand = new RelayCommand(ExecuteCancel, () => _canCancel && _isPanelVisible); } public ICommand CancelCommand { get; } public bool IsPanelVisible { get => _isPanelVisible; private set { if (_isPanelVisible == value) { return; } _isPanelVisible = value; OnPropertyChanged(); OnPropertyChanged(nameof(PanelVisibility)); if (CancelCommand is RelayCommand rc) { rc.RaiseCanExecuteChanged(); } } } public Visibility PanelVisibility => _isPanelVisible ? Visibility.Visible : Visibility.Collapsed; public string StatusLine { get => _statusLine; private set { if (_statusLine == value) { return; } _statusLine = value; OnPropertyChanged(); } } public double AnalysisPercent { get => _analysisPercent; private set { if (Math.Abs(_analysisPercent - value) < 0.01) { return; } _analysisPercent = value; OnPropertyChanged(); } } public void StartBatch(int total) { _canCancel = true; IsPanelVisible = true; StatusLine = total > 0 ? $"Анализ файлов: 0 из {total}" : "Анализ файлов"; AnalysisPercent = 0; if (CancelCommand is RelayCommand rc) { rc.RaiseCanExecuteChanged(); } } public void OnProgress(EmbyToolbox.Services.QueueAnalysisProgress p) { if (p.Total <= 0) { return; } StatusLine = $"Анализ файлов: {p.Processed} из {p.Total}"; AnalysisPercent = 100.0 * p.Processed / p.Total; } public async Task FinalizeAndHideAsync(int errorCount) { _canCancel = false; if (CancelCommand is RelayCommand rc) { rc.RaiseCanExecuteChanged(); } if (errorCount > 0) { StatusLine = $"Анализ завершен с ошибками: {errorCount}"; AnalysisPercent = 100; await Task.Delay(2500).ConfigureAwait(true); } IsPanelVisible = false; } public event PropertyChangedEventHandler? PropertyChanged; private void ExecuteCancel() => _onCancel(); private void OnPropertyChanged([CallerMemberName] string? propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }