/ src / modules / imageresizer / ui / ViewModels / ProgressViewModel.cs
ProgressViewModel.cs
  1  #pragma warning disable IDE0073
  2  // Copyright (c) Brice Lambson
  3  // The Brice Lambson licenses this file to you under the MIT license.
  4  // See the LICENSE file in the project root for more information.  Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/
  5  #pragma warning restore IDE0073
  6  
  7  using System;
  8  using System.Diagnostics;
  9  using System.Linq;
 10  using System.Threading;
 11  using System.Threading.Tasks;
 12  using System.Windows.Input;
 13  
 14  using ImageResizer.Helpers;
 15  using ImageResizer.Models;
 16  using ImageResizer.Views;
 17  
 18  namespace ImageResizer.ViewModels
 19  {
 20      public class ProgressViewModel : Observable, IDisposable
 21      {
 22          private readonly MainViewModel _mainViewModel;
 23          private readonly ResizeBatch _batch;
 24          private readonly IMainView _mainView;
 25          private readonly Stopwatch _stopwatch = new Stopwatch();
 26          private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
 27  
 28          private double _progress;
 29          private TimeSpan _timeRemaining;
 30          private bool disposedValue;
 31  
 32          public ProgressViewModel(
 33              ResizeBatch batch,
 34              MainViewModel mainViewModel,
 35              IMainView mainView)
 36          {
 37              _batch = batch;
 38              _mainViewModel = mainViewModel;
 39              _mainView = mainView;
 40  
 41              StartCommand = new RelayCommand(Start);
 42              StopCommand = new RelayCommand(Stop);
 43          }
 44  
 45          public double Progress
 46          {
 47              get => _progress;
 48              set => Set(ref _progress, value);
 49          }
 50  
 51          public TimeSpan TimeRemaining
 52          {
 53              get => _timeRemaining;
 54              set => Set(ref _timeRemaining, value);
 55          }
 56  
 57          public ICommand StartCommand { get; }
 58  
 59          public ICommand StopCommand { get; }
 60  
 61          public void Start()
 62          {
 63              _ = Task.Factory.StartNew(StartExecutingWork, _cancellationTokenSource.Token, TaskCreationOptions.None, TaskScheduler.Current);
 64          }
 65  
 66          private void StartExecutingWork()
 67          {
 68              _stopwatch.Restart();
 69              var errors = _batch.Process(
 70                  (completed, total) =>
 71                  {
 72                      var progress = completed / total;
 73                      Progress = progress;
 74                      _mainViewModel.Progress = progress;
 75  
 76                      TimeRemaining = _stopwatch.Elapsed.Multiply((total - completed) / completed);
 77                  },
 78                  _cancellationTokenSource.Token);
 79  
 80              if (errors.Any())
 81              {
 82                  _mainViewModel.Progress = 0;
 83                  _mainViewModel.CurrentPage = new ResultsViewModel(_mainView, errors);
 84              }
 85              else
 86              {
 87                  _mainView.Close();
 88              }
 89          }
 90  
 91          public void Stop()
 92          {
 93              _cancellationTokenSource.Cancel();
 94              _mainView.Close();
 95          }
 96  
 97          protected virtual void Dispose(bool disposing)
 98          {
 99              if (!disposedValue)
100              {
101                  if (disposing)
102                  {
103                      _cancellationTokenSource.Dispose();
104                  }
105  
106                  disposedValue = true;
107              }
108          }
109  
110          public void Dispose()
111          {
112              // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
113              Dispose(disposing: true);
114              GC.SuppressFinalize(this);
115          }
116      }
117  }