mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-03-25 18:58:48 +00:00
Core - Added events for plugin removal, entry installlation/uninstallation Workshop - Remove the related workshop entry when manually removing a plugin or profile Workshop - Prevent installing profiles with missing plugins and show a dialog with which plugins are missing
184 lines
6.9 KiB
C#
184 lines
6.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
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.Screens.Workshop.EntryReleases.Dialogs;
|
|
using Artemis.UI.Shared;
|
|
using Artemis.UI.Shared.Routing;
|
|
using Artemis.UI.Shared.Services;
|
|
using Artemis.UI.Shared.Services.Builders;
|
|
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;
|
|
|
|
namespace Artemis.UI.Screens.Workshop.EntryReleases;
|
|
|
|
public partial class EntryReleaseInfoViewModel : ActivatableViewModelBase
|
|
{
|
|
private readonly IRouter _router;
|
|
private readonly INotificationService _notificationService;
|
|
private readonly IWindowService _windowService;
|
|
private readonly IWorkshopService _workshopService;
|
|
private readonly IPluginManagementService _pluginManagementService;
|
|
private readonly ISettingsVmFactory _settingsVmFactory;
|
|
private readonly Progress<StreamProgress> _progress = new();
|
|
|
|
[Notify] private IReleaseDetails? _release;
|
|
[Notify] private float _installProgress;
|
|
[Notify] private bool _isCurrentVersion;
|
|
[Notify] private bool _installationInProgress;
|
|
[Notify] private bool _inDetailsScreen;
|
|
|
|
private CancellationTokenSource? _cts;
|
|
|
|
public EntryReleaseInfoViewModel(IRouter router,
|
|
INotificationService notificationService,
|
|
IWindowService windowService,
|
|
IWorkshopService workshopService,
|
|
IPluginManagementService pluginManagementService,
|
|
ISettingsVmFactory settingsVmFactory)
|
|
{
|
|
_router = router;
|
|
_notificationService = notificationService;
|
|
_windowService = windowService;
|
|
_workshopService = workshopService;
|
|
_pluginManagementService = pluginManagementService;
|
|
_settingsVmFactory = settingsVmFactory;
|
|
_progress.ProgressChanged += (_, f) => InstallProgress = f.ProgressPercentage;
|
|
|
|
this.WhenActivated(d =>
|
|
{
|
|
_workshopService.OnEntryInstalled += WorkshopServiceOnOnEntryInstalled;
|
|
_workshopService.OnEntryUninstalled += WorkshopServiceOnOnEntryInstalled;
|
|
Disposable.Create(() =>
|
|
{
|
|
_workshopService.OnEntryInstalled -= WorkshopServiceOnOnEntryInstalled;
|
|
_workshopService.OnEntryUninstalled -= WorkshopServiceOnOnEntryInstalled;
|
|
}).DisposeWith(d);
|
|
|
|
IsCurrentVersion = Release != null && _workshopService.GetInstalledEntry(Release.Entry.Id)?.ReleaseId == Release.Id;
|
|
});
|
|
|
|
this.WhenAnyValue(vm => vm.Release).Subscribe(r => IsCurrentVersion = r != null && _workshopService.GetInstalledEntry(r.Entry.Id)?.ReleaseId == r.Id);
|
|
|
|
InDetailsScreen = true;
|
|
}
|
|
|
|
private void WorkshopServiceOnOnEntryInstalled(object? sender, InstalledEntry e)
|
|
{
|
|
IsCurrentVersion = Release != null && _workshopService.GetInstalledEntry(Release.Entry.Id)?.ReleaseId == Release.Id;
|
|
}
|
|
|
|
public async Task Close()
|
|
{
|
|
await _router.GoUp();
|
|
}
|
|
|
|
public async Task Install()
|
|
{
|
|
if (Release == null)
|
|
return;
|
|
|
|
// If the entry has missing dependencies, show a dialog
|
|
List<IEntrySummary> missing = Release.Dependencies.Where(d => _workshopService.GetInstalledEntry(d.Id) == null).Cast<IEntrySummary>().ToList();
|
|
if (missing.Count > 0)
|
|
{
|
|
await _windowService.CreateContentDialog()
|
|
.WithTitle("Requirements missing")
|
|
.WithViewModel(out DependenciesDialogViewModel _, Release.Entry, missing)
|
|
.WithCloseButtonText("Cancel installation")
|
|
.ShowAsync();
|
|
return;
|
|
}
|
|
|
|
_cts = new CancellationTokenSource();
|
|
InstallProgress = 0;
|
|
InstallationInProgress = true;
|
|
try
|
|
{
|
|
EntryInstallResult result = await _workshopService.InstallEntry(Release.Entry, Release, _progress, _cts.Token);
|
|
if (result.IsSuccess)
|
|
{
|
|
_notificationService.CreateNotification().WithTitle("Installation succeeded").WithSeverity(NotificationSeverity.Success).Show();
|
|
InstallationInProgress = false;
|
|
await Manage();
|
|
}
|
|
else if (!_cts.IsCancellationRequested)
|
|
_notificationService.CreateNotification().WithTitle("Installation failed").WithMessage(result.Message).WithSeverity(NotificationSeverity.Error).Show();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
_windowService.ShowExceptionDialog("Failed to install workshop entry", e);
|
|
}
|
|
finally
|
|
{
|
|
InstallationInProgress = false;
|
|
}
|
|
}
|
|
|
|
public async Task Manage()
|
|
{
|
|
if (Release?.Entry.EntryType != EntryType.Profile)
|
|
await _router.Navigate("../../manage", new RouterNavigationOptions {AdditionalArguments = true});
|
|
}
|
|
|
|
public async Task Reinstall()
|
|
{
|
|
if (await _windowService.ShowConfirmContentDialog("Reinstall entry", "Are you sure you want to reinstall this entry?"))
|
|
await Install();
|
|
}
|
|
|
|
public async Task Uninstall()
|
|
{
|
|
InstalledEntry? installedEntry = _workshopService.GetInstalledEntry(Release!.Entry.Id);
|
|
if (installedEntry == null)
|
|
return;
|
|
|
|
InstallationInProgress = true;
|
|
try
|
|
{
|
|
bool confirmed = await _windowService.ShowConfirmContentDialog("Do you want to uninstall this entry?", "Both the entry and its contents will be removed.");
|
|
if (!confirmed)
|
|
return;
|
|
|
|
// Ideally the installation handler does this but it doesn't have access to the required view models
|
|
if (installedEntry.EntryType == EntryType.Plugin)
|
|
await UninstallPluginPrerequisites(installedEntry);
|
|
|
|
await _workshopService.UninstallEntry(installedEntry, CancellationToken.None);
|
|
|
|
_notificationService.CreateNotification().WithTitle("Entry uninstalled").WithSeverity(NotificationSeverity.Success).Show();
|
|
}
|
|
finally
|
|
{
|
|
InstallationInProgress = false;
|
|
}
|
|
}
|
|
|
|
public void Cancel()
|
|
{
|
|
_cts?.Cancel();
|
|
}
|
|
|
|
private async Task UninstallPluginPrerequisites(InstalledEntry installedEntry)
|
|
{
|
|
if (!installedEntry.TryGetMetadata("PluginId", out Guid pluginId))
|
|
return;
|
|
Plugin? plugin = _pluginManagementService.GetAllPlugins().FirstOrDefault(p => p.Guid == pluginId);
|
|
if (plugin == null)
|
|
return;
|
|
|
|
PluginViewModel pluginViewModel = _settingsVmFactory.PluginViewModel(plugin, ReactiveCommand.Create(() => { }));
|
|
await pluginViewModel.ExecuteRemovePrerequisites(true);
|
|
}
|
|
} |