From 21b8112de58deb72d8c2d886671a516446b9f4da Mon Sep 17 00:00:00 2001 From: Robert Date: Thu, 15 Feb 2024 22:57:33 +0100 Subject: [PATCH] Workshop - Implemented plugin browsing, installation and removal --- src/Artemis.UI/Artemis.UI.csproj | 20 --- src/Artemis.UI/ArtemisBootstrapper.cs | 1 + src/Artemis.UI/Routing/Routes.cs | 3 + src/Artemis.UI/Screens/Root/RootViewModel.cs | 5 + .../Screens/Sidebar/SidebarViewModel.cs | 1 + .../Workshop/Entries/EntriesViewModel.cs | 3 +- .../Entries/List/EntryListItemViewModel.cs | 1 + .../Entries/Tabs/PluginListView.axaml | 65 ++++++++++ .../Entries/Tabs/PluginListView.axaml.cs | 14 ++ .../Entries/Tabs/PluginListViewModel.cs | 34 +++++ .../Entries/Tabs/ProfileListViewModel.cs | 2 +- .../Workshop/Home/WorkshopHomeView.axaml | 8 ++ .../Workshop/Plugin/PluginDetailsView.axaml | 30 +++++ .../Plugin/PluginDetailsView.axaml.cs | 14 ++ .../Workshop/Plugin/PluginDetailsViewModel.cs | 59 +++++++++ .../EntryInstallationHandlerFactory.cs | 1 + .../EntryUninstallResult.cs | 5 +- .../PluginEntryInstallationHandler.cs | 122 ++++++++++++++++++ .../Services/Interfaces/IWorkshopService.cs | 1 + .../Services/WorkshopService.cs | 48 ++++++- .../WorkshopConstants.cs | 8 +- 21 files changed, 410 insertions(+), 35 deletions(-) create mode 100644 src/Artemis.UI/Screens/Workshop/Entries/Tabs/PluginListView.axaml create mode 100644 src/Artemis.UI/Screens/Workshop/Entries/Tabs/PluginListView.axaml.cs create mode 100644 src/Artemis.UI/Screens/Workshop/Entries/Tabs/PluginListViewModel.cs create mode 100644 src/Artemis.UI/Screens/Workshop/Plugin/PluginDetailsView.axaml create mode 100644 src/Artemis.UI/Screens/Workshop/Plugin/PluginDetailsView.axaml.cs create mode 100644 src/Artemis.UI/Screens/Workshop/Plugin/PluginDetailsViewModel.cs create mode 100644 src/Artemis.WebClient.Workshop/Handlers/InstallationHandlers/Implementations/PluginEntryInstallationHandler.cs diff --git a/src/Artemis.UI/Artemis.UI.csproj b/src/Artemis.UI/Artemis.UI.csproj index 3f5b1f056..0048cffb7 100644 --- a/src/Artemis.UI/Artemis.UI.csproj +++ b/src/Artemis.UI/Artemis.UI.csproj @@ -35,24 +35,4 @@ - - - - PluginSelectionStepView.axaml - Code - - - ProfileAdaptionHintsStepView.axaml - Code - - - ProfileSelectionStepView.axaml - Code - - - - - - - \ No newline at end of file diff --git a/src/Artemis.UI/ArtemisBootstrapper.cs b/src/Artemis.UI/ArtemisBootstrapper.cs index be365cd9f..f869bb8e3 100644 --- a/src/Artemis.UI/ArtemisBootstrapper.cs +++ b/src/Artemis.UI/ArtemisBootstrapper.cs @@ -13,6 +13,7 @@ using Artemis.UI.Shared.Services; using Artemis.VisualScripting.DryIoc; using Artemis.WebClient.Updating.DryIoc; using Artemis.WebClient.Workshop.DryIoc; +using Artemis.WebClient.Workshop.Services; using Avalonia; using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; diff --git a/src/Artemis.UI/Routing/Routes.cs b/src/Artemis.UI/Routing/Routes.cs index 1d4862f44..8e26f8d3b 100644 --- a/src/Artemis.UI/Routing/Routes.cs +++ b/src/Artemis.UI/Routing/Routes.cs @@ -12,6 +12,7 @@ using Artemis.UI.Screens.Workshop.Home; using Artemis.UI.Screens.Workshop.Layout; using Artemis.UI.Screens.Workshop.Library; using Artemis.UI.Screens.Workshop.Library.Tabs; +using Artemis.UI.Screens.Workshop.Plugin; using Artemis.UI.Screens.Workshop.Profile; using Artemis.UI.Shared.Routing; @@ -32,6 +33,8 @@ public static class Routes { Children = new List { + new RouteRegistration("plugins/{page:int}"), + new RouteRegistration("plugins/details/{entryId:long}"), new RouteRegistration("profiles/{page:int}"), new RouteRegistration("profiles/details/{entryId:long}"), new RouteRegistration("layouts/{page:int}"), diff --git a/src/Artemis.UI/Screens/Root/RootViewModel.cs b/src/Artemis.UI/Screens/Root/RootViewModel.cs index e1fb3eeb9..ce83f0742 100644 --- a/src/Artemis.UI/Screens/Root/RootViewModel.cs +++ b/src/Artemis.UI/Screens/Root/RootViewModel.cs @@ -13,6 +13,7 @@ using Artemis.UI.Shared; using Artemis.UI.Shared.Routing; using Artemis.UI.Shared.Services; using Artemis.UI.Shared.Services.MainWindow; +using Artemis.WebClient.Workshop.Services; using Avalonia; using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; @@ -41,6 +42,7 @@ public class RootViewModel : RoutableHostScreen, IMainWindowProv IMainWindowService mainWindowService, IDebugService debugService, IUpdateService updateService, + IWorkshopService workshopService, SidebarViewModel sidebarViewModel, DefaultTitleBarViewModel defaultTitleBarViewModel) { @@ -76,6 +78,9 @@ public class RootViewModel : RoutableHostScreen, IMainWindowProv { if (_updateService.Initialize()) return; + + // Before initializing the core and files become in use, clean up orphaned files + workshopService.RemoveOrphanedFiles(); coreService.Initialize(); registrationService.RegisterBuiltInDataModelDisplays(); diff --git a/src/Artemis.UI/Screens/Sidebar/SidebarViewModel.cs b/src/Artemis.UI/Screens/Sidebar/SidebarViewModel.cs index ae9de0d2c..bb2d56f95 100644 --- a/src/Artemis.UI/Screens/Sidebar/SidebarViewModel.cs +++ b/src/Artemis.UI/Screens/Sidebar/SidebarViewModel.cs @@ -43,6 +43,7 @@ public partial class SidebarViewModel : ActivatableViewModelBase { new(MaterialIconKind.FolderVideo, "Profiles", "workshop/entries/profiles/1", "workshop/entries/profiles"), new(MaterialIconKind.KeyboardVariant, "Layouts", "workshop/entries/layouts/1", "workshop/entries/layouts"), + new(MaterialIconKind.Plugin, "Plugins", "workshop/entries/plugins/1", "workshop/entries/plugins"), new(MaterialIconKind.Bookshelf, "Library", "workshop/library"), }), diff --git a/src/Artemis.UI/Screens/Workshop/Entries/EntriesViewModel.cs b/src/Artemis.UI/Screens/Workshop/Entries/EntriesViewModel.cs index 4ee34fee4..904348bc6 100644 --- a/src/Artemis.UI/Screens/Workshop/Entries/EntriesViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/Entries/EntriesViewModel.cs @@ -25,7 +25,8 @@ public partial class EntriesViewModel : RoutableHostScreen Tabs = new ObservableCollection { new("Profiles", "workshop/entries/profiles/1", "workshop/entries/profiles"), - new("Layouts", "workshop/entries/layouts/1", "workshop/entries/layouts") + new("Layouts", "workshop/entries/layouts/1", "workshop/entries/layouts"), + new("Plugins", "workshop/entries/plugins/1", "workshop/entries/plugins"), }; this.WhenActivated(d => diff --git a/src/Artemis.UI/Screens/Workshop/Entries/List/EntryListItemViewModel.cs b/src/Artemis.UI/Screens/Workshop/Entries/List/EntryListItemViewModel.cs index be57fd898..757396c72 100644 --- a/src/Artemis.UI/Screens/Workshop/Entries/List/EntryListItemViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/Entries/List/EntryListItemViewModel.cs @@ -34,6 +34,7 @@ public class EntryListItemViewModel : ActivatableViewModelBase await _router.Navigate($"workshop/entries/profiles/details/{Entry.Id}"); break; case EntryType.Plugin: + await _router.Navigate($"workshop/entries/plugins/details/{Entry.Id}"); break; default: throw new ArgumentOutOfRangeException(); diff --git a/src/Artemis.UI/Screens/Workshop/Entries/Tabs/PluginListView.axaml b/src/Artemis.UI/Screens/Workshop/Entries/Tabs/PluginListView.axaml new file mode 100644 index 000000000..e52c30641 --- /dev/null +++ b/src/Artemis.UI/Screens/Workshop/Entries/Tabs/PluginListView.axaml @@ -0,0 +1,65 @@ + + + + + + + + + + + Categories + + + + + + + + + + + + + + + + + + + + + + + + + + + Looks like your current filters gave no results + + Modify or clear your filters to view other plugins + + + + + + + + diff --git a/src/Artemis.UI/Screens/Workshop/Entries/Tabs/PluginListView.axaml.cs b/src/Artemis.UI/Screens/Workshop/Entries/Tabs/PluginListView.axaml.cs new file mode 100644 index 000000000..2e32eea93 --- /dev/null +++ b/src/Artemis.UI/Screens/Workshop/Entries/Tabs/PluginListView.axaml.cs @@ -0,0 +1,14 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Markup.Xaml; +using Avalonia.ReactiveUI; + +namespace Artemis.UI.Screens.Workshop.Entries.Tabs; + +public partial class PluginListView : ReactiveUserControl +{ + public PluginListView() + { + InitializeComponent(); + } +} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Workshop/Entries/Tabs/PluginListViewModel.cs b/src/Artemis.UI/Screens/Workshop/Entries/Tabs/PluginListViewModel.cs new file mode 100644 index 000000000..206697490 --- /dev/null +++ b/src/Artemis.UI/Screens/Workshop/Entries/Tabs/PluginListViewModel.cs @@ -0,0 +1,34 @@ +using System; +using Artemis.UI.Screens.Workshop.Categories; +using Artemis.UI.Screens.Workshop.Entries.List; +using Artemis.UI.Shared.Routing; +using Artemis.UI.Shared.Services; +using Artemis.WebClient.Workshop; + +namespace Artemis.UI.Screens.Workshop.Entries.Tabs; + +public class PluginListViewModel : EntryListViewModel +{ + public PluginListViewModel(IWorkshopClient workshopClient, + IRouter router, + CategoriesViewModel categoriesViewModel, + EntryListInputViewModel entryListInputViewModel, + INotificationService notificationService, + Func getEntryListViewModel) + : base("workshop/entries/plugins", workshopClient, router, categoriesViewModel, entryListInputViewModel, notificationService, getEntryListViewModel) + { + entryListInputViewModel.SearchWatermark = "Search plugins"; + } + + protected override EntryFilterInput GetFilter() + { + return new EntryFilterInput + { + And = new[] + { + new EntryFilterInput {EntryType = new EntryTypeOperationFilterInput {Eq = EntryType.Plugin}}, + base.GetFilter() + } + }; + } +} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Workshop/Entries/Tabs/ProfileListViewModel.cs b/src/Artemis.UI/Screens/Workshop/Entries/Tabs/ProfileListViewModel.cs index c09a587a3..f251ee10d 100644 --- a/src/Artemis.UI/Screens/Workshop/Entries/Tabs/ProfileListViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/Entries/Tabs/ProfileListViewModel.cs @@ -12,7 +12,7 @@ public class ProfileListViewModel : List.EntryListViewModel public ProfileListViewModel(IWorkshopClient workshopClient, IRouter router, CategoriesViewModel categoriesViewModel, - List.EntryListInputViewModel entryListInputViewModel, + EntryListInputViewModel entryListInputViewModel, INotificationService notificationService, Func getEntryListViewModel) : base("workshop/entries/profiles", workshopClient, router, categoriesViewModel, entryListInputViewModel, notificationService, getEntryListViewModel) diff --git a/src/Artemis.UI/Screens/Workshop/Home/WorkshopHomeView.axaml b/src/Artemis.UI/Screens/Workshop/Home/WorkshopHomeView.axaml index 433f87c50..4bc7bd2a4 100644 --- a/src/Artemis.UI/Screens/Workshop/Home/WorkshopHomeView.axaml +++ b/src/Artemis.UI/Screens/Workshop/Home/WorkshopHomeView.axaml @@ -57,6 +57,14 @@ + +