mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-01-01 02:03:32 +00:00
UI - Implemented plugin feature VMs
This commit is contained in:
parent
8a7f8cff96
commit
c178fc6cf8
@ -76,15 +76,11 @@ namespace Artemis.UI.Avalonia.Shared.Services.Builders
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ContentDialogBuilder WithViewModel<T>(params (string name, object value)[] parameters)
|
public ContentDialogBuilder WithViewModel<T>(ref T viewModel, params (string name, object value)[] parameters)
|
||||||
{
|
{
|
||||||
if (parameters.Length != 0)
|
IParameter[] paramsArray = parameters.Select(kv => new ConstructorArgument(kv.name, kv.value)).Cast<IParameter>().ToArray();
|
||||||
{
|
viewModel = _kernel.Get<T>(paramsArray);
|
||||||
IParameter[] paramsArray = parameters.Select(kv => new ConstructorArgument(kv.name, kv.value)).Cast<IParameter>().ToArray();
|
_contentDialog.Content = _kernel.Get<T>();
|
||||||
_contentDialog.Content = _kernel.Get<T>(paramsArray);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
_contentDialog.Content = _kernel.Get<T>();
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ using Artemis.UI.Avalonia.Shared.Utilities;
|
|||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
using FluentAvalonia.UI.Controls;
|
using FluentAvalonia.UI.Controls;
|
||||||
|
using ReactiveUI;
|
||||||
using Button = Avalonia.Controls.Button;
|
using Button = Avalonia.Controls.Button;
|
||||||
|
|
||||||
namespace Artemis.UI.Avalonia.Shared.Services.Builders
|
namespace Artemis.UI.Avalonia.Shared.Services.Builders
|
||||||
@ -106,7 +107,7 @@ namespace Artemis.UI.Avalonia.Shared.Services.Builders
|
|||||||
public IControl Build()
|
public IControl Build()
|
||||||
{
|
{
|
||||||
return _action != null
|
return _action != null
|
||||||
? new Button {Content = _text, Command = new DelegateCommand(_ => _action())}
|
? new Button {Content = _text, Command = ReactiveCommand.Create(() => _action)}
|
||||||
: new Button {Content = _text};
|
: new Button {Content = _text};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,11 +8,11 @@ namespace Artemis.UI.Avalonia.Shared.Services.Interfaces
|
|||||||
public interface IWindowService : IArtemisSharedUIService
|
public interface IWindowService : IArtemisSharedUIService
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a view model instance of type <typeparamref name="T" /> and shows its corresponding View as a window
|
/// Creates a view model instance of type <typeparamref name="TViewModel" /> and shows its corresponding View as a window
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">The type of view model to create</typeparam>
|
/// <typeparam name="TViewModel">The type of view model to create</typeparam>
|
||||||
/// <returns>The created view model</returns>
|
/// <returns>The created view model</returns>
|
||||||
T ShowWindow<T>();
|
TViewModel ShowWindow<TViewModel>(params (string name, object value)[] parameters);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Given a ViewModel, show its corresponding View as a window
|
/// Given a ViewModel, show its corresponding View as a window
|
||||||
@ -28,12 +28,20 @@ namespace Artemis.UI.Avalonia.Shared.Services.Interfaces
|
|||||||
void ShowExceptionDialog(string title, Exception exception);
|
void ShowExceptionDialog(string title, Exception exception);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Given a ViewModel, show its corresponding View as a Dialog
|
/// Given an existing ViewModel, show its corresponding View as a Dialog
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">The return type</typeparam>
|
/// <typeparam name="TResult">The return type</typeparam>
|
||||||
/// <param name="viewModel">ViewModel to show the View for</param>
|
/// <param name="viewModel">ViewModel to show the View for</param>
|
||||||
/// <returns>A task containing the return value of type <typeparamref name="T" /></returns>
|
/// <returns>A task containing the return value of type <typeparamref name="TResult" /></returns>
|
||||||
Task<T> ShowDialogAsync<T>(object viewModel);
|
Task<TResult> ShowDialogAsync<TResult>(DialogViewModelBase<TResult> viewModel);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a view model instance of type <typeparamref name="TViewModel"/> and shows its corresponding View as a Dialog
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TViewModel">The view model type</typeparam>
|
||||||
|
/// <typeparam name="TResult">The return type</typeparam>
|
||||||
|
/// <returns>A task containing the return value of type <typeparamref name="TResult" /></returns>
|
||||||
|
Task<TResult> ShowDialogAsync<TViewModel, TResult>(params (string name, object value)[] parameters) where TViewModel : DialogViewModelBase<TResult>;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates an open file dialog, use the fluent API to configure it
|
/// Creates an open file dialog, use the fluent API to configure it
|
||||||
@ -49,6 +57,8 @@ namespace Artemis.UI.Avalonia.Shared.Services.Interfaces
|
|||||||
|
|
||||||
ContentDialogBuilder CreateContentDialog();
|
ContentDialogBuilder CreateContentDialog();
|
||||||
|
|
||||||
|
ConfirmDialogBuilder CreateConfirmDialog();
|
||||||
|
|
||||||
Window GetCurrentWindow();
|
Window GetCurrentWindow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Artemis.UI.Avalonia.Shared.Services
|
namespace Artemis.UI.Avalonia.Shared.Services
|
||||||
{
|
{
|
||||||
public class ExceptionDialogViewModel : ActivatableViewModelBase
|
public class ExceptionDialogViewModel : DialogViewModelBase<object>
|
||||||
{
|
{
|
||||||
public ExceptionDialogViewModel(string title, Exception exception)
|
public ExceptionDialogViewModel(string title, Exception exception)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -8,6 +8,7 @@ using Avalonia;
|
|||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Controls.ApplicationLifetimes;
|
using Avalonia.Controls.ApplicationLifetimes;
|
||||||
using Ninject;
|
using Ninject;
|
||||||
|
using Ninject.Parameters;
|
||||||
|
|
||||||
namespace Artemis.UI.Avalonia.Shared.Services
|
namespace Artemis.UI.Avalonia.Shared.Services
|
||||||
{
|
{
|
||||||
@ -21,9 +22,10 @@ namespace Artemis.UI.Avalonia.Shared.Services
|
|||||||
_kernel = kernel;
|
_kernel = kernel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T ShowWindow<T>()
|
public T ShowWindow<T>(params (string name, object value)[] parameters)
|
||||||
{
|
{
|
||||||
T viewModel = _kernel.Get<T>()!;
|
IParameter[] paramsArray = parameters.Select(kv => new ConstructorArgument(kv.name, kv.value)).Cast<IParameter>().ToArray();
|
||||||
|
T viewModel = _kernel.Get<T>(paramsArray)!;
|
||||||
ShowWindow(viewModel);
|
ShowWindow(viewModel);
|
||||||
return viewModel;
|
return viewModel;
|
||||||
}
|
}
|
||||||
@ -34,49 +36,69 @@ namespace Artemis.UI.Avalonia.Shared.Services
|
|||||||
Type? type = viewModel.GetType().Assembly.GetType(name);
|
Type? type = viewModel.GetType().Assembly.GetType(name);
|
||||||
|
|
||||||
if (type == null)
|
if (type == null)
|
||||||
|
{
|
||||||
throw new ArtemisSharedUIException($"Failed to find a window named {name}.");
|
throw new ArtemisSharedUIException($"Failed to find a window named {name}.");
|
||||||
|
}
|
||||||
|
|
||||||
if (!type.IsAssignableTo(typeof(Window)))
|
if (!type.IsAssignableTo(typeof(Window)))
|
||||||
|
{
|
||||||
throw new ArtemisSharedUIException($"Type {name} is not a window.");
|
throw new ArtemisSharedUIException($"Type {name} is not a window.");
|
||||||
|
}
|
||||||
|
|
||||||
Window window = (Window) Activator.CreateInstance(type)!;
|
Window window = (Window) Activator.CreateInstance(type)!;
|
||||||
window.DataContext = viewModel;
|
window.DataContext = viewModel;
|
||||||
window.Show();
|
window.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
public async Task<TResult> ShowDialogAsync<TViewModel, TResult>(params (string name, object value)[] parameters) where TViewModel : DialogViewModelBase<TResult>
|
||||||
public void ShowExceptionDialog(string title, Exception exception)
|
|
||||||
{
|
{
|
||||||
if (_exceptionDialogOpen)
|
IParameter[] paramsArray = parameters.Select(kv => new ConstructorArgument(kv.name, kv.value)).Cast<IParameter>().ToArray();
|
||||||
return;
|
TViewModel viewModel = _kernel.Get<TViewModel>(paramsArray)!;
|
||||||
|
return await ShowDialogAsync(viewModel);
|
||||||
try
|
|
||||||
{
|
|
||||||
_exceptionDialogOpen = true;
|
|
||||||
ShowDialogAsync<object>(new ExceptionDialogViewModel(title, exception)).GetAwaiter().GetResult();
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
_exceptionDialogOpen = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<T> ShowDialogAsync<T>(object viewModel)
|
public async Task<TResult> ShowDialogAsync<TResult>(DialogViewModelBase<TResult> viewModel)
|
||||||
{
|
{
|
||||||
if (Application.Current.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime classic)
|
if (Application.Current.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime classic)
|
||||||
throw new ArtemisSharedUIException($"Can't show a dialog when application lifetime is not IClassicDesktopStyleApplicationLifetime.");
|
{
|
||||||
|
throw new ArtemisSharedUIException("Can't show a dialog when application lifetime is not IClassicDesktopStyleApplicationLifetime.");
|
||||||
|
}
|
||||||
|
|
||||||
string name = viewModel.GetType().FullName!.Split('`')[0].Replace("ViewModel", "View");
|
string name = viewModel.GetType().FullName!.Split('`')[0].Replace("ViewModel", "View");
|
||||||
Type? type = viewModel.GetType().Assembly.GetType(name);
|
Type? type = viewModel.GetType().Assembly.GetType(name);
|
||||||
|
|
||||||
if (type == null)
|
if (type == null)
|
||||||
|
{
|
||||||
throw new ArtemisSharedUIException($"Failed to find a window named {name}.");
|
throw new ArtemisSharedUIException($"Failed to find a window named {name}.");
|
||||||
|
}
|
||||||
|
|
||||||
if (!type.IsAssignableTo(typeof(Window)))
|
if (!type.IsAssignableTo(typeof(Window)))
|
||||||
|
{
|
||||||
throw new ArtemisSharedUIException($"Type {name} is not a window.");
|
throw new ArtemisSharedUIException($"Type {name} is not a window.");
|
||||||
|
}
|
||||||
|
|
||||||
Window window = (Window) Activator.CreateInstance(type)!;
|
Window window = (Window) Activator.CreateInstance(type)!;
|
||||||
window.DataContext = viewModel;
|
window.DataContext = viewModel;
|
||||||
Window parent = classic.Windows.FirstOrDefault(w => w.IsActive) ?? classic.MainWindow;
|
Window parent = classic.Windows.FirstOrDefault(w => w.IsActive) ?? classic.MainWindow;
|
||||||
return await window.ShowDialog<T>(parent);
|
return await window.ShowDialog<TResult>(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ShowExceptionDialog(string title, Exception exception)
|
||||||
|
{
|
||||||
|
if (_exceptionDialogOpen)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_exceptionDialogOpen = true;
|
||||||
|
ShowDialogAsync(new ExceptionDialogViewModel(title, exception)).GetAwaiter().GetResult();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_exceptionDialogOpen = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ContentDialogBuilder CreateContentDialog()
|
public ContentDialogBuilder CreateContentDialog()
|
||||||
@ -97,7 +119,9 @@ namespace Artemis.UI.Avalonia.Shared.Services
|
|||||||
public Window GetCurrentWindow()
|
public Window GetCurrentWindow()
|
||||||
{
|
{
|
||||||
if (Application.Current.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime classic)
|
if (Application.Current.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime classic)
|
||||||
|
{
|
||||||
throw new ArtemisSharedUIException("Can't show a dialog when application lifetime is not IClassicDesktopStyleApplicationLifetime.");
|
throw new ArtemisSharedUIException("Can't show a dialog when application lifetime is not IClassicDesktopStyleApplicationLifetime.");
|
||||||
|
}
|
||||||
|
|
||||||
Window parent = classic.Windows.FirstOrDefault(w => w.IsActive) ?? classic.MainWindow;
|
Window parent = classic.Windows.FirstOrDefault(w => w.IsActive) ?? classic.MainWindow;
|
||||||
return parent;
|
return parent;
|
||||||
|
|||||||
@ -1,60 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Windows.Input;
|
|
||||||
|
|
||||||
namespace Artemis.UI.Avalonia.Shared.Utilities
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Provides a command that simply calls a delegate when invoked
|
|
||||||
/// </summary>
|
|
||||||
public class DelegateCommand : ICommand
|
|
||||||
{
|
|
||||||
private readonly Predicate<object?>? _canExecute;
|
|
||||||
private readonly Action<object?> _execute;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a new instance of the <see cref="DelegateCommand" /> class
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="execute">The delegate to execute</param>
|
|
||||||
public DelegateCommand(Action<object?> execute) : this(execute, null)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a new instance of the <see cref="DelegateCommand" /> class with a predicate indicating whether the command
|
|
||||||
/// can be executed
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="execute">The delegate to execute</param>
|
|
||||||
/// <param name="canExecute">The predicate that determines whether the command can execute</param>
|
|
||||||
public DelegateCommand(Action<object?> execute, Predicate<object?>? canExecute)
|
|
||||||
{
|
|
||||||
_execute = execute;
|
|
||||||
_canExecute = canExecute;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Invokes the <see cref="CanExecuteChanged" /> event
|
|
||||||
/// </summary>
|
|
||||||
public void RaiseCanExecuteChanged()
|
|
||||||
{
|
|
||||||
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public event EventHandler? CanExecuteChanged;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public bool CanExecute(object? parameter)
|
|
||||||
{
|
|
||||||
if (_canExecute == null)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return _canExecute(parameter);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void Execute(object? parameter)
|
|
||||||
{
|
|
||||||
_execute(parameter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -6,14 +6,14 @@ using ReactiveUI;
|
|||||||
namespace Artemis.UI.Avalonia.Shared
|
namespace Artemis.UI.Avalonia.Shared
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents the base class for Artemis view models
|
/// Represents the base class for Artemis view models
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class ViewModelBase : ReactiveObject
|
public abstract class ViewModelBase : ReactiveObject
|
||||||
{
|
{
|
||||||
private string? _displayName;
|
private string? _displayName;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the display name of the view model
|
/// Gets or sets the display name of the view model
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? DisplayName
|
public string? DisplayName
|
||||||
{
|
{
|
||||||
@ -23,7 +23,7 @@ namespace Artemis.UI.Avalonia.Shared
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents the base class for Artemis view models that are interested in the activated event
|
/// Represents the base class for Artemis view models that are interested in the activated event
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class ActivatableViewModelBase : ViewModelBase, IActivatableViewModel, IDisposable
|
public abstract class ActivatableViewModelBase : ViewModelBase, IActivatableViewModel, IDisposable
|
||||||
{
|
{
|
||||||
@ -34,17 +34,14 @@ namespace Artemis.UI.Avalonia.Shared
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Releases the unmanaged resources used by the object and optionally releases the managed resources.
|
/// Releases the unmanaged resources used by the object and optionally releases the managed resources.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="disposing">
|
/// <param name="disposing">
|
||||||
/// <see langword="true" /> to release both managed and unmanaged resources;
|
/// <see langword="true" /> to release both managed and unmanaged resources;
|
||||||
/// <see langword="false" /> to release only unmanaged resources.
|
/// <see langword="false" /> to release only unmanaged resources.
|
||||||
/// </param>
|
/// </param>
|
||||||
protected virtual void Dispose(bool disposing)
|
protected virtual void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (disposing)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@ -59,11 +56,10 @@ namespace Artemis.UI.Avalonia.Shared
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents the base class for Artemis view models used to drive dialogs
|
/// Represents the base class for Artemis view models used to drive dialogs
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class DialogViewModelBase<TResult> : ActivatableViewModelBase
|
public abstract class DialogViewModelBase<TResult> : ActivatableViewModelBase
|
||||||
{
|
{
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected DialogViewModelBase()
|
protected DialogViewModelBase()
|
||||||
{
|
{
|
||||||
@ -71,9 +67,8 @@ namespace Artemis.UI.Avalonia.Shared
|
|||||||
Cancel = ReactiveCommand.Create(() => { });
|
Cancel = ReactiveCommand.Create(() => { });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Closes the dialog with a given result
|
/// Closes the dialog with a given result
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ReactiveCommand<TResult, TResult> Close { get; }
|
public ReactiveCommand<TResult, TResult> Close { get; }
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.UI.Avalonia.Screens.Device;
|
using Artemis.UI.Avalonia.Screens.Device;
|
||||||
using Artemis.UI.Avalonia.Screens.Device.Tabs.ViewModels;
|
using Artemis.UI.Avalonia.Screens.Device.Tabs.ViewModels;
|
||||||
|
using Artemis.UI.Avalonia.Screens.Plugins.ViewModels;
|
||||||
using Artemis.UI.Avalonia.Screens.Root.ViewModels;
|
using Artemis.UI.Avalonia.Screens.Root.ViewModels;
|
||||||
using Artemis.UI.Avalonia.Screens.SurfaceEditor.ViewModels;
|
using Artemis.UI.Avalonia.Screens.SurfaceEditor.ViewModels;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
@ -33,4 +34,9 @@ namespace Artemis.UI.Avalonia.Ninject.Factories
|
|||||||
SurfaceDeviceViewModel SurfaceDeviceViewModel(ArtemisDevice device);
|
SurfaceDeviceViewModel SurfaceDeviceViewModel(ArtemisDevice device);
|
||||||
ListDeviceViewModel ListDeviceViewModel(ArtemisDevice device);
|
ListDeviceViewModel ListDeviceViewModel(ArtemisDevice device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface IPrerequisitesVmFactory : IVmFactory
|
||||||
|
{
|
||||||
|
PluginPrerequisiteViewModel PluginPrerequisiteViewModel(PluginPrerequisite pluginPrerequisite, bool uninstall);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -6,11 +6,12 @@ using System.Linq;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.Core.Services;
|
using Artemis.Core.Services;
|
||||||
|
using Artemis.UI.Avalonia.Shared;
|
||||||
using Artemis.UI.Avalonia.Shared.Services.Builders;
|
using Artemis.UI.Avalonia.Shared.Services.Builders;
|
||||||
using Artemis.UI.Avalonia.Shared.Services.Interfaces;
|
using Artemis.UI.Avalonia.Shared.Services.Interfaces;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
|
|
||||||
namespace Artemis.UI.Avalonia.Screens.Settings.Tabs.Plugins.ViewModels
|
namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||||
{
|
{
|
||||||
public class PluginFeatureViewModel : ActivatableViewModelBase
|
public class PluginFeatureViewModel : ActivatableViewModelBase
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,10 +1,7 @@
|
|||||||
using System;
|
using Artemis.Core;
|
||||||
using System.ComponentModel;
|
|
||||||
using Artemis.Core;
|
|
||||||
using Artemis.UI.Avalonia;
|
|
||||||
using Artemis.UI.Avalonia.Shared;
|
using Artemis.UI.Avalonia.Shared;
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.Plugins
|
namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||||
{
|
{
|
||||||
public class PluginPrerequisiteActionViewModel : ViewModelBase
|
public class PluginPrerequisiteActionViewModel : ViewModelBase
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,26 +1,51 @@
|
|||||||
using System;
|
using System.Collections.ObjectModel;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.Core.Services;
|
using Artemis.UI.Avalonia.Shared;
|
||||||
using Artemis.UI.Shared.Services;
|
using DynamicData;
|
||||||
using Stylet;
|
using ReactiveUI;
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.Plugins
|
namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||||
{
|
{
|
||||||
public class PluginPrerequisiteViewModel : Conductor<PluginPrerequisiteActionViewModel>.Collection.OneActive
|
public class PluginPrerequisiteViewModel : ActivatableViewModelBase
|
||||||
{
|
{
|
||||||
private readonly bool _uninstall;
|
private readonly bool _uninstall;
|
||||||
|
private readonly ObservableAsPropertyHelper<bool> _busy;
|
||||||
|
private readonly ObservableAsPropertyHelper<int> _activeStepNumber;
|
||||||
|
|
||||||
private bool _installing;
|
private bool _installing;
|
||||||
private bool _uninstalling;
|
private bool _uninstalling;
|
||||||
private bool _isMet;
|
private bool _isMet;
|
||||||
|
|
||||||
|
private PluginPrerequisiteActionViewModel? _activeAction;
|
||||||
|
|
||||||
public PluginPrerequisiteViewModel(PluginPrerequisite pluginPrerequisite, bool uninstall)
|
public PluginPrerequisiteViewModel(PluginPrerequisite pluginPrerequisite, bool uninstall)
|
||||||
{
|
{
|
||||||
_uninstall = uninstall;
|
_uninstall = uninstall;
|
||||||
|
|
||||||
PluginPrerequisite = pluginPrerequisite;
|
PluginPrerequisite = pluginPrerequisite;
|
||||||
|
Actions = new ObservableCollection<PluginPrerequisiteActionViewModel>(!_uninstall
|
||||||
|
? PluginPrerequisite.InstallActions.Select(a => new PluginPrerequisiteActionViewModel(a))
|
||||||
|
: PluginPrerequisite.UninstallActions.Select(a => new PluginPrerequisiteActionViewModel(a)));
|
||||||
|
|
||||||
|
this.WhenAnyValue(x => x.Installing, x => x.Uninstalling, (i, u) => i || u).ToProperty(this, x => x.Busy, out _busy);
|
||||||
|
this.WhenAnyValue(x => x.ActiveAction, a => Actions.IndexOf(a)).ToProperty(this, x => x.ActiveStepNumber, out _activeStepNumber);
|
||||||
|
|
||||||
|
PluginPrerequisite.PropertyChanged += PluginPrerequisiteOnPropertyChanged;
|
||||||
|
|
||||||
|
// Could be slow so take it off of the UI thread
|
||||||
|
Task.Run(() => IsMet = PluginPrerequisite.IsMet());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableCollection<PluginPrerequisiteActionViewModel> Actions { get; }
|
||||||
|
|
||||||
|
public PluginPrerequisiteActionViewModel? ActiveAction
|
||||||
|
{
|
||||||
|
get => _activeAction;
|
||||||
|
set => this.RaiseAndSetIfChanged(ref _activeAction , value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PluginPrerequisite PluginPrerequisite { get; }
|
public PluginPrerequisite PluginPrerequisite { get; }
|
||||||
@ -28,32 +53,24 @@ namespace Artemis.UI.Screens.Plugins
|
|||||||
public bool Installing
|
public bool Installing
|
||||||
{
|
{
|
||||||
get => _installing;
|
get => _installing;
|
||||||
set
|
set => this.RaiseAndSetIfChanged(ref _installing, value);
|
||||||
{
|
|
||||||
SetAndNotify(ref _installing, value);
|
|
||||||
NotifyOfPropertyChange(nameof(Busy));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Uninstalling
|
public bool Uninstalling
|
||||||
{
|
{
|
||||||
get => _uninstalling;
|
get => _uninstalling;
|
||||||
set
|
set => this.RaiseAndSetIfChanged(ref _uninstalling, value);
|
||||||
{
|
|
||||||
SetAndNotify(ref _uninstalling, value);
|
|
||||||
NotifyOfPropertyChange(nameof(Busy));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsMet
|
public bool IsMet
|
||||||
{
|
{
|
||||||
get => _isMet;
|
get => _isMet;
|
||||||
set => SetAndNotify(ref _isMet, value);
|
set => this.RaiseAndSetIfChanged(ref _isMet, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Busy => Installing || Uninstalling;
|
public bool Busy => _busy.Value;
|
||||||
public int ActiveStemNumber => Items.IndexOf(ActiveItem) + 1;
|
public int ActiveStepNumber => _activeStepNumber.Value;
|
||||||
public bool HasMultipleActions => Items.Count > 1;
|
public bool HasMultipleActions => Actions.Count > 1;
|
||||||
|
|
||||||
public async Task Install(CancellationToken cancellationToken)
|
public async Task Install(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
@ -89,7 +106,7 @@ namespace Artemis.UI.Screens.Plugins
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PluginPrerequisiteOnPropertyChanged(object sender, PropertyChangedEventArgs e)
|
private void PluginPrerequisiteOnPropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.PropertyName == nameof(PluginPrerequisite.CurrentAction))
|
if (e.PropertyName == nameof(PluginPrerequisite.CurrentAction))
|
||||||
ActivateCurrentAction();
|
ActivateCurrentAction();
|
||||||
@ -97,37 +114,27 @@ namespace Artemis.UI.Screens.Plugins
|
|||||||
|
|
||||||
private void ActivateCurrentAction()
|
private void ActivateCurrentAction()
|
||||||
{
|
{
|
||||||
PluginPrerequisiteActionViewModel newActiveItem = Items.FirstOrDefault(i => i.Action == PluginPrerequisite.CurrentAction);
|
PluginPrerequisiteActionViewModel? activeAction = Actions.FirstOrDefault(i => i.Action == PluginPrerequisite.CurrentAction);
|
||||||
if (newActiveItem == null)
|
if (activeAction == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ActiveItem = newActiveItem;
|
ActiveAction = activeAction;
|
||||||
NotifyOfPropertyChange(nameof(ActiveStemNumber));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Overrides of Screen
|
#region IDisposable
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void OnClose()
|
protected override void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
PluginPrerequisite.PropertyChanged -= PluginPrerequisiteOnPropertyChanged;
|
if (disposing)
|
||||||
base.OnClose();
|
{
|
||||||
}
|
PluginPrerequisite.PropertyChanged -= PluginPrerequisiteOnPropertyChanged;
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
base.Dispose(disposing);
|
||||||
protected override void OnInitialActivate()
|
|
||||||
{
|
|
||||||
PluginPrerequisite.PropertyChanged += PluginPrerequisiteOnPropertyChanged;
|
|
||||||
// Could be slow so take it off of the UI thread
|
|
||||||
Task.Run(() => IsMet = PluginPrerequisite.IsMet());
|
|
||||||
|
|
||||||
Items.AddRange(!_uninstall
|
|
||||||
? PluginPrerequisite.InstallActions.Select(a => new PluginPrerequisiteActionViewModel(a))
|
|
||||||
: PluginPrerequisite.UninstallActions.Select(a => new PluginPrerequisiteActionViewModel(a)));
|
|
||||||
|
|
||||||
base.OnInitialActivate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5,10 +5,12 @@ using System.Linq;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
|
using Artemis.UI.Avalonia.Ninject.Factories;
|
||||||
using Artemis.UI.Avalonia.Shared;
|
using Artemis.UI.Avalonia.Shared;
|
||||||
|
using Artemis.UI.Avalonia.Shared.Services.Interfaces;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.Plugins
|
namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||||
{
|
{
|
||||||
public class PluginPrerequisitesInstallDialogViewModel : DialogViewModelBase<bool>
|
public class PluginPrerequisitesInstallDialogViewModel : DialogViewModelBase<bool>
|
||||||
{
|
{
|
||||||
@ -20,14 +22,14 @@ namespace Artemis.UI.Screens.Plugins
|
|||||||
private bool _showProgress;
|
private bool _showProgress;
|
||||||
private CancellationTokenSource? _tokenSource;
|
private CancellationTokenSource? _tokenSource;
|
||||||
|
|
||||||
public PluginPrerequisitesInstallDialogViewModel(List<IPrerequisitesSubject> subjects, IPrerequisitesVmFactory prerequisitesVmFactory, IDialogService dialogService)
|
public PluginPrerequisitesInstallDialogViewModel(List<IPrerequisitesSubject> subjects, IPrerequisitesVmFactory prerequisitesVmFactory)
|
||||||
{
|
{
|
||||||
Prerequisites = new ObservableCollection<PluginPrerequisiteViewModel>();
|
Prerequisites = new ObservableCollection<PluginPrerequisiteViewModel>();
|
||||||
foreach (IPrerequisitesSubject prerequisitesSubject in subjects)
|
foreach (PluginPrerequisite prerequisite in subjects.SelectMany(prerequisitesSubject => prerequisitesSubject.Prerequisites))
|
||||||
Prerequisites.AddRange(prerequisitesSubject.Prerequisites.Select(p => prerequisitesVmFactory.PluginPrerequisiteViewModel(p, false)));
|
Prerequisites.Add(prerequisitesVmFactory.PluginPrerequisiteViewModel(prerequisite, false));
|
||||||
|
|
||||||
foreach (PluginPrerequisiteViewModel pluginPrerequisiteViewModel in Prerequisites)
|
CanInstall = false;
|
||||||
pluginPrerequisiteViewModel.ConductWith(this);
|
Task.Run(() => CanInstall = Prerequisites.Any(p => !p.PluginPrerequisite.IsMet()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObservableCollection<PluginPrerequisiteViewModel> Prerequisites { get; }
|
public ObservableCollection<PluginPrerequisiteViewModel> Prerequisites { get; }
|
||||||
@ -68,7 +70,7 @@ namespace Artemis.UI.Screens.Plugins
|
|||||||
set => this.RaiseAndSetIfChanged(ref _canInstall, value);
|
set => this.RaiseAndSetIfChanged(ref _canInstall, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void Install()
|
public async Task Install()
|
||||||
{
|
{
|
||||||
CanInstall = false;
|
CanInstall = false;
|
||||||
ShowFailed = false;
|
ShowFailed = false;
|
||||||
@ -116,13 +118,12 @@ namespace Artemis.UI.Screens.Plugins
|
|||||||
|
|
||||||
public void Accept()
|
public void Accept()
|
||||||
{
|
{
|
||||||
Result = true;
|
Close.Execute(true);
|
||||||
Close.Execute();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Task<object> Show(IDialogService dialogService, List<IPrerequisitesSubject> subjects)
|
public static async Task<bool> Show(IWindowService windowService, List<IPrerequisitesSubject> subjects)
|
||||||
{
|
{
|
||||||
return dialogService.ShowDialog<PluginPrerequisitesInstallDialogViewModel>(new Dictionary<string, object> {{"subjects", subjects}});
|
return await windowService.ShowDialogAsync<PluginPrerequisitesInstallDialogViewModel, bool>(("subjects", subjects));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@ -136,18 +137,5 @@ namespace Artemis.UI.Screens.Plugins
|
|||||||
|
|
||||||
base.Dispose(disposing);
|
base.Dispose(disposing);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Overrides of Screen
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void OnInitialActivate()
|
|
||||||
{
|
|
||||||
CanInstall = false;
|
|
||||||
Task.Run(() => CanInstall = Prerequisites.Any(p => !p.PluginPrerequisite.IsMet()));
|
|
||||||
|
|
||||||
base.OnInitialActivate();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,76 +1,79 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.Core.Services;
|
using Artemis.Core.Services;
|
||||||
using Artemis.UI.Ninject.Factories;
|
using Artemis.UI.Avalonia.Ninject.Factories;
|
||||||
using Artemis.UI.Shared.Services;
|
using Artemis.UI.Avalonia.Shared;
|
||||||
using MaterialDesignThemes.Wpf;
|
using Artemis.UI.Avalonia.Shared.Services.Interfaces;
|
||||||
using Stylet;
|
using DynamicData;
|
||||||
|
using ReactiveUI;
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.Plugins
|
namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||||
{
|
{
|
||||||
public class PluginPrerequisitesUninstallDialogViewModel : DialogViewModelBase
|
public class PluginPrerequisitesUninstallDialogViewModel : DialogViewModelBase<bool>
|
||||||
{
|
{
|
||||||
private readonly IDialogService _dialogService;
|
|
||||||
private readonly IPluginManagementService _pluginManagementService;
|
private readonly IPluginManagementService _pluginManagementService;
|
||||||
private readonly List<IPrerequisitesSubject> _subjects;
|
private readonly List<IPrerequisitesSubject> _subjects;
|
||||||
private PluginPrerequisiteViewModel _activePrerequisite;
|
private readonly IWindowService _windowService;
|
||||||
private bool _canUninstall;
|
private bool _canUninstall;
|
||||||
private bool _isFinished;
|
private bool _isFinished;
|
||||||
private CancellationTokenSource _tokenSource;
|
private PluginPrerequisiteViewModel? _activePrerequisite;
|
||||||
|
private CancellationTokenSource? _tokenSource;
|
||||||
|
|
||||||
public PluginPrerequisitesUninstallDialogViewModel(List<IPrerequisitesSubject> subjects, string cancelLabel, IPrerequisitesVmFactory prerequisitesVmFactory,
|
public PluginPrerequisitesUninstallDialogViewModel(List<IPrerequisitesSubject> subjects, string cancelLabel, IPrerequisitesVmFactory prerequisitesVmFactory, IWindowService windowService,
|
||||||
IDialogService dialogService, IPluginManagementService pluginManagementService)
|
IPluginManagementService pluginManagementService)
|
||||||
{
|
{
|
||||||
_subjects = subjects;
|
_subjects = subjects;
|
||||||
_dialogService = dialogService;
|
_windowService = windowService;
|
||||||
_pluginManagementService = pluginManagementService;
|
_pluginManagementService = pluginManagementService;
|
||||||
|
|
||||||
CancelLabel = cancelLabel;
|
CancelLabel = cancelLabel;
|
||||||
Prerequisites = new BindableCollection<PluginPrerequisiteViewModel>();
|
Prerequisites = new ObservableCollection<PluginPrerequisiteViewModel>();
|
||||||
foreach (IPrerequisitesSubject prerequisitesSubject in subjects)
|
foreach (PluginPrerequisite prerequisite in subjects.SelectMany(prerequisitesSubject => prerequisitesSubject.Prerequisites))
|
||||||
Prerequisites.AddRange(prerequisitesSubject.Prerequisites.Select(p => prerequisitesVmFactory.PluginPrerequisiteViewModel(p, true)));
|
Prerequisites.Add(prerequisitesVmFactory.PluginPrerequisiteViewModel(prerequisite, true));
|
||||||
|
|
||||||
foreach (PluginPrerequisiteViewModel pluginPrerequisiteViewModel in Prerequisites)
|
// Could be slow so take it off of the UI thread
|
||||||
pluginPrerequisiteViewModel.ConductWith(this);
|
Task.Run(() => CanUninstall = Prerequisites.Any(p => p.PluginPrerequisite.IsMet()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public string CancelLabel { get; }
|
public string CancelLabel { get; }
|
||||||
public BindableCollection<PluginPrerequisiteViewModel> Prerequisites { get; }
|
public ObservableCollection<PluginPrerequisiteViewModel> Prerequisites { get; }
|
||||||
|
|
||||||
public PluginPrerequisiteViewModel ActivePrerequisite
|
public PluginPrerequisiteViewModel? ActivePrerequisite
|
||||||
{
|
{
|
||||||
get => _activePrerequisite;
|
get => _activePrerequisite;
|
||||||
set => SetAndNotify(ref _activePrerequisite, value);
|
set => this.RaiseAndSetIfChanged(ref _activePrerequisite, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CanUninstall
|
public bool CanUninstall
|
||||||
{
|
{
|
||||||
get => _canUninstall;
|
get => _canUninstall;
|
||||||
set => SetAndNotify(ref _canUninstall, value);
|
set => this.RaiseAndSetIfChanged(ref _canUninstall, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsFinished
|
public bool IsFinished
|
||||||
{
|
{
|
||||||
get => _isFinished;
|
get => _isFinished;
|
||||||
set => SetAndNotify(ref _isFinished, value);
|
set => this.RaiseAndSetIfChanged(ref _isFinished, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Overrides of DialogViewModelBase
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void OnDialogClosed(object sender, DialogClosingEventArgs e)
|
protected override void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
_tokenSource?.Cancel();
|
if (disposing)
|
||||||
base.OnDialogClosed(sender, e);
|
{
|
||||||
|
_tokenSource?.Cancel();
|
||||||
|
_tokenSource?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
base.Dispose(disposing);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
public async Task Uninstall()
|
||||||
|
|
||||||
public async void Uninstall()
|
|
||||||
{
|
{
|
||||||
CanUninstall = false;
|
CanUninstall = false;
|
||||||
|
|
||||||
@ -78,20 +81,28 @@ namespace Artemis.UI.Screens.Plugins
|
|||||||
foreach (IPrerequisitesSubject prerequisitesSubject in _subjects)
|
foreach (IPrerequisitesSubject prerequisitesSubject in _subjects)
|
||||||
{
|
{
|
||||||
if (prerequisitesSubject is PluginInfo pluginInfo)
|
if (prerequisitesSubject is PluginInfo pluginInfo)
|
||||||
|
{
|
||||||
_pluginManagementService.DisablePlugin(pluginInfo.Plugin, true);
|
_pluginManagementService.DisablePlugin(pluginInfo.Plugin, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable all subjects that are features if still required
|
// Disable all subjects that are features if still required
|
||||||
foreach (IPrerequisitesSubject prerequisitesSubject in _subjects)
|
foreach (IPrerequisitesSubject prerequisitesSubject in _subjects)
|
||||||
{
|
{
|
||||||
if (prerequisitesSubject is not PluginFeatureInfo featureInfo)
|
if (prerequisitesSubject is not PluginFeatureInfo featureInfo)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Disable the parent plugin if the feature is AlwaysEnabled
|
// Disable the parent plugin if the feature is AlwaysEnabled
|
||||||
if (featureInfo.AlwaysEnabled)
|
if (featureInfo.AlwaysEnabled)
|
||||||
|
{
|
||||||
_pluginManagementService.DisablePlugin(featureInfo.Plugin, true);
|
_pluginManagementService.DisablePlugin(featureInfo.Plugin, true);
|
||||||
else if (featureInfo.Instance != null)
|
}
|
||||||
|
else if (featureInfo.Instance != null)
|
||||||
|
{
|
||||||
_pluginManagementService.DisablePluginFeature(featureInfo.Instance, true);
|
_pluginManagementService.DisablePluginFeature(featureInfo.Instance, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_tokenSource = new CancellationTokenSource();
|
_tokenSource = new CancellationTokenSource();
|
||||||
@ -102,14 +113,18 @@ namespace Artemis.UI.Screens.Plugins
|
|||||||
{
|
{
|
||||||
pluginPrerequisiteViewModel.IsMet = pluginPrerequisiteViewModel.PluginPrerequisite.IsMet();
|
pluginPrerequisiteViewModel.IsMet = pluginPrerequisiteViewModel.PluginPrerequisite.IsMet();
|
||||||
if (!pluginPrerequisiteViewModel.IsMet)
|
if (!pluginPrerequisiteViewModel.IsMet)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
ActivePrerequisite = pluginPrerequisiteViewModel;
|
ActivePrerequisite = pluginPrerequisiteViewModel;
|
||||||
await ActivePrerequisite.Uninstall(_tokenSource.Token);
|
await ActivePrerequisite.Uninstall(_tokenSource.Token);
|
||||||
|
|
||||||
// Wait after the task finished for the user to process what happened
|
// Wait after the task finished for the user to process what happened
|
||||||
if (pluginPrerequisiteViewModel != Prerequisites.Last())
|
if (pluginPrerequisiteViewModel != Prerequisites.Last())
|
||||||
|
{
|
||||||
await Task.Delay(1000);
|
await Task.Delay(1000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Prerequisites.All(p => !p.IsMet))
|
if (Prerequisites.All(p => !p.IsMet))
|
||||||
@ -120,14 +135,12 @@ namespace Artemis.UI.Screens.Plugins
|
|||||||
|
|
||||||
// This shouldn't be happening and the experience isn't very nice for the user (too lazy to make a nice UI for such an edge case)
|
// This shouldn't be happening and the experience isn't very nice for the user (too lazy to make a nice UI for such an edge case)
|
||||||
// but at least give some feedback
|
// but at least give some feedback
|
||||||
Session?.Close(false);
|
Close.Execute(false);
|
||||||
await _dialogService.ShowConfirmDialog(
|
await _windowService.CreateContentDialog()
|
||||||
"Plugin prerequisites",
|
.WithTitle("Plugin prerequisites")
|
||||||
"The plugin was not able to fully remove all prerequisites. \r\nPlease try again or contact the plugin creator.",
|
.WithContent("The plugin was not able to fully remove all prerequisites. \r\nPlease try again or contact the plugin creator.")
|
||||||
"Confirm",
|
.ShowAsync();
|
||||||
""
|
await Show(_windowService, _subjects);
|
||||||
);
|
|
||||||
await Show(_dialogService, _subjects);
|
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException)
|
catch (OperationCanceledException)
|
||||||
{
|
{
|
||||||
@ -143,30 +156,12 @@ namespace Artemis.UI.Screens.Plugins
|
|||||||
|
|
||||||
public void Accept()
|
public void Accept()
|
||||||
{
|
{
|
||||||
Session?.Close(true);
|
Close.Execute(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Task<object> Show(IDialogService dialogService, List<IPrerequisitesSubject> subjects, string cancelLabel = "CANCEL")
|
public static async Task<object> Show(IWindowService windowService, List<IPrerequisitesSubject> subjects, string cancelLabel = "Cancel")
|
||||||
{
|
{
|
||||||
return dialogService.ShowDialog<PluginPrerequisitesUninstallDialogViewModel>(new Dictionary<string, object>
|
return await windowService.ShowDialogAsync<PluginPrerequisitesUninstallDialogViewModel, bool>(("subjects", subjects), ("cancelLabel", cancelLabel));
|
||||||
{
|
|
||||||
{"subjects", subjects},
|
|
||||||
{"cancelLabel", cancelLabel},
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Overrides of Screen
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void OnInitialActivate()
|
|
||||||
{
|
|
||||||
CanUninstall = false;
|
|
||||||
// Could be slow so take it off of the UI thread
|
|
||||||
Task.Run(() => CanUninstall = Prerequisites.Any(p => p.PluginPrerequisite.IsMet()));
|
|
||||||
|
|
||||||
base.OnInitialActivate();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,28 +1,23 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.Core.Services;
|
using Artemis.Core.Services;
|
||||||
using Artemis.UI.Avalonia.Screens.Settings.Tabs.Plugins.ViewModels;
|
using Artemis.UI.Avalonia.Shared;
|
||||||
using Artemis.UI.Ninject.Factories;
|
|
||||||
using Artemis.UI.Screens.Plugins;
|
|
||||||
using Artemis.UI.Shared.Services;
|
|
||||||
using Ninject;
|
using Ninject;
|
||||||
using Stylet;
|
using ReactiveUI;
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||||
{
|
{
|
||||||
public class PluginSettingsViewModel : Conductor<PluginFeatureViewModel>.Collection.AllActive
|
public class PluginSettingsViewModel : ActivatableViewModelBase
|
||||||
{
|
{
|
||||||
private readonly ICoreService _coreService;
|
private readonly ICoreService _coreService;
|
||||||
private readonly IDialogService _dialogService;
|
|
||||||
private readonly IMessageService _messageService;
|
|
||||||
private readonly IPluginManagementService _pluginManagementService;
|
private readonly IPluginManagementService _pluginManagementService;
|
||||||
private readonly ISettingsVmFactory _settingsVmFactory;
|
private readonly ISettingsVmFactory _settingsVmFactory;
|
||||||
private readonly IWindowManager _windowManager;
|
|
||||||
private bool _canInstallPrerequisites;
|
private bool _canInstallPrerequisites;
|
||||||
private bool _canRemovePrerequisites;
|
private bool _canRemovePrerequisites;
|
||||||
private bool _enabling;
|
private bool _enabling;
|
||||||
@ -32,31 +27,27 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
|||||||
public PluginSettingsViewModel(Plugin plugin,
|
public PluginSettingsViewModel(Plugin plugin,
|
||||||
ISettingsVmFactory settingsVmFactory,
|
ISettingsVmFactory settingsVmFactory,
|
||||||
ICoreService coreService,
|
ICoreService coreService,
|
||||||
IWindowManager windowManager,
|
IPluginManagementService pluginManagementService)
|
||||||
IDialogService dialogService,
|
|
||||||
IPluginManagementService pluginManagementService,
|
|
||||||
IMessageService messageService)
|
|
||||||
{
|
{
|
||||||
Plugin = plugin;
|
Plugin = plugin;
|
||||||
|
|
||||||
_settingsVmFactory = settingsVmFactory;
|
_settingsVmFactory = settingsVmFactory;
|
||||||
_coreService = coreService;
|
_coreService = coreService;
|
||||||
_windowManager = windowManager;
|
|
||||||
_dialogService = dialogService;
|
|
||||||
_pluginManagementService = pluginManagementService;
|
_pluginManagementService = pluginManagementService;
|
||||||
_messageService = messageService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ObservableCollection<PluginFeatureViewModel> PluginFeatures { get; }
|
||||||
|
|
||||||
public Plugin Plugin
|
public Plugin Plugin
|
||||||
{
|
{
|
||||||
get => _plugin;
|
get => _plugin;
|
||||||
set => SetAndNotify(ref _plugin, value);
|
set => this.RaiseAndSetIfChanged(ref _plugin, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Enabling
|
public bool Enabling
|
||||||
{
|
{
|
||||||
get => _enabling;
|
get => _enabling;
|
||||||
set => SetAndNotify(ref _enabling, value);
|
set => this.RaiseAndSetIfChanged(ref _enabling, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Type => Plugin.GetType().BaseType?.Name ?? Plugin.GetType().Name;
|
public string Type => Plugin.GetType().BaseType?.Name ?? Plugin.GetType().Name;
|
||||||
@ -73,7 +64,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
|||||||
get => _isSettingsPopupOpen;
|
get => _isSettingsPopupOpen;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (!SetAndNotify(ref _isSettingsPopupOpen, value)) return;
|
if (!this.RaiseAndSetIfChanged(ref _isSettingsPopupOpen, value)) return;
|
||||||
CheckPrerequisites();
|
CheckPrerequisites();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -81,13 +72,13 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
|||||||
public bool CanInstallPrerequisites
|
public bool CanInstallPrerequisites
|
||||||
{
|
{
|
||||||
get => _canInstallPrerequisites;
|
get => _canInstallPrerequisites;
|
||||||
set => SetAndNotify(ref _canInstallPrerequisites, value);
|
set => this.RaiseAndSetIfChanged(ref _canInstallPrerequisites, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CanRemovePrerequisites
|
public bool CanRemovePrerequisites
|
||||||
{
|
{
|
||||||
get => _canRemovePrerequisites;
|
get => _canRemovePrerequisites;
|
||||||
set => SetAndNotify(ref _canRemovePrerequisites, value);
|
set => this.RaiseAndSetIfChanged(ref _canRemovePrerequisites, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OpenSettings()
|
public void OpenSettings()
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Stylet;
|
|
||||||
|
|
||||||
namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
namespace Artemis.UI.Avalonia.Screens.Plugins.ViewModels
|
||||||
{
|
{
|
||||||
public class PluginSettingsWindowViewModel : Conductor<PluginConfigurationViewModel>
|
public class PluginSettingsWindowViewModel : Conductor<PluginConfigurationViewModel>
|
||||||
{
|
{
|
||||||
|
|||||||
@ -3,6 +3,6 @@
|
|||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
x:Class="Artemis.UI.Avalonia.Screens.Settings.Tabs.Plugins.Views.PluginFeatureView">
|
x:Class="Artemis.UI.Avalonia.Screens.Plugins.Views.PluginFeatureView">
|
||||||
Welcome to Avalonia!
|
Welcome to Avalonia!
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
using Avalonia;
|
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Markup.Xaml;
|
using Avalonia.Markup.Xaml;
|
||||||
|
|
||||||
namespace Artemis.UI.Avalonia.Screens.Settings.Tabs.Plugins.Views
|
namespace Artemis.UI.Avalonia.Screens.Plugins.Views
|
||||||
{
|
{
|
||||||
public partial class PluginFeatureView : UserControl
|
public partial class PluginFeatureView : UserControl
|
||||||
{
|
{
|
||||||
|
|||||||
@ -3,6 +3,6 @@
|
|||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
x:Class="Artemis.UI.Avalonia.Screens.Settings.Tabs.Plugins.Views.PluginSettingsView">
|
x:Class="Artemis.UI.Avalonia.Screens.Plugins.Views.PluginSettingsView">
|
||||||
Welcome to Avalonia!
|
Welcome to Avalonia!
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
using Avalonia;
|
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Markup.Xaml;
|
using Avalonia.Markup.Xaml;
|
||||||
|
|
||||||
namespace Artemis.UI.Avalonia.Screens.Settings.Tabs.Plugins.Views
|
namespace Artemis.UI.Avalonia.Screens.Plugins.Views
|
||||||
{
|
{
|
||||||
public partial class PluginSettingsView : UserControl
|
public partial class PluginSettingsView : UserControl
|
||||||
{
|
{
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
x:Class="Artemis.UI.Avalonia.Screens.Settings.Tabs.Plugins.Views.PluginSettingsWindowView"
|
x:Class="Artemis.UI.Avalonia.Screens.Plugins.Views.PluginSettingsWindowView"
|
||||||
Title="PluginSettingsWindowView">
|
Title="PluginSettingsWindowView">
|
||||||
Welcome to Avalonia!
|
Welcome to Avalonia!
|
||||||
</Window>
|
</Window>
|
||||||
|
|||||||
@ -2,7 +2,7 @@ using Avalonia;
|
|||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Markup.Xaml;
|
using Avalonia.Markup.Xaml;
|
||||||
|
|
||||||
namespace Artemis.UI.Avalonia.Screens.Settings.Tabs.Plugins.Views
|
namespace Artemis.UI.Avalonia.Screens.Plugins.Views
|
||||||
{
|
{
|
||||||
public partial class PluginSettingsWindowView : Window
|
public partial class PluginSettingsWindowView : Window
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user