Plugins - Reworked bootstrapper

This commit is contained in:
Robert committed 2021-04-30 17:39:58 +02:00
1 parent 5cae14efd3
commit 21700aaad5
13 files changed
+288 -135

No files matched your search

@@ -12,7 +12,13 @@
d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance local:PluginFeatureViewModel}">
<UserControl.Resources>
<converters:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary
Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.PopupBox.xaml" />
</ResourceDictionary.MergedDictionaries>
<converters:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />
</ResourceDictionary>
</UserControl.Resources>
<Grid Margin="-3 -8">
<Grid.ColumnDefinitions>
@@ -23,11 +29,11 @@
<!-- Icon column -->
<shared:ArtemisIcon Grid.Column="0"
Icon="{Binding FeatureInfo.Icon}"
Width="20"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Visibility="{Binding LoadException, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=Inverted, FallbackValue=Collapsed}" />
Icon="{Binding FeatureInfo.Icon}"
Width="20"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Visibility="{Binding LoadException, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=Inverted, FallbackValue=Collapsed}" />
<Button Grid.Column="0"
Margin="-8"
@@ -42,16 +48,16 @@
</Button>
<!-- Display name column -->
<TextBlock Grid.Column="1"
Text="{Binding FeatureInfo.Name}"
Style="{StaticResource MaterialDesignTextBlock}"
VerticalAlignment="Center"
<TextBlock Grid.Column="1"
Text="{Binding FeatureInfo.Name}"
Style="{StaticResource MaterialDesignTextBlock}"
VerticalAlignment="Center"
TextWrapping="Wrap"
ToolTip="{Binding FeatureInfo.Description}" />
<!-- Enable toggle column -->
<StackPanel Grid.Column="2"
HorizontalAlignment="Right"
HorizontalAlignment="Right"
Margin="8"
Visibility="{Binding Enabling, Converter={x:Static s:BoolToVisibilityConverter.InverseInstance}, Mode=OneWay, FallbackValue=Collapsed}"
Orientation="Horizontal"
@@ -63,11 +69,31 @@
VerticalAlignment="Center"
Margin="0 0 5 0"
Visibility="{Binding ShowShield, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}" />
<CheckBox Style="{StaticResource MaterialDesignCheckBox}"
<CheckBox Style="{StaticResource MaterialDesignCheckBox}"
IsChecked="{Binding IsEnabled}"
IsEnabled="{Binding CanToggleEnabled}">
Feature enabled
</CheckBox>
<materialDesign:PopupBox Style="{StaticResource MaterialDesignToolPopupBox}"
Margin="0 -4 -10 -4"
Foreground="{StaticResource MaterialDesignBody}"
IsEnabled="{Binding IsPopupEnabled}">
<StackPanel>
<Button Command="{s:Action InstallPrerequisites}">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="CheckAll" Margin="0 0 10 0 " VerticalAlignment="Center" />
<TextBlock VerticalAlignment="Center">Install prerequisites</TextBlock>
</StackPanel>
</Button>
<Button Command="{s:Action RemovePrerequisites}">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="Delete" Margin="0 0 10 0 " VerticalAlignment="Center" />
<TextBlock VerticalAlignment="Center">Remove prerequisites</TextBlock>
</StackPanel>
</Button>
</StackPanel>
</materialDesign:PopupBox>
</StackPanel>
<StackPanel Grid.Column="2" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="7"
Visibility="{Binding Enabling, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay, FallbackValue=Collapsed}">
@@ -1,9 +1,12 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Artemis.Core;
using Artemis.Core.Services;
using Artemis.UI.Screens.Plugins;
using Artemis.UI.Shared.Services;
using Stylet;
@@ -16,6 +19,9 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
private readonly IPluginManagementService _pluginManagementService;
private bool _enabling;
private readonly IMessageService _messageService;
private bool _isSettingsPopupOpen;
private bool _canInstallPrerequisites;
private bool _canRemovePrerequisites;
public PluginFeatureViewModel(PluginFeatureInfo pluginFeatureInfo,
bool showShield,
@@ -51,6 +57,9 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
}
public bool CanToggleEnabled => FeatureInfo.Plugin.IsEnabled && !FeatureInfo.AlwaysEnabled;
public bool CanInstallPrerequisites => FeatureInfo.Prerequisites.Any();
public bool CanRemovePrerequisites => FeatureInfo.Prerequisites.Any(p => p.UninstallActions.Any());
public bool IsPopupEnabled => CanInstallPrerequisites || CanRemovePrerequisites;
public void ShowLogsFolder()
{
@@ -96,6 +105,21 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
base.OnClose();
}
public async Task InstallPrerequisites()
{
if (FeatureInfo.Prerequisites.Any())
await ShowPrerequisitesDialog(false, FeatureInfo);
}
public async Task RemovePrerequisites()
{
if (FeatureInfo.Prerequisites.Any(p => p.UninstallActions.Any()))
{
await ShowPrerequisitesDialog(true, FeatureInfo);
NotifyOfPropertyChange(nameof(IsEnabled));
}
}
private async Task UpdateEnabled(bool enable)
{
if (IsEnabled == enable || FeatureInfo.Instance == null)
@@ -120,7 +144,18 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
}
}
await Task.Run(() => _pluginManagementService.EnablePluginFeature(FeatureInfo.Instance, true));
// Check if all prerequisites are met async
if (!FeatureInfo.ArePrerequisitesMet())
{
await ShowPrerequisitesDialog(false, FeatureInfo);
if (!FeatureInfo.ArePrerequisitesMet())
{
NotifyOfPropertyChange(nameof(IsEnabled));
return;
}
}
await Task.Run(() => _pluginManagementService.EnablePluginFeature(FeatureInfo.Instance!, true));
}
catch (Exception e)
{
@@ -138,6 +173,13 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
}
}
private async Task<object> ShowPrerequisitesDialog(bool uninstall, IPrerequisitesSubject subject)
{
if (uninstall)
return await _dialogService.ShowDialog<PluginPrerequisitesUninstallDialogViewModel>(new Dictionary<string, object> { { "subject", subject } });
return await _dialogService.ShowDialog<PluginPrerequisitesInstallDialogViewModel>(new Dictionary<string, object> { { "subject", subject } });
}
#region Event handlers
private void OnFeatureEnabling(object sender, PluginFeatureEventArgs e)
@@ -136,24 +136,26 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
if (wasEnabled)
await UpdateEnabled(true);
_messageService.ShowMessage("Reloaded plugin.");
}
public async Task InstallPrerequisites()
{
if (Plugin.Info.Prerequisites.Any())
await ShowPrerequisitesDialog(false);
await ShowPrerequisitesDialog(false, Plugin.Info);
}
public async Task RemovePrerequisites()
{
if (Plugin.Info.Prerequisites.Any(p => p.UninstallActions.Any()))
{
await ShowPrerequisitesDialog(true);
await ShowPrerequisitesDialog(true, Plugin.Info);
NotifyOfPropertyChange(nameof(IsEnabled));
NotifyOfPropertyChange(nameof(CanOpenSettings));
}
}
public async Task RemoveSettings()
{
bool confirmed = await _dialogService.ShowConfirmDialog("Clear plugin settings", "Are you sure you want to clear the settings of this plugin?");
@@ -180,9 +182,31 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
return;
// If the plugin or any of its features has uninstall actions, offer to run these
List<PluginFeatureInfo> featuresToUninstall = Plugin.Features.Where(f => f.Prerequisites.Any(fp => fp.UninstallActions.Any())).ToList();
if (Plugin.Info.Prerequisites.Any(p => p.UninstallActions.Any()) || Plugin.Features.Any(f => f.Prerequisites.Any(fp => fp.UninstallActions.Any())))
{
bool remove = await _dialogService.ShowConfirmDialog(
"Remove plugin",
"This plugin installed one or more prerequisites.\r\nDo you want to remove these?",
"Uninstall",
"Skip"
);
if (remove)
{
if (Plugin.Info.Prerequisites.Any(p => p.UninstallActions.Any()))
{
object result = await ShowPrerequisitesDialog(true, Plugin.Info);
if (result is bool resultBool && !resultBool)
return;
}
foreach (PluginFeatureInfo pluginFeatureInfo in featuresToUninstall)
{
object result = await ShowPrerequisitesDialog(true, pluginFeatureInfo);
if (result is bool resultBool && !resultBool)
return;
}
}
}
try
@@ -244,7 +268,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
// Check if all prerequisites are met async
if (!Plugin.Info.ArePrerequisitesMet())
{
await ShowPrerequisitesDialog(false);
await ShowPrerequisitesDialog(false, Plugin.Info);
if (!Plugin.Info.ArePrerequisitesMet())
{
CancelEnable();
@@ -285,11 +309,11 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
CanRemovePrerequisites = Plugin.Info.Prerequisites.Any(p => p.UninstallActions.Any());
}
private async Task<object> ShowPrerequisitesDialog(bool uninstall)
private async Task<object> ShowPrerequisitesDialog(bool uninstall, IPrerequisitesSubject subject)
{
if (uninstall)
return await _dialogService.ShowDialog<PluginPrerequisitesUninstallDialogViewModel>(new Dictionary<string, object> { { "pluginOrFeature", Plugin } });
return await _dialogService.ShowDialog<PluginPrerequisitesInstallDialogViewModel>(new Dictionary<string, object> { { "pluginOrFeature", Plugin } });
return await _dialogService.ShowDialog<PluginPrerequisitesUninstallDialogViewModel>(new Dictionary<string, object> {{"subject", subject } });
return await _dialogService.ShowDialog<PluginPrerequisitesInstallDialogViewModel>(new Dictionary<string, object> {{ "subject", subject } });
}
}
}