mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-12 11:56:30 +00:00
Core - Added API for retrieving current suspended device providers
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
This commit is contained in:
1 parent
86f78940b1
commit
648b7765ef
20 files changed
+440
-106
No files matched your search
@@ -0,0 +1,44 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:dialogs="clr-namespace:Artemis.UI.Screens.Workshop.EntryReleases.Dialogs"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Artemis.UI.Screens.Workshop.EntryReleases.Dialogs.DependenciesDialogView"
|
||||
x:DataType="dialogs:DependenciesDialogViewModel">
|
||||
<StackPanel>
|
||||
<TextBlock IsVisible="{CompiledBinding Multiple}">
|
||||
<Run Text="Some or all of the required" />
|
||||
<Run Text="{CompiledBinding EntryTypePlural}" />
|
||||
<Run Text="are not installed. This" />
|
||||
<Run Text="{CompiledBinding DependantType}" />
|
||||
<Run Text="will not work properly without them. The missing" />
|
||||
<Run Text="{CompiledBinding EntryTypePlural}" />
|
||||
<Run Text="are listed below and you can click on them to view them" />
|
||||
</TextBlock>
|
||||
<TextBlock IsVisible="{CompiledBinding !Multiple}">
|
||||
<Run Text="A required" />
|
||||
<Run Text="{CompiledBinding EntryType}" />
|
||||
<Run Text="is not installed. This" />
|
||||
<Run Text="{CompiledBinding DependantType}" />
|
||||
<Run Text="will not work properly without it. The missing" />
|
||||
<Run Text="{CompiledBinding EntryType}" />
|
||||
<Run Text="is listed below and you can click on it to view it" />
|
||||
</TextBlock>
|
||||
|
||||
<ScrollViewer MaxHeight="500" Margin="0 30 0 0">
|
||||
<ItemsControl ItemsSource="{CompiledBinding Dependencies}" >
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<VirtualizingStackPanel />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<ContentControl Content="{CompiledBinding}" Margin="0 0 0 5"></ContentControl>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</ScrollViewer>
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,14 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Screens.Workshop.EntryReleases.Dialogs;
|
||||
|
||||
public partial class DependenciesDialogView : ReactiveUserControl<DependenciesDialogViewModel>
|
||||
{
|
||||
public DependenciesDialogView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Reactive.Linq;
|
||||
using Artemis.UI.Screens.Workshop.Entries.List;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Routing;
|
||||
using Artemis.WebClient.Workshop;
|
||||
using Humanizer;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Screens.Workshop.EntryReleases.Dialogs;
|
||||
|
||||
public class DependenciesDialogViewModel : ContentDialogViewModelBase
|
||||
{
|
||||
public DependenciesDialogViewModel(IEntrySummary dependant, List<IEntrySummary> dependencies, Func<IEntrySummary, EntryListItemViewModel> getEntryListItemViewModel, IRouter router)
|
||||
{
|
||||
Dependant = dependant;
|
||||
DependantType = dependant.EntryType.Humanize(LetterCasing.LowerCase);
|
||||
EntryType = dependencies.First().EntryType.Humanize(LetterCasing.LowerCase);
|
||||
EntryTypePlural = dependencies.First().EntryType.Humanize(LetterCasing.LowerCase).Pluralize();
|
||||
Dependencies = new ObservableCollection<EntryListItemViewModel>(dependencies.Select(getEntryListItemViewModel));
|
||||
|
||||
this.WhenActivated(d => router.CurrentPath.Skip(1).Subscribe(s => ContentDialog?.Hide()).DisposeWith(d));
|
||||
}
|
||||
|
||||
public string DependantType { get; }
|
||||
public string EntryType { get; }
|
||||
public string EntryTypePlural { get; }
|
||||
public bool Multiple => Dependencies.Count > 1;
|
||||
|
||||
public IEntrySummary Dependant { get; }
|
||||
public ObservableCollection<EntryListItemViewModel> Dependencies { get; }
|
||||
}
|
||||
@@ -1,13 +1,14 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reactive.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;
|
||||
@@ -17,7 +18,6 @@ using Artemis.WebClient.Workshop;
|
||||
using Artemis.WebClient.Workshop.Handlers.InstallationHandlers;
|
||||
using Artemis.WebClient.Workshop.Models;
|
||||
using Artemis.WebClient.Workshop.Services;
|
||||
using Humanizer;
|
||||
using PropertyChanged.SourceGenerator;
|
||||
using ReactiveUI;
|
||||
|
||||
@@ -30,13 +30,12 @@ public partial class EntryReleaseInfoViewModel : ActivatableViewModelBase
|
||||
private readonly IWindowService _windowService;
|
||||
private readonly IWorkshopService _workshopService;
|
||||
private readonly IPluginManagementService _pluginManagementService;
|
||||
private readonly EntryInstallationHandlerFactory _factory;
|
||||
private readonly ISettingsVmFactory _settingsVmFactory;
|
||||
private readonly Progress<StreamProgress> _progress = new();
|
||||
private readonly ObservableAsPropertyHelper<bool> _isCurrentVersion;
|
||||
|
||||
[Notify] private IReleaseDetails? _release;
|
||||
[Notify] private float _installProgress;
|
||||
[Notify] private bool _isCurrentVersion;
|
||||
[Notify] private bool _installationInProgress;
|
||||
[Notify] private bool _inDetailsScreen;
|
||||
|
||||
@@ -47,7 +46,6 @@ public partial class EntryReleaseInfoViewModel : ActivatableViewModelBase
|
||||
IWindowService windowService,
|
||||
IWorkshopService workshopService,
|
||||
IPluginManagementService pluginManagementService,
|
||||
EntryInstallationHandlerFactory factory,
|
||||
ISettingsVmFactory settingsVmFactory)
|
||||
{
|
||||
_router = router;
|
||||
@@ -55,18 +53,31 @@ public partial class EntryReleaseInfoViewModel : ActivatableViewModelBase
|
||||
_windowService = windowService;
|
||||
_workshopService = workshopService;
|
||||
_pluginManagementService = pluginManagementService;
|
||||
_factory = factory;
|
||||
_settingsVmFactory = settingsVmFactory;
|
||||
_progress.ProgressChanged += (_, f) => InstallProgress = f.ProgressPercentage;
|
||||
|
||||
_isCurrentVersion = this.WhenAnyValue(vm => vm.Release, vm => vm.InstallationInProgress, (release, _) => release)
|
||||
.Select(r => r != null && _workshopService.GetInstalledEntry(r.Entry.Id)?.ReleaseId == r.Id)
|
||||
.ToProperty(this, vm => vm.IsCurrentVersion);
|
||||
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;
|
||||
}
|
||||
|
||||
public bool IsCurrentVersion => _isCurrentVersion.Value;
|
||||
private void WorkshopServiceOnOnEntryInstalled(object? sender, InstalledEntry e)
|
||||
{
|
||||
IsCurrentVersion = Release != null && _workshopService.GetInstalledEntry(Release.Entry.Id)?.ReleaseId == Release.Id;
|
||||
}
|
||||
|
||||
public async Task Close()
|
||||
{
|
||||
@@ -79,15 +90,15 @@ public partial class EntryReleaseInfoViewModel : ActivatableViewModelBase
|
||||
return;
|
||||
|
||||
// If the entry has missing dependencies, show a dialog
|
||||
foreach (IGetEntryById_Entry_LatestRelease_Dependencies dependency in Release.Dependencies)
|
||||
List<IEntrySummary> missing = Release.Dependencies.Where(d => _workshopService.GetInstalledEntry(d.Id) == null).Cast<IEntrySummary>().ToList();
|
||||
if (missing.Count > 0)
|
||||
{
|
||||
if (_workshopService.GetInstalledEntry(dependency.Id) == null)
|
||||
{
|
||||
if (await _windowService.ShowConfirmContentDialog("Missing dependencies",
|
||||
$"One or more dependencies are missing, this {Release.Entry.EntryType.Humanize(LetterCasing.LowerCase)} won't work without them", "View dependencies"))
|
||||
await _router.GoUp();
|
||||
return;
|
||||
}
|
||||
await _windowService.CreateContentDialog()
|
||||
.WithTitle("Requirements missing")
|
||||
.WithViewModel(out DependenciesDialogViewModel _, Release.Entry, missing)
|
||||
.WithCloseButtonText("Cancel installation")
|
||||
.ShowAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
_cts = new CancellationTokenSource();
|
||||
@@ -95,8 +106,7 @@ public partial class EntryReleaseInfoViewModel : ActivatableViewModelBase
|
||||
InstallationInProgress = true;
|
||||
try
|
||||
{
|
||||
IEntryInstallationHandler handler = _factory.CreateHandler(Release.Entry.EntryType);
|
||||
EntryInstallResult result = await handler.InstallAsync(Release.Entry, Release, _progress, _cts.Token);
|
||||
EntryInstallResult result = await _workshopService.InstallEntry(Release.Entry, Release, _progress, _cts.Token);
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
_notificationService.CreateNotification().WithTitle("Installation succeeded").WithSeverity(NotificationSeverity.Success).Show();
|
||||
@@ -145,8 +155,9 @@ public partial class EntryReleaseInfoViewModel : ActivatableViewModelBase
|
||||
if (installedEntry.EntryType == EntryType.Plugin)
|
||||
await UninstallPluginPrerequisites(installedEntry);
|
||||
|
||||
IEntryInstallationHandler handler = _factory.CreateHandler(installedEntry.EntryType);
|
||||
await handler.UninstallAsync(installedEntry, CancellationToken.None);
|
||||
await _workshopService.UninstallEntry(installedEntry, CancellationToken.None);
|
||||
|
||||
_notificationService.CreateNotification().WithTitle("Entry uninstalled").WithSeverity(NotificationSeverity.Success).Show();
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using System;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Reactive.Linq;
|
||||
using System.Reactive.Disposables;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.WebClient.Workshop;
|
||||
using Artemis.WebClient.Workshop.Models;
|
||||
@@ -22,19 +20,24 @@ public partial class EntryReleaseItemViewModel : ActivatableViewModelBase
|
||||
_entry = entry;
|
||||
|
||||
Release = release;
|
||||
UpdateIsCurrentVersion();
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
Observable.FromEventPattern<InstalledEntry>(x => _workshopService.OnInstalledEntrySaved += x, x => _workshopService.OnInstalledEntrySaved -= x)
|
||||
.Subscribe(_ => UpdateIsCurrentVersion())
|
||||
.DisposeWith(d);
|
||||
_workshopService.OnEntryInstalled += WorkshopServiceOnOnEntryInstalled;
|
||||
_workshopService.OnEntryUninstalled += WorkshopServiceOnOnEntryInstalled;
|
||||
Disposable.Create(() =>
|
||||
{
|
||||
_workshopService.OnEntryInstalled -= WorkshopServiceOnOnEntryInstalled;
|
||||
_workshopService.OnEntryUninstalled -= WorkshopServiceOnOnEntryInstalled;
|
||||
}).DisposeWith(d);
|
||||
|
||||
IsCurrentVersion = _workshopService.GetInstalledEntry(_entry.Id)?.ReleaseId == Release.Id;
|
||||
});
|
||||
}
|
||||
|
||||
public IRelease Release { get; }
|
||||
|
||||
private void UpdateIsCurrentVersion()
|
||||
private void WorkshopServiceOnOnEntryInstalled(object? sender, InstalledEntry e)
|
||||
{
|
||||
IsCurrentVersion = _workshopService.GetInstalledEntry(_entry.Id)?.ReleaseId == Release.Id;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user