1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-12 21:38:38 +00:00
Artemis/src/Artemis.UI/Screens/StartupWizard/Steps/DefaultEntryItemViewModel.cs
Robert 565647f1ed Workshop - Improves default entry handling in workshop
Core - Modifies the Artemis data folder path based on the build configuration.
Plugins - Adds a confirmation dialog to prompt the user to restart if a plugin requires admin rights.
Startup wizard - Updates the installation progress bar in the startup wizard.
Workshop - Changes category retrieval to be based on EntryType.
Workshop - Adds the ability to include default entries when searching the workshop.
2025-12-08 22:27:18 +01:00

107 lines
4.3 KiB
C#

using System;
using System.Linq;
using System.Reactive.Disposables;
using System.Threading;
using System.Threading.Tasks;
using Artemis.Core;
using Artemis.Core.Services;
using Artemis.UI.DryIoc.Factories;
using Artemis.UI.Screens.Plugins;
using Artemis.UI.Shared;
using Artemis.UI.Shared.Services;
using Artemis.UI.Shared.Utilities;
using Artemis.WebClient.Workshop;
using Artemis.WebClient.Workshop.Handlers.InstallationHandlers;
using Artemis.WebClient.Workshop.Models;
using Artemis.WebClient.Workshop.Services;
using PropertyChanged.SourceGenerator;
using ReactiveUI;
using Serilog;
namespace Artemis.UI.Screens.StartupWizard.Steps;
public partial class DefaultEntryItemViewModel : ActivatableViewModelBase
{
private readonly ILogger _logger;
private readonly IWorkshopService _workshopService;
private readonly IWindowService _windowService;
private readonly IPluginManagementService _pluginManagementService;
private readonly ISettingsVmFactory _settingsVmFactory;
private readonly Progress<StreamProgress> _progress = new();
[Notify] private bool _isInstalled;
[Notify] private bool _shouldInstall;
[Notify] private float _installProgress;
public DefaultEntryItemViewModel(ILogger logger, IEntrySummary entry, IWorkshopService workshopService, IWindowService windowService, IPluginManagementService pluginManagementService,
ISettingsVmFactory settingsVmFactory)
{
_logger = logger;
_workshopService = workshopService;
_windowService = windowService;
_pluginManagementService = pluginManagementService;
_settingsVmFactory = settingsVmFactory;
Entry = entry;
_progress.ProgressChanged += (_, f) => InstallProgress = f.ProgressPercentage;
this.WhenActivated((CompositeDisposable _) => { IsInstalled = workshopService.GetInstalledEntry(entry.Id) != null; });
}
public IEntrySummary Entry { get; }
public async Task<bool> InstallEntry(CancellationToken cancellationToken)
{
if (IsInstalled || !ShouldInstall || Entry.LatestRelease == null)
return true;
// Most entries install so fast it looks broken without a small delay
Task minimumDelay = Task.Delay(200, cancellationToken);
EntryInstallResult result = await _workshopService.InstallEntry(Entry, Entry.LatestRelease, _progress, cancellationToken);
await minimumDelay;
if (!result.IsSuccess)
{
await _windowService.CreateContentDialog().WithTitle("Failed to install entry")
.WithContent($"Failed to install entry '{Entry.Name}' ({Entry.Id}): {result.Message}")
.WithCloseButtonText("Skip and continue")
.ShowAsync();
}
// If the entry is a plugin, enable the plugin and all features
else if (result.Entry?.EntryType == EntryType.Plugin)
{
await EnablePluginAndFeatures(result.Entry);
}
return result.IsSuccess;
}
private async Task EnablePluginAndFeatures(InstalledEntry entry)
{
if (!entry.TryGetMetadata("PluginId", out Guid pluginId))
throw new InvalidOperationException("Plugin entry does not contain a PluginId metadata value.");
Plugin? plugin = _pluginManagementService.GetAllPlugins().FirstOrDefault(p => p.Guid == pluginId);
if (plugin == null)
throw new InvalidOperationException($"Plugin with id '{pluginId}' does not exist.");
// There's quite a bit of UI involved in enabling a plugin, borrowing the PluginSettingsViewModel for this
PluginViewModel pluginViewModel = _settingsVmFactory.PluginViewModel(plugin, ReactiveCommand.Create(() => { }));
await pluginViewModel.UpdateEnabled(true);
// Find features without prerequisites to enable
foreach (PluginFeatureInfo pluginFeatureInfo in plugin.Features)
{
if (pluginFeatureInfo.Instance == null || pluginFeatureInfo.Instance.IsEnabled || pluginFeatureInfo.Prerequisites.Count != 0)
continue;
try
{
_pluginManagementService.EnablePluginFeature(pluginFeatureInfo.Instance, true);
}
catch (Exception e)
{
_logger.Warning(e, "Failed to enable plugin feature '{FeatureName}', skipping", pluginFeatureInfo.Name);
}
}
}
}