diff --git a/src/Artemis.UI.Avalonia.Shared/Artemis.UI.Avalonia.Shared.csproj b/src/Artemis.UI.Avalonia.Shared/Artemis.UI.Avalonia.Shared.csproj index 4abc0d292..f2e68cafb 100644 --- a/src/Artemis.UI.Avalonia.Shared/Artemis.UI.Avalonia.Shared.csproj +++ b/src/Artemis.UI.Avalonia.Shared/Artemis.UI.Avalonia.Shared.csproj @@ -6,8 +6,12 @@ + + C:\Repos\Artemis\src\Artemis.UI.Avalonia.Shared\Artemis.UI.Avalonia.Shared.xml + + diff --git a/src/Artemis.UI.Avalonia.Shared/ViewModelBase.cs b/src/Artemis.UI.Avalonia.Shared/ViewModelBase.cs new file mode 100644 index 000000000..486498be8 --- /dev/null +++ b/src/Artemis.UI.Avalonia.Shared/ViewModelBase.cs @@ -0,0 +1,85 @@ +using System; +using System.Reactive; +using System.Reactive.Disposables; +using ReactiveUI; + +namespace Artemis.UI.Avalonia.Shared +{ + /// + /// Represents the base class for Artemis view models + /// + public abstract class ViewModelBase : ReactiveObject + { + private string? _displayName; + + /// + /// Gets or sets the display name of the view model + /// + public string? DisplayName + { + get => _displayName; + set => this.RaiseAndSetIfChanged(ref _displayName, value); + } + } + + /// + /// Represents the base class for Artemis view models that are interested in the activated event + /// + public abstract class ActivatableViewModelBase : ViewModelBase, IActivatableViewModel, IDisposable + { + /// + protected ActivatableViewModelBase() + { + this.WhenActivated(disposables => Disposable.Create(Dispose).DisposeWith(disposables)); + } + + /// + /// Releases the unmanaged resources used by the object and optionally releases the managed resources. + /// + /// + /// to release both managed and unmanaged resources; + /// to release only unmanaged resources. + /// + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + } + } + + /// + public ViewModelActivator Activator { get; } = new(); + + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + } + + /// + /// Represents the base class for Artemis view models used to drive dialogs + /// + public abstract class DialogViewModelBase : ActivatableViewModelBase + { + + /// + protected DialogViewModelBase() + { + Close = ReactiveCommand.Create(t => t); + Cancel = ReactiveCommand.Create(() => { }); + } + + + /// + /// Closes the dialog with a given result + /// + public ReactiveCommand Close { get; } + + /// + /// Closes the dialog without a result + /// + public ReactiveCommand Cancel { get; } + } +} \ No newline at end of file diff --git a/src/Artemis.UI.Avalonia.Shared/packages.lock.json b/src/Artemis.UI.Avalonia.Shared/packages.lock.json index e4e9b7e24..4e75df400 100644 --- a/src/Artemis.UI.Avalonia.Shared/packages.lock.json +++ b/src/Artemis.UI.Avalonia.Shared/packages.lock.json @@ -17,6 +17,17 @@ "System.ValueTuple": "4.5.0" } }, + "Avalonia.ReactiveUI": { + "type": "Direct", + "requested": "[0.10.10, )", + "resolved": "0.10.10", + "contentHash": "hDMPhusehGxsHpwaFQwGOgEmAuFLp9VVnFDrX6Le1+8idpfxgHYWyzqo4uVYUiEO1OC2ab0Ik9Un/utLZcvh7w==", + "dependencies": { + "Avalonia": "0.10.10", + "ReactiveUI": "13.2.10", + "System.Reactive": "5.0.0" + } + }, "Avalonia.Svg.Skia": { "type": "Direct", "requested": "[0.10.8.3, )", @@ -191,6 +202,14 @@ "System.Xml.XmlDocument": "4.3.0" } }, + "DynamicData": { + "type": "Transitive", + "resolved": "7.1.1", + "contentHash": "Pc6J5bFnSxEa64PV2V67FMcLlDdpv6m+zTBKSnRN3aLon/WtWWy8kuDpHFbJlgXHtqc6Nxloj9ItuvDlvKC/8w==", + "dependencies": { + "System.Reactive": "5.0.0" + } + }, "EmbedIO": { "type": "Transitive", "resolved": "3.4.3", @@ -457,6 +476,17 @@ "Ninject": "3.3.3" } }, + "ReactiveUI": { + "type": "Transitive", + "resolved": "13.2.10", + "contentHash": "fOCbEZ+RsO2Jhv6vB8VX+ZEvczYJaC95atcSG7oXohJeL/sEwbbqvv9k+tbj2l4bRSj2j5CQvhwA3HNLaxlCAg==", + "dependencies": { + "DynamicData": "7.1.1", + "Splat": "10.0.1", + "System.Reactive": "5.0.0", + "System.Runtime.Serialization.Primitives": "4.3.0" + } + }, "runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": { "type": "Transitive", "resolved": "4.3.0", @@ -623,6 +653,11 @@ "SkiaSharp": "2.80.2" } }, + "Splat": { + "type": "Transitive", + "resolved": "10.0.1", + "contentHash": "N8BMGVuUBnVLAHSVbna/st8XiLd8ulF3BfkKUSGCPqYpDCis3ELvM+aFaZQLBUIBEcweCYVLq3HFEBqHkCKFyA==" + }, "Svg.Custom": { "type": "Transitive", "resolved": "0.5.8.3", @@ -1264,6 +1299,15 @@ "System.Runtime.Extensions": "4.3.0" } }, + "System.Runtime.Serialization.Primitives": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "Wz+0KOukJGAlXjtKr+5Xpuxf8+c8739RI1C+A2BoQZT+wMCCoMDDdO8/4IRHfaVINqL78GO8dW8G2lW/e45Mcw==", + "dependencies": { + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0" + } + }, "System.Security.AccessControl": { "type": "Transitive", "resolved": "5.0.0", diff --git a/src/Artemis.UI.Avalonia/Artemis.UI.Avalonia.csproj b/src/Artemis.UI.Avalonia/Artemis.UI.Avalonia.csproj index 3f8a3f1ab..427d243fd 100644 --- a/src/Artemis.UI.Avalonia/Artemis.UI.Avalonia.csproj +++ b/src/Artemis.UI.Avalonia/Artemis.UI.Avalonia.csproj @@ -4,6 +4,9 @@ net5.0 enable + + + @@ -11,9 +14,6 @@ - - - @@ -50,6 +50,15 @@ %(Filename) + + %(Filename) + + + %(Filename) + + + %(Filename) + %(Filename) @@ -62,7 +71,7 @@ %(Filename) - + %(Filename) @@ -83,18 +92,6 @@ - - $(DefaultXamlRuntime) - MSBuild:Compile - - - $(DefaultXamlRuntime) - MSBuild:Compile - - - $(DefaultXamlRuntime) - MSBuild:Compile - $(DefaultXamlRuntime) MSBuild:Compile diff --git a/src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Plugins/ViewModels/PluginFeatureViewModel.cs b/src/Artemis.UI.Avalonia/Screens/Plugins/ViewModels/PluginFeatureViewModel.cs similarity index 100% rename from src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Plugins/ViewModels/PluginFeatureViewModel.cs rename to src/Artemis.UI.Avalonia/Screens/Plugins/ViewModels/PluginFeatureViewModel.cs diff --git a/src/Artemis.UI.Avalonia/Screens/Plugins/ViewModels/PluginPrerequisiteActionViewModel.cs b/src/Artemis.UI.Avalonia/Screens/Plugins/ViewModels/PluginPrerequisiteActionViewModel.cs new file mode 100644 index 000000000..0a42da735 --- /dev/null +++ b/src/Artemis.UI.Avalonia/Screens/Plugins/ViewModels/PluginPrerequisiteActionViewModel.cs @@ -0,0 +1,20 @@ +using System; +using System.ComponentModel; +using Artemis.Core; +using Artemis.UI.Avalonia; +using Artemis.UI.Avalonia.Shared; + +namespace Artemis.UI.Screens.Plugins +{ + public class PluginPrerequisiteActionViewModel : ViewModelBase + { + + + public PluginPrerequisiteActionViewModel(PluginPrerequisiteAction action) + { + Action = action; + } + + public PluginPrerequisiteAction Action { get; } + } +} \ No newline at end of file diff --git a/src/Artemis.UI.Avalonia/Screens/Plugins/ViewModels/PluginPrerequisiteViewModel.cs b/src/Artemis.UI.Avalonia/Screens/Plugins/ViewModels/PluginPrerequisiteViewModel.cs new file mode 100644 index 000000000..453ec9bac --- /dev/null +++ b/src/Artemis.UI.Avalonia/Screens/Plugins/ViewModels/PluginPrerequisiteViewModel.cs @@ -0,0 +1,133 @@ +using System; +using System.ComponentModel; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Artemis.Core; +using Artemis.Core.Services; +using Artemis.UI.Shared.Services; +using Stylet; + +namespace Artemis.UI.Screens.Plugins +{ + public class PluginPrerequisiteViewModel : Conductor.Collection.OneActive + { + private readonly bool _uninstall; + private bool _installing; + private bool _uninstalling; + private bool _isMet; + + public PluginPrerequisiteViewModel(PluginPrerequisite pluginPrerequisite, bool uninstall) + { + _uninstall = uninstall; + PluginPrerequisite = pluginPrerequisite; + } + + public PluginPrerequisite PluginPrerequisite { get; } + + public bool Installing + { + get => _installing; + set + { + SetAndNotify(ref _installing, value); + NotifyOfPropertyChange(nameof(Busy)); + } + } + + public bool Uninstalling + { + get => _uninstalling; + set + { + SetAndNotify(ref _uninstalling, value); + NotifyOfPropertyChange(nameof(Busy)); + } + } + + public bool IsMet + { + get => _isMet; + set => SetAndNotify(ref _isMet, value); + } + + public bool Busy => Installing || Uninstalling; + public int ActiveStemNumber => Items.IndexOf(ActiveItem) + 1; + public bool HasMultipleActions => Items.Count > 1; + + 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 newActiveItem = Items.FirstOrDefault(i => i.Action == PluginPrerequisite.CurrentAction); + if (newActiveItem == null) + return; + + ActiveItem = newActiveItem; + NotifyOfPropertyChange(nameof(ActiveStemNumber)); + } + + #region Overrides of Screen + + /// + protected override void OnClose() + { + PluginPrerequisite.PropertyChanged -= PluginPrerequisiteOnPropertyChanged; + base.OnClose(); + } + + /// + 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 + } +} \ No newline at end of file diff --git a/src/Artemis.UI.Avalonia/Screens/Plugins/ViewModels/PluginPrerequisitesInstallDialogViewModel.cs b/src/Artemis.UI.Avalonia/Screens/Plugins/ViewModels/PluginPrerequisitesInstallDialogViewModel.cs new file mode 100644 index 000000000..eccb78f87 --- /dev/null +++ b/src/Artemis.UI.Avalonia/Screens/Plugins/ViewModels/PluginPrerequisitesInstallDialogViewModel.cs @@ -0,0 +1,153 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Artemis.Core; +using Artemis.UI.Avalonia.Shared; +using ReactiveUI; + +namespace Artemis.UI.Screens.Plugins +{ + public class PluginPrerequisitesInstallDialogViewModel : DialogViewModelBase + { + private PluginPrerequisiteViewModel _activePrerequisite; + private bool _canInstall; + private bool _showFailed; + private bool _showInstall = true; + private bool _showIntro = true; + private bool _showProgress; + private CancellationTokenSource? _tokenSource; + + public PluginPrerequisitesInstallDialogViewModel(List subjects, IPrerequisitesVmFactory prerequisitesVmFactory, IDialogService dialogService) + { + Prerequisites = new ObservableCollection(); + foreach (IPrerequisitesSubject prerequisitesSubject in subjects) + Prerequisites.AddRange(prerequisitesSubject.Prerequisites.Select(p => prerequisitesVmFactory.PluginPrerequisiteViewModel(p, false))); + + foreach (PluginPrerequisiteViewModel pluginPrerequisiteViewModel in Prerequisites) + pluginPrerequisiteViewModel.ConductWith(this); + } + + public ObservableCollection Prerequisites { get; } + + public PluginPrerequisiteViewModel ActivePrerequisite + { + get => _activePrerequisite; + set => this.RaiseAndSetIfChanged(ref _activePrerequisite, value); + } + + public bool ShowProgress + { + get => _showProgress; + set => this.RaiseAndSetIfChanged(ref _showProgress, value); + } + + public bool ShowIntro + { + get => _showIntro; + set => this.RaiseAndSetIfChanged(ref _showIntro, value); + } + + public bool ShowFailed + { + get => _showFailed; + set => this.RaiseAndSetIfChanged(ref _showFailed, value); + } + + public bool ShowInstall + { + get => _showInstall; + set => this.RaiseAndSetIfChanged(ref _showInstall, value); + } + + public bool CanInstall + { + get => _canInstall; + set => this.RaiseAndSetIfChanged(ref _canInstall, value); + } + + public async void Install() + { + CanInstall = false; + ShowFailed = false; + ShowIntro = false; + ShowProgress = true; + + _tokenSource = new CancellationTokenSource(); + + try + { + foreach (PluginPrerequisiteViewModel pluginPrerequisiteViewModel in Prerequisites) + { + pluginPrerequisiteViewModel.IsMet = pluginPrerequisiteViewModel.PluginPrerequisite.IsMet(); + if (pluginPrerequisiteViewModel.IsMet) + continue; + + ActivePrerequisite = pluginPrerequisiteViewModel; + await ActivePrerequisite.Install(_tokenSource.Token); + + if (!ActivePrerequisite.IsMet) + { + CanInstall = true; + ShowFailed = true; + ShowProgress = false; + return; + } + + // Wait after the task finished for the user to process what happened + if (pluginPrerequisiteViewModel != Prerequisites.Last()) + await Task.Delay(1000); + } + + ShowInstall = false; + } + catch (OperationCanceledException) + { + // ignored + } + finally + { + _tokenSource.Dispose(); + _tokenSource = null; + } + } + + public void Accept() + { + Result = true; + Close.Execute(); + } + + public static Task Show(IDialogService dialogService, List subjects) + { + return dialogService.ShowDialog(new Dictionary {{"subjects", subjects}}); + } + + /// + protected override void Dispose(bool disposing) + { + if (disposing) + { + _tokenSource?.Cancel(); + _tokenSource?.Dispose(); + } + + base.Dispose(disposing); + } + + #region Overrides of Screen + + /// + protected override void OnInitialActivate() + { + CanInstall = false; + Task.Run(() => CanInstall = Prerequisites.Any(p => !p.PluginPrerequisite.IsMet())); + + base.OnInitialActivate(); + } + + #endregion + } +} \ No newline at end of file diff --git a/src/Artemis.UI.Avalonia/Screens/Plugins/ViewModels/PluginPrerequisitesUninstallDialogViewModel.cs b/src/Artemis.UI.Avalonia/Screens/Plugins/ViewModels/PluginPrerequisitesUninstallDialogViewModel.cs new file mode 100644 index 000000000..3d5ba00f0 --- /dev/null +++ b/src/Artemis.UI.Avalonia/Screens/Plugins/ViewModels/PluginPrerequisitesUninstallDialogViewModel.cs @@ -0,0 +1,172 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Artemis.Core; +using Artemis.Core.Services; +using Artemis.UI.Ninject.Factories; +using Artemis.UI.Shared.Services; +using MaterialDesignThemes.Wpf; +using Stylet; + +namespace Artemis.UI.Screens.Plugins +{ + public class PluginPrerequisitesUninstallDialogViewModel : DialogViewModelBase + { + private readonly IDialogService _dialogService; + private readonly IPluginManagementService _pluginManagementService; + private readonly List _subjects; + private PluginPrerequisiteViewModel _activePrerequisite; + private bool _canUninstall; + private bool _isFinished; + private CancellationTokenSource _tokenSource; + + public PluginPrerequisitesUninstallDialogViewModel(List subjects, string cancelLabel, IPrerequisitesVmFactory prerequisitesVmFactory, + IDialogService dialogService, IPluginManagementService pluginManagementService) + { + _subjects = subjects; + _dialogService = dialogService; + _pluginManagementService = pluginManagementService; + + CancelLabel = cancelLabel; + Prerequisites = new BindableCollection(); + foreach (IPrerequisitesSubject prerequisitesSubject in subjects) + Prerequisites.AddRange(prerequisitesSubject.Prerequisites.Select(p => prerequisitesVmFactory.PluginPrerequisiteViewModel(p, true))); + + foreach (PluginPrerequisiteViewModel pluginPrerequisiteViewModel in Prerequisites) + pluginPrerequisiteViewModel.ConductWith(this); + } + + public string CancelLabel { get; } + public BindableCollection Prerequisites { get; } + + public PluginPrerequisiteViewModel ActivePrerequisite + { + get => _activePrerequisite; + set => SetAndNotify(ref _activePrerequisite, value); + } + + public bool CanUninstall + { + get => _canUninstall; + set => SetAndNotify(ref _canUninstall, value); + } + + public bool IsFinished + { + get => _isFinished; + set => SetAndNotify(ref _isFinished, value); + } + + #region Overrides of DialogViewModelBase + + /// + public override void OnDialogClosed(object sender, DialogClosingEventArgs e) + { + _tokenSource?.Cancel(); + base.OnDialogClosed(sender, e); + } + + #endregion + + public async void Uninstall() + { + CanUninstall = false; + + // Disable all subjects that are plugins, this will disable their features too + foreach (IPrerequisitesSubject prerequisitesSubject in _subjects) + { + if (prerequisitesSubject is PluginInfo pluginInfo) + _pluginManagementService.DisablePlugin(pluginInfo.Plugin, true); + } + + // Disable all subjects that are features if still required + foreach (IPrerequisitesSubject prerequisitesSubject in _subjects) + { + if (prerequisitesSubject is not PluginFeatureInfo featureInfo) + continue; + + // Disable the parent plugin if the feature is AlwaysEnabled + if (featureInfo.AlwaysEnabled) + _pluginManagementService.DisablePlugin(featureInfo.Plugin, true); + else if (featureInfo.Instance != null) + _pluginManagementService.DisablePluginFeature(featureInfo.Instance, true); + } + + _tokenSource = new CancellationTokenSource(); + + try + { + foreach (PluginPrerequisiteViewModel pluginPrerequisiteViewModel in Prerequisites) + { + pluginPrerequisiteViewModel.IsMet = pluginPrerequisiteViewModel.PluginPrerequisite.IsMet(); + if (!pluginPrerequisiteViewModel.IsMet) + continue; + + ActivePrerequisite = pluginPrerequisiteViewModel; + await ActivePrerequisite.Uninstall(_tokenSource.Token); + + // Wait after the task finished for the user to process what happened + if (pluginPrerequisiteViewModel != Prerequisites.Last()) + await Task.Delay(1000); + } + + if (Prerequisites.All(p => !p.IsMet)) + { + IsFinished = true; + return; + } + + // 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 + Session?.Close(false); + await _dialogService.ShowConfirmDialog( + "Plugin prerequisites", + "The plugin was not able to fully remove all prerequisites. \r\nPlease try again or contact the plugin creator.", + "Confirm", + "" + ); + await Show(_dialogService, _subjects); + } + catch (OperationCanceledException) + { + // ignored + } + finally + { + CanUninstall = true; + _tokenSource.Dispose(); + _tokenSource = null; + } + } + + public void Accept() + { + Session?.Close(true); + } + + public static Task Show(IDialogService dialogService, List subjects, string cancelLabel = "CANCEL") + { + return dialogService.ShowDialog(new Dictionary + { + {"subjects", subjects}, + {"cancelLabel", cancelLabel}, + }); + } + + #region Overrides of Screen + + /// + 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 + } +} \ No newline at end of file diff --git a/src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Plugins/ViewModels/PluginSettingsViewModel.cs b/src/Artemis.UI.Avalonia/Screens/Plugins/ViewModels/PluginSettingsViewModel.cs similarity index 100% rename from src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Plugins/ViewModels/PluginSettingsViewModel.cs rename to src/Artemis.UI.Avalonia/Screens/Plugins/ViewModels/PluginSettingsViewModel.cs diff --git a/src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Plugins/ViewModels/PluginSettingsWindowViewModel.cs b/src/Artemis.UI.Avalonia/Screens/Plugins/ViewModels/PluginSettingsWindowViewModel.cs similarity index 100% rename from src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Plugins/ViewModels/PluginSettingsWindowViewModel.cs rename to src/Artemis.UI.Avalonia/Screens/Plugins/ViewModels/PluginSettingsWindowViewModel.cs diff --git a/src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Plugins/Views/PluginFeatureView.axaml b/src/Artemis.UI.Avalonia/Screens/Plugins/Views/PluginFeatureView.axaml similarity index 100% rename from src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Plugins/Views/PluginFeatureView.axaml rename to src/Artemis.UI.Avalonia/Screens/Plugins/Views/PluginFeatureView.axaml diff --git a/src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Plugins/Views/PluginFeatureView.axaml.cs b/src/Artemis.UI.Avalonia/Screens/Plugins/Views/PluginFeatureView.axaml.cs similarity index 100% rename from src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Plugins/Views/PluginFeatureView.axaml.cs rename to src/Artemis.UI.Avalonia/Screens/Plugins/Views/PluginFeatureView.axaml.cs diff --git a/src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Plugins/Views/PluginSettingsView.axaml b/src/Artemis.UI.Avalonia/Screens/Plugins/Views/PluginSettingsView.axaml similarity index 100% rename from src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Plugins/Views/PluginSettingsView.axaml rename to src/Artemis.UI.Avalonia/Screens/Plugins/Views/PluginSettingsView.axaml diff --git a/src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Plugins/Views/PluginSettingsView.axaml.cs b/src/Artemis.UI.Avalonia/Screens/Plugins/Views/PluginSettingsView.axaml.cs similarity index 100% rename from src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Plugins/Views/PluginSettingsView.axaml.cs rename to src/Artemis.UI.Avalonia/Screens/Plugins/Views/PluginSettingsView.axaml.cs diff --git a/src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Plugins/Views/PluginSettingsWindowView.axaml b/src/Artemis.UI.Avalonia/Screens/Plugins/Views/PluginSettingsWindowView.axaml similarity index 100% rename from src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Plugins/Views/PluginSettingsWindowView.axaml rename to src/Artemis.UI.Avalonia/Screens/Plugins/Views/PluginSettingsWindowView.axaml diff --git a/src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Plugins/Views/PluginSettingsWindowView.axaml.cs b/src/Artemis.UI.Avalonia/Screens/Plugins/Views/PluginSettingsWindowView.axaml.cs similarity index 100% rename from src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Plugins/Views/PluginSettingsWindowView.axaml.cs rename to src/Artemis.UI.Avalonia/Screens/Plugins/Views/PluginSettingsWindowView.axaml.cs diff --git a/src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Plugins/Views/PluginFeatureView.xaml b/src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Plugins/Views/PluginFeatureView.xaml deleted file mode 100644 index 38998a889..000000000 --- a/src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Plugins/Views/PluginFeatureView.xaml +++ /dev/null @@ -1,106 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Feature enabled - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Plugins/Views/PluginSettingsView.xaml b/src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Plugins/Views/PluginSettingsView.xaml deleted file mode 100644 index d20d17e5a..000000000 --- a/src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Plugins/Views/PluginSettingsView.xaml +++ /dev/null @@ -1,209 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Plugin enabled - - - - - - - - - - - - - - Plugin features - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Plugins/Views/PluginSettingsWindowView.xaml b/src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Plugins/Views/PluginSettingsWindowView.xaml deleted file mode 100644 index 1500833d6..000000000 --- a/src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Plugins/Views/PluginSettingsWindowView.xaml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Plugins/ViewModels/PluginsTabViewModel.cs b/src/Artemis.UI.Avalonia/Screens/Settings/Tabs/ViewModels/PluginsTabViewModel.cs similarity index 100% rename from src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Plugins/ViewModels/PluginsTabViewModel.cs rename to src/Artemis.UI.Avalonia/Screens/Settings/Tabs/ViewModels/PluginsTabViewModel.cs diff --git a/src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Plugins/Views/PluginsTabView.axaml b/src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Views/PluginsTabView.axaml similarity index 100% rename from src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Plugins/Views/PluginsTabView.axaml rename to src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Views/PluginsTabView.axaml diff --git a/src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Plugins/Views/PluginsTabView.axaml.cs b/src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Views/PluginsTabView.axaml.cs similarity index 100% rename from src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Plugins/Views/PluginsTabView.axaml.cs rename to src/Artemis.UI.Avalonia/Screens/Settings/Tabs/Views/PluginsTabView.axaml.cs diff --git a/src/Artemis.UI.Avalonia/ViewLocator.cs b/src/Artemis.UI.Avalonia/ViewLocator.cs index b4d3fafd1..fde4e39e8 100644 --- a/src/Artemis.UI.Avalonia/ViewLocator.cs +++ b/src/Artemis.UI.Avalonia/ViewLocator.cs @@ -1,4 +1,5 @@ using System; +using Artemis.UI.Avalonia.Shared; using Avalonia.Controls; using Avalonia.Controls.Templates; diff --git a/src/Artemis.UI.Avalonia/ViewModelBase.cs b/src/Artemis.UI.Avalonia/ViewModelBase.cs deleted file mode 100644 index ec317b41d..000000000 --- a/src/Artemis.UI.Avalonia/ViewModelBase.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using System.Reactive.Disposables; -using ReactiveUI; - -namespace Artemis.UI.Avalonia -{ - public abstract class ViewModelBase : ReactiveObject - { - private string? _displayName; - - public string? DisplayName - { - get => _displayName; - set => this.RaiseAndSetIfChanged(ref _displayName, value); - } - } - - public abstract class ActivatableViewModelBase : ViewModelBase, IActivatableViewModel, IDisposable - { - /// - protected ActivatableViewModelBase() - { - this.WhenActivated(disposables => - { - Disposable.Create(Dispose).DisposeWith(disposables); - }); - } - - #region IDisposable - - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - } - } - - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - #endregion - - public ViewModelActivator Activator { get; } = new(); - } -} \ No newline at end of file diff --git a/src/Artemis.UI.Avalonia/packages.lock.json b/src/Artemis.UI.Avalonia/packages.lock.json index 1ed186fb7..ab2580987 100644 --- a/src/Artemis.UI.Avalonia/packages.lock.json +++ b/src/Artemis.UI.Avalonia/packages.lock.json @@ -1695,6 +1695,7 @@ "dependencies": { "Artemis.Core": "1.0.0", "Avalonia": "0.10.10", + "Avalonia.ReactiveUI": "0.10.10", "Avalonia.Svg.Skia": "0.10.8.3", "Avalonia.Xaml.Behaviors": "0.10.10", "Avalonia.Xaml.Interactions": "0.10.10",