using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; using System.Reactive.Disposables; using System.Threading; using System.Threading.Tasks; using Artemis.Core; using Artemis.UI.Shared; using ReactiveUI; namespace Artemis.UI.Screens.Plugins.Prerequisites; public class PluginPrerequisiteViewModel : ActivatableViewModelBase { private readonly ObservableAsPropertyHelper _activeStepNumber; private readonly ObservableAsPropertyHelper _busy; private readonly bool _uninstall; private PluginPrerequisiteActionViewModel? _activeAction; private bool _installing; private bool _isMet; private bool _uninstalling; public PluginPrerequisiteViewModel(PluginPrerequisite pluginPrerequisite, bool uninstall) { _uninstall = uninstall; PluginPrerequisite = pluginPrerequisite; Actions = new ObservableCollection(!_uninstall ? PluginPrerequisite.InstallActions.Select(a => new PluginPrerequisiteActionViewModel(a)) : PluginPrerequisite.UninstallActions.Select(a => new PluginPrerequisiteActionViewModel(a))); _busy = this.WhenAnyValue(x => x.Installing, x => x.Uninstalling, (i, u) => i || u).ToProperty(this, x => x.Busy); _activeStepNumber = this.WhenAnyValue(x => x.ActiveAction, a => Actions.IndexOf(a!) + 1).ToProperty(this, x => x.ActiveStepNumber); this.WhenActivated(d => { PluginPrerequisite.PropertyChanged += PluginPrerequisiteOnPropertyChanged; Disposable.Create(() => PluginPrerequisite.PropertyChanged -= PluginPrerequisiteOnPropertyChanged).DisposeWith(d); }); // Could be slow so take it off of the UI thread Task.Run(() => IsMet = PluginPrerequisite.IsMet()); } public ObservableCollection Actions { get; } public PluginPrerequisiteActionViewModel? ActiveAction { get => _activeAction; set => RaiseAndSetIfChanged(ref _activeAction, value); } public PluginPrerequisite PluginPrerequisite { get; } public bool Installing { get => _installing; set => RaiseAndSetIfChanged(ref _installing, value); } public bool Uninstalling { get => _uninstalling; set => RaiseAndSetIfChanged(ref _uninstalling, value); } public bool IsMet { get => _isMet; set => RaiseAndSetIfChanged(ref _isMet, value); } public bool Busy => _busy.Value; public int ActiveStepNumber => _activeStepNumber.Value; public async Task Install(CancellationToken cancellationToken) { if (Busy) return; Installing = true; try { await PluginPrerequisite.Install(cancellationToken); } finally { Installing = false; IsMet = PluginPrerequisite.IsMet(); } } public async Task Uninstall(CancellationToken cancellationToken) { if (Busy) return; Uninstalling = true; try { await PluginPrerequisite.Uninstall(cancellationToken); } finally { Uninstalling = false; IsMet = PluginPrerequisite.IsMet(); } } private void PluginPrerequisiteOnPropertyChanged(object? sender, PropertyChangedEventArgs e) { if (e.PropertyName == nameof(PluginPrerequisite.CurrentAction)) ActivateCurrentAction(); } private void ActivateCurrentAction() { PluginPrerequisiteActionViewModel? activeAction = Actions.FirstOrDefault(i => i.Action == PluginPrerequisite.CurrentAction); if (activeAction == null) return; ActiveAction = activeAction; } }