diff --git a/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryInfoViewModel.cs b/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryInfoViewModel.cs index 24bb74225..d5c4de433 100644 --- a/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryInfoViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryInfoViewModel.cs @@ -10,10 +10,10 @@ namespace Artemis.UI.Screens.Workshop.Entries.Details; public class EntryInfoViewModel : ViewModelBase { private readonly INotificationService _notificationService; - public IGetEntryById_Entry Entry { get; } + public IEntryDetails Entry { get; } public DateTimeOffset? UpdatedAt { get; } - public EntryInfoViewModel(IGetEntryById_Entry entry, INotificationService notificationService) + public EntryInfoViewModel(IEntryDetails entry, INotificationService notificationService) { _notificationService = notificationService; Entry = entry; diff --git a/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryReleasesViewModel.cs b/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryReleasesViewModel.cs index 21be13b28..12bd22b3a 100644 --- a/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryReleasesViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryReleasesViewModel.cs @@ -20,7 +20,7 @@ public class EntryReleasesViewModel : ViewModelBase private readonly IWindowService _windowService; private readonly INotificationService _notificationService; - public EntryReleasesViewModel(IGetEntryById_Entry entry, EntryInstallationHandlerFactory factory, IWindowService windowService, INotificationService notificationService) + public EntryReleasesViewModel(IEntryDetails entry, EntryInstallationHandlerFactory factory, IWindowService windowService, INotificationService notificationService) { _factory = factory; _windowService = windowService; @@ -31,7 +31,7 @@ public class EntryReleasesViewModel : ViewModelBase OnInstallationStarted = Confirm; } - public IGetEntryById_Entry Entry { get; } + public IEntryDetails Entry { get; } public ReactiveCommand DownloadLatestRelease { get; } public Func> OnInstallationStarted { get; set; } diff --git a/src/Artemis.UI/Screens/Workshop/Entries/List/EntryListItemView.axaml b/src/Artemis.UI/Screens/Workshop/Entries/List/EntryListItemView.axaml index f041d5655..91932033a 100644 --- a/src/Artemis.UI/Screens/Workshop/Entries/List/EntryListItemView.axaml +++ b/src/Artemis.UI/Screens/Workshop/Entries/List/EntryListItemView.axaml @@ -21,9 +21,11 @@ HorizontalContentAlignment="Stretch" Command="{CompiledBinding NavigateToEntry}" IsVisible="{CompiledBinding Entry, Converter={x:Static ObjectConverters.IsNotNull}}"> - + - + by @@ -65,7 +67,7 @@ - + @@ -73,6 +75,18 @@ downloads + + + + + + installed + + + + update available + + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Workshop/Entries/List/EntryListItemViewModel.cs b/src/Artemis.UI/Screens/Workshop/Entries/List/EntryListItemViewModel.cs index 757396c72..d129f9be6 100644 --- a/src/Artemis.UI/Screens/Workshop/Entries/List/EntryListItemViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/Entries/List/EntryListItemViewModel.cs @@ -1,26 +1,39 @@ using System; using System.Reactive; +using System.Reactive.Disposables; using System.Threading.Tasks; using Artemis.UI.Shared; using Artemis.UI.Shared.Routing; using Artemis.WebClient.Workshop; +using Artemis.WebClient.Workshop.Models; +using Artemis.WebClient.Workshop.Services; +using PropertyChanged.SourceGenerator; using ReactiveUI; namespace Artemis.UI.Screens.Workshop.Entries.List; -public class EntryListItemViewModel : ActivatableViewModelBase +public partial class EntryListItemViewModel : ActivatableViewModelBase { private readonly IRouter _router; + [Notify] private bool _isInstalled; + [Notify] private bool _updateAvailable; - public EntryListItemViewModel(IGetEntries_Entries_Items entry, IRouter router) + public EntryListItemViewModel(IEntrySummary entry, IRouter router, IWorkshopService workshopService) { _router = router; Entry = entry; NavigateToEntry = ReactiveCommand.CreateFromTask(ExecuteNavigateToEntry); + + this.WhenActivated((CompositeDisposable _) => + { + InstalledEntry? installedEntry = workshopService.GetInstalledEntry(entry.Id); + IsInstalled = installedEntry != null; + UpdateAvailable = installedEntry != null && installedEntry.ReleaseId != entry.LatestReleaseId; + }); } - public IGetEntries_Entries_Items Entry { get; } + public IEntrySummary Entry { get; } public ReactiveCommand NavigateToEntry { get; } private async Task ExecuteNavigateToEntry() diff --git a/src/Artemis.UI/Screens/Workshop/Entries/List/EntryListViewModel.cs b/src/Artemis.UI/Screens/Workshop/Entries/List/EntryListViewModel.cs index 7bbd75704..4d831ba29 100644 --- a/src/Artemis.UI/Screens/Workshop/Entries/List/EntryListViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/Entries/List/EntryListViewModel.cs @@ -21,7 +21,7 @@ namespace Artemis.UI.Screens.Workshop.Entries.List; public abstract partial class EntryListViewModel : RoutableScreen { - private readonly SourceList _entries = new(); + private readonly SourceList _entries = new(); private readonly ObservableAsPropertyHelper _isLoading; private readonly INotificationService _notificationService; private readonly string _route; @@ -37,13 +37,13 @@ public abstract partial class EntryListViewModel : RoutableScreen getEntryListViewModel) + Func getEntryListViewModel) { _route = route; _workshopClient = workshopClient; _notificationService = notificationService; - _showPagination = this.WhenAnyValue(vm => vm.TotalPages).Select(t => t > 1).ToProperty(this, vm => vm.ShowPagination); - _isLoading = this.WhenAnyValue(vm => vm.Page, vm => vm.LoadedPage, (p, c) => p != c).ToProperty(this, vm => vm.IsLoading); + _showPagination = this.WhenAnyValue(vm => vm.TotalPages).Select(t => t > 1).ToProperty(this, vm => vm.ShowPagination); + _isLoading = this.WhenAnyValue(vm => vm.Page, vm => vm.LoadedPage, (p, c) => p != c).ToProperty(this, vm => vm.IsLoading); CategoriesViewModel = categoriesViewModel; InputViewModel = entryListInputViewModel; diff --git a/src/Artemis.UI/Screens/Workshop/Entries/Tabs/LayoutListViewModel.cs b/src/Artemis.UI/Screens/Workshop/Entries/Tabs/LayoutListViewModel.cs index ed2fa328b..ca0cdbb99 100644 --- a/src/Artemis.UI/Screens/Workshop/Entries/Tabs/LayoutListViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/Entries/Tabs/LayoutListViewModel.cs @@ -14,7 +14,7 @@ public class LayoutListViewModel : List.EntryListViewModel CategoriesViewModel categoriesViewModel, EntryListInputViewModel entryListInputViewModel, INotificationService notificationService, - Func getEntryListViewModel) + Func getEntryListViewModel) : base("workshop/entries/layouts", workshopClient, router, categoriesViewModel, entryListInputViewModel, notificationService, getEntryListViewModel) { entryListInputViewModel.SearchWatermark = "Search layouts"; diff --git a/src/Artemis.UI/Screens/Workshop/Entries/Tabs/PluginListViewModel.cs b/src/Artemis.UI/Screens/Workshop/Entries/Tabs/PluginListViewModel.cs index 206697490..7af13b4e4 100644 --- a/src/Artemis.UI/Screens/Workshop/Entries/Tabs/PluginListViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/Entries/Tabs/PluginListViewModel.cs @@ -14,7 +14,7 @@ public class PluginListViewModel : EntryListViewModel CategoriesViewModel categoriesViewModel, EntryListInputViewModel entryListInputViewModel, INotificationService notificationService, - Func getEntryListViewModel) + Func getEntryListViewModel) : base("workshop/entries/plugins", workshopClient, router, categoriesViewModel, entryListInputViewModel, notificationService, getEntryListViewModel) { entryListInputViewModel.SearchWatermark = "Search plugins"; diff --git a/src/Artemis.UI/Screens/Workshop/Entries/Tabs/ProfileListViewModel.cs b/src/Artemis.UI/Screens/Workshop/Entries/Tabs/ProfileListViewModel.cs index f251ee10d..d8ae07a17 100644 --- a/src/Artemis.UI/Screens/Workshop/Entries/Tabs/ProfileListViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/Entries/Tabs/ProfileListViewModel.cs @@ -14,7 +14,7 @@ public class ProfileListViewModel : List.EntryListViewModel CategoriesViewModel categoriesViewModel, EntryListInputViewModel entryListInputViewModel, INotificationService notificationService, - Func getEntryListViewModel) + Func getEntryListViewModel) : base("workshop/entries/profiles", workshopClient, router, categoriesViewModel, entryListInputViewModel, notificationService, getEntryListViewModel) { entryListInputViewModel.SearchWatermark = "Search profiles"; diff --git a/src/Artemis.UI/Screens/Workshop/Layout/LayoutDetailsView.axaml b/src/Artemis.UI/Screens/Workshop/Layout/LayoutDetailsView.axaml index cc566cbd3..3dd205871 100644 --- a/src/Artemis.UI/Screens/Workshop/Layout/LayoutDetailsView.axaml +++ b/src/Artemis.UI/Screens/Workshop/Layout/LayoutDetailsView.axaml @@ -17,13 +17,17 @@ - - - - - - - + + + + + + + + + + + diff --git a/src/Artemis.UI/Screens/Workshop/Layout/LayoutDetailsViewModel.cs b/src/Artemis.UI/Screens/Workshop/Layout/LayoutDetailsViewModel.cs index 1c12e2dbf..9663f5ad4 100644 --- a/src/Artemis.UI/Screens/Workshop/Layout/LayoutDetailsViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/Layout/LayoutDetailsViewModel.cs @@ -24,10 +24,10 @@ public partial class LayoutDetailsViewModel : RoutableScreen _getEntryInfoViewModel; - private readonly Func _getEntryReleasesViewModel; - private readonly Func _getEntryImagesViewModel; - [Notify] private IGetEntryById_Entry? _entry; + private readonly Func _getEntryInfoViewModel; + private readonly Func _getEntryReleasesViewModel; + private readonly Func _getEntryImagesViewModel; + [Notify] private IEntryDetails? _entry; [Notify] private EntryInfoViewModel? _entryInfoViewModel; [Notify] private EntryReleasesViewModel? _entryReleasesViewModel; [Notify] private EntryImagesViewModel? _entryImagesViewModel; @@ -35,9 +35,9 @@ public partial class LayoutDetailsViewModel : RoutableScreen getEntryInfoViewModel, - Func getEntryReleasesViewModel, - Func getEntryImagesViewModel) + Func getEntryInfoViewModel, + Func getEntryReleasesViewModel, + Func getEntryImagesViewModel) { _client = client; _deviceService = deviceService; @@ -59,19 +59,12 @@ public partial class LayoutDetailsViewModel : RoutableScreen - - - - - - - + + + + + + + + + + + + + Used by these profiles + + + + + + + + diff --git a/src/Artemis.UI/Screens/Workshop/Plugins/PluginDetailsViewModel.cs b/src/Artemis.UI/Screens/Workshop/Plugins/PluginDetailsViewModel.cs index bfce68a94..be800a735 100644 --- a/src/Artemis.UI/Screens/Workshop/Plugins/PluginDetailsViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/Plugins/PluginDetailsViewModel.cs @@ -1,10 +1,13 @@ using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Linq; using System.Threading; using System.Threading.Tasks; using Artemis.Core; using Artemis.Core.Services; using Artemis.UI.Screens.Workshop.Entries.Details; +using Artemis.UI.Screens.Workshop.Entries.List; using Artemis.UI.Screens.Workshop.Parameters; using Artemis.UI.Screens.Workshop.Plugins.Dialogs; using Artemis.UI.Shared.Routing; @@ -21,20 +24,23 @@ public partial class PluginDetailsViewModel : RoutableScreen _getEntryInfoViewModel; - private readonly Func _getEntryReleasesViewModel; - private readonly Func _getEntryImagesViewModel; - [Notify] private IGetEntryById_Entry? _entry; + private readonly Func _getEntryInfoViewModel; + private readonly Func _getEntryReleasesViewModel; + private readonly Func _getEntryImagesViewModel; + private readonly Func _getEntryListViewModel; + [Notify] private IEntryDetails? _entry; [Notify] private EntryInfoViewModel? _entryInfoViewModel; [Notify] private EntryReleasesViewModel? _entryReleasesViewModel; [Notify] private EntryImagesViewModel? _entryImagesViewModel; - + [Notify] private ReadOnlyObservableCollection? _dependants; + public PluginDetailsViewModel(IWorkshopClient client, IWindowService windowService, IPluginManagementService pluginManagementService, - Func getEntryInfoViewModel, - Func getEntryReleasesViewModel, - Func getEntryImagesViewModel) + Func getEntryInfoViewModel, + Func getEntryReleasesViewModel, + Func getEntryImagesViewModel, + Func getEntryListViewModel) { _client = client; _windowService = windowService; @@ -42,6 +48,7 @@ public partial class PluginDetailsViewModel : RoutableScreen? dependants = (await _client.GetDependantEntries.ExecuteAsync(entryId, 0, 25, cancellationToken)).Data?.Entries?.Items; + Dependants = dependants != null && dependants.Any() + ? new ReadOnlyObservableCollection(new ObservableCollection(dependants.Select(_getEntryListViewModel))) + : null; } private async Task OnInstallationStarted(IEntryDetails entryDetails) diff --git a/src/Artemis.UI/Screens/Workshop/Profile/ProfileDetailsView.axaml b/src/Artemis.UI/Screens/Workshop/Profile/ProfileDetailsView.axaml index 0569ee176..499a5b978 100644 --- a/src/Artemis.UI/Screens/Workshop/Profile/ProfileDetailsView.axaml +++ b/src/Artemis.UI/Screens/Workshop/Profile/ProfileDetailsView.axaml @@ -17,13 +17,28 @@ - - - - - - - + + + + + + + + + + + + + Required plugins + + + + + + + + + diff --git a/src/Artemis.UI/Screens/Workshop/Profile/ProfileDetailsViewModel.cs b/src/Artemis.UI/Screens/Workshop/Profile/ProfileDetailsViewModel.cs index 6c65b78c4..8aadc53d4 100644 --- a/src/Artemis.UI/Screens/Workshop/Profile/ProfileDetailsViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/Profile/ProfileDetailsViewModel.cs @@ -1,7 +1,11 @@ using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; using System.Threading; using System.Threading.Tasks; using Artemis.UI.Screens.Workshop.Entries.Details; +using Artemis.UI.Screens.Workshop.Entries.List; using Artemis.UI.Screens.Workshop.Parameters; using Artemis.UI.Shared.Routing; using Artemis.WebClient.Workshop; @@ -13,23 +17,28 @@ namespace Artemis.UI.Screens.Workshop.Profile; public partial class ProfileDetailsViewModel : RoutableScreen { private readonly IWorkshopClient _client; - private readonly Func _getEntryInfoViewModel; - private readonly Func _getEntryReleasesViewModel; - private readonly Func _getEntryImagesViewModel; - [Notify] private IGetEntryById_Entry? _entry; + private readonly Func _getEntryInfoViewModel; + private readonly Func _getEntryReleasesViewModel; + private readonly Func _getEntryImagesViewModel; + private readonly Func _getEntryListViewModel; + + [Notify] private IEntryDetails? _entry; [Notify] private EntryInfoViewModel? _entryInfoViewModel; [Notify] private EntryReleasesViewModel? _entryReleasesViewModel; [Notify] private EntryImagesViewModel? _entryImagesViewModel; + [Notify] private ReadOnlyObservableCollection? _dependencies; public ProfileDetailsViewModel(IWorkshopClient client, - Func getEntryInfoViewModel, - Func getEntryReleasesViewModel, - Func getEntryImagesViewModel) + Func getEntryInfoViewModel, + Func getEntryReleasesViewModel, + Func getEntryImagesViewModel, + Func getEntryListViewModel) { _client = client; _getEntryInfoViewModel = getEntryInfoViewModel; _getEntryReleasesViewModel = getEntryReleasesViewModel; _getEntryImagesViewModel = getEntryImagesViewModel; + _getEntryListViewModel = getEntryListViewModel; } public override async Task OnNavigating(WorkshopDetailParameters parameters, NavigationArguments args, CancellationToken cancellationToken) @@ -44,16 +53,13 @@ public partial class ProfileDetailsViewModel : RoutableScreen? dependencies = (await _client.GetLatestDependencies.ExecuteAsync(entryId, cancellationToken)).Data?.Entry?.LatestRelease?.Dependencies; + Dependencies = dependencies != null && dependencies.Any() + ? new ReadOnlyObservableCollection(new ObservableCollection(dependencies.Select(_getEntryListViewModel))) + : null; } } \ No newline at end of file diff --git a/src/Artemis.WebClient.Workshop/Handlers/InstallationHandlers/Implementations/LayoutEntryInstallationHandler.cs b/src/Artemis.WebClient.Workshop/Handlers/InstallationHandlers/Implementations/LayoutEntryInstallationHandler.cs index aa755b8a0..3014950f7 100644 --- a/src/Artemis.WebClient.Workshop/Handlers/InstallationHandlers/Implementations/LayoutEntryInstallationHandler.cs +++ b/src/Artemis.WebClient.Workshop/Handlers/InstallationHandlers/Implementations/LayoutEntryInstallationHandler.cs @@ -41,7 +41,7 @@ public class LayoutEntryInstallationHandler : IEntryInstallationHandler } // Ensure there is an installed entry - InstalledEntry installedEntry = _workshopService.GetInstalledEntry(entry) ?? new InstalledEntry(entry, release); + InstalledEntry installedEntry = _workshopService.GetInstalledEntry(entry.Id) ?? new InstalledEntry(entry, release); DirectoryInfo releaseDirectory = installedEntry.GetReleaseDirectory(release); // If the folder already exists, remove it so that if the layout now contains less files, old things dont stick around diff --git a/src/Artemis.WebClient.Workshop/Handlers/InstallationHandlers/Implementations/PluginEntryInstallationHandler.cs b/src/Artemis.WebClient.Workshop/Handlers/InstallationHandlers/Implementations/PluginEntryInstallationHandler.cs index 7b9fc5539..34f0aac53 100644 --- a/src/Artemis.WebClient.Workshop/Handlers/InstallationHandlers/Implementations/PluginEntryInstallationHandler.cs +++ b/src/Artemis.WebClient.Workshop/Handlers/InstallationHandlers/Implementations/PluginEntryInstallationHandler.cs @@ -25,7 +25,7 @@ public class PluginEntryInstallationHandler : IEntryInstallationHandler public async Task InstallAsync(IEntryDetails entry, IRelease release, Progress progress, CancellationToken cancellationToken) { // Ensure there is an installed entry - InstalledEntry? installedEntry = _workshopService.GetInstalledEntry(entry); + InstalledEntry? installedEntry = _workshopService.GetInstalledEntry(entry.Id); if (installedEntry != null) { // If the folder already exists, we're not going to reinstall the plugin since files may be in use, consider our job done diff --git a/src/Artemis.WebClient.Workshop/Handlers/InstallationHandlers/Implementations/ProfileEntryInstallationHandler.cs b/src/Artemis.WebClient.Workshop/Handlers/InstallationHandlers/Implementations/ProfileEntryInstallationHandler.cs index 78c31e98c..218665d05 100644 --- a/src/Artemis.WebClient.Workshop/Handlers/InstallationHandlers/Implementations/ProfileEntryInstallationHandler.cs +++ b/src/Artemis.WebClient.Workshop/Handlers/InstallationHandlers/Implementations/ProfileEntryInstallationHandler.cs @@ -36,7 +36,7 @@ public class ProfileEntryInstallationHandler : IEntryInstallationHandler } // Find existing installation to potentially replace the profile - InstalledEntry? installedEntry = _workshopService.GetInstalledEntry(entry); + InstalledEntry? installedEntry = _workshopService.GetInstalledEntry(entry.Id); if (installedEntry != null && installedEntry.TryGetMetadata("ProfileId", out Guid profileId)) { ProfileConfiguration? existing = _profileService.ProfileCategories.SelectMany(c => c.ProfileConfigurations).FirstOrDefault(c => c.ProfileId == profileId); diff --git a/src/Artemis.WebClient.Workshop/Queries/Fragments.graphql b/src/Artemis.WebClient.Workshop/Queries/Fragments.graphql index a66c3a660..c89bf34f6 100644 --- a/src/Artemis.WebClient.Workshop/Queries/Fragments.graphql +++ b/src/Artemis.WebClient.Workshop/Queries/Fragments.graphql @@ -28,6 +28,20 @@ fragment submittedEntry on Entry { createdAt } +fragment entrySummary on Entry { + id + author + name + summary + entryType + downloads + createdAt + latestReleaseId + categories { + ...category + } +} + fragment entryDetails on Entry { id author diff --git a/src/Artemis.WebClient.Workshop/Queries/GetDependantEntries.graphql b/src/Artemis.WebClient.Workshop/Queries/GetDependantEntries.graphql new file mode 100644 index 000000000..551cb140e --- /dev/null +++ b/src/Artemis.WebClient.Workshop/Queries/GetDependantEntries.graphql @@ -0,0 +1,15 @@ +query GetDependantEntries($entryId: Long! $skip: Int $take: Int) { + entries( + where: { + latestRelease: { dependencies: { some: { id: { eq: $entryId } } } } + } + skip: $skip + take: $take + order: { createdAt: DESC } + ) { + totalCount + items { + ...entrySummary + } + } +} diff --git a/src/Artemis.WebClient.Workshop/Queries/GetEntries.graphql b/src/Artemis.WebClient.Workshop/Queries/GetEntries.graphql index 366e3bae4..456466a30 100644 --- a/src/Artemis.WebClient.Workshop/Queries/GetEntries.graphql +++ b/src/Artemis.WebClient.Workshop/Queries/GetEntries.graphql @@ -2,16 +2,7 @@ query GetEntries($search: String $filter: EntryFilterInput $skip: Int $take: Int entries(search: $search where: $filter skip: $skip take: $take, order: $order) { totalCount items { - id - author - name - summary - entryType - downloads - createdAt - categories { - ...category - } + ...entrySummary } } } \ No newline at end of file diff --git a/src/Artemis.WebClient.Workshop/Queries/GetLatestDependencies.graphql b/src/Artemis.WebClient.Workshop/Queries/GetLatestDependencies.graphql new file mode 100644 index 000000000..67987cde5 --- /dev/null +++ b/src/Artemis.WebClient.Workshop/Queries/GetLatestDependencies.graphql @@ -0,0 +1,9 @@ +query GetLatestDependencies($id: Long!) { + entry(id: $id) { + latestRelease { + dependencies { + ...entrySummary + } + } + } +} diff --git a/src/Artemis.WebClient.Workshop/Services/Interfaces/IWorkshopService.cs b/src/Artemis.WebClient.Workshop/Services/Interfaces/IWorkshopService.cs index 7bc1a04c1..ea61b3b6d 100644 --- a/src/Artemis.WebClient.Workshop/Services/Interfaces/IWorkshopService.cs +++ b/src/Artemis.WebClient.Workshop/Services/Interfaces/IWorkshopService.cs @@ -14,7 +14,7 @@ public interface IWorkshopService Task NavigateToEntry(long entryId, EntryType entryType); List GetInstalledEntries(); - InstalledEntry? GetInstalledEntry(IEntryDetails entry); + InstalledEntry? GetInstalledEntry(long entryId); void RemoveInstalledEntry(InstalledEntry installedEntry); void SaveInstalledEntry(InstalledEntry entry); void Initialize(); diff --git a/src/Artemis.WebClient.Workshop/Services/WorkshopService.cs b/src/Artemis.WebClient.Workshop/Services/WorkshopService.cs index 0721c97f0..95b90ccc5 100644 --- a/src/Artemis.WebClient.Workshop/Services/WorkshopService.cs +++ b/src/Artemis.WebClient.Workshop/Services/WorkshopService.cs @@ -152,9 +152,9 @@ public class WorkshopService : IWorkshopService } /// - public InstalledEntry? GetInstalledEntry(IEntryDetails entry) + public InstalledEntry? GetInstalledEntry(long entryId) { - EntryEntity? entity = _entryRepository.GetByEntryId(entry.Id); + EntryEntity? entity = _entryRepository.GetByEntryId(entryId); if (entity == null) return null; diff --git a/src/Artemis.WebClient.Workshop/graphql.config.yml b/src/Artemis.WebClient.Workshop/graphql.config.yml index a8ba99703..9662a514f 100644 --- a/src/Artemis.WebClient.Workshop/graphql.config.yml +++ b/src/Artemis.WebClient.Workshop/graphql.config.yml @@ -2,7 +2,7 @@ schema: schema.graphql extensions: endpoints: Default GraphQL Endpoint: - url: https://localhost:7281/graphql + url: https://workshop.artemis-rgb.com/graphql headers: user-agent: JS GraphQL introspect: true diff --git a/src/Artemis.WebClient.Workshop/schema.graphql b/src/Artemis.WebClient.Workshop/schema.graphql index 959e11204..150e74f3a 100644 --- a/src/Artemis.WebClient.Workshop/schema.graphql +++ b/src/Artemis.WebClient.Workshop/schema.graphql @@ -5,8 +5,6 @@ schema { mutation: Mutation } -directive @tag(name: String!) on SCHEMA | SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION - type Category { icon: String! id: Long! @@ -35,6 +33,7 @@ type Entry { authorId: UUID! categories: [Category!]! createdAt: DateTime! + dependantReleases: [Release!]! description: String! downloads: Long! entryType: EntryType! @@ -46,6 +45,7 @@ type Entry { latestReleaseId: Long layoutInfo: [LayoutInfo!]! name: String! + pluginInfo: PluginInfo releases: [Release!]! summary: String! tags: [Tag!]! @@ -84,10 +84,33 @@ type Mutation { updateEntryImage(input: UpdateEntryImageInput!): Image } +type PluginInfo { + api: Int + entry: Entry! + entryId: Long! + helpPage: String + platforms: PluginPlatform + pluginGuid: UUID! + repository: String + requiresAdmin: Boolean! + website: String +} + +"A segment of a collection." +type PluginInfosCollectionSegment { + "A flattened list of the items." + items: [PluginInfo!] + "Information to aid in pagination." + pageInfo: CollectionSegmentInfo! + totalCount: Int! +} + type Query { categories(order: [CategorySortInput!], where: CategoryFilterInput): [Category!]! entries(order: [EntrySortInput!], search: String, skip: Int, take: Int, where: EntryFilterInput): EntriesCollectionSegment entry(id: Long!): Entry + pluginInfo(pluginGuid: UUID!): PluginInfo + pluginInfos(order: [PluginInfoSortInput!], skip: Int, take: Int, where: PluginInfoFilterInput): PluginInfosCollectionSegment searchEntries(input: String!, order: [EntrySortInput!], type: EntryType, where: EntryFilterInput): [Entry!]! searchKeyboardLayout(deviceProvider: UUID!, logicalLayout: String, model: String!, physicalLayout: KeyboardLayoutType!, vendor: String!): LayoutInfo searchLayout(deviceProvider: UUID!, deviceType: RGBDeviceType!, model: String!, vendor: String!): LayoutInfo @@ -96,6 +119,7 @@ type Query { type Release { createdAt: DateTime! + dependencies: [Entry!]! downloadSize: Long! downloads: Long! entry: Entry! @@ -131,11 +155,18 @@ enum KeyboardLayoutType { UNKNOWN } +enum PluginPlatform { + LINUX + OSX + WINDOWS +} + enum RGBDeviceType { ALL COOLER DRAM FAN + GAME_CONTROLLER GRAPHICS_CARD HEADSET HEADSET_STAND @@ -166,6 +197,11 @@ scalar Long scalar UUID +input BooleanOperationFilterInput { + eq: Boolean + neq: Boolean +} + input CategoryFilterInput { and: [CategoryFilterInput!] icon: StringOperationFilterInput @@ -220,6 +256,7 @@ input EntryFilterInput { authorId: UuidOperationFilterInput categories: ListFilterInputTypeOfCategoryFilterInput createdAt: DateTimeOperationFilterInput + dependantReleases: ListFilterInputTypeOfReleaseFilterInput description: StringOperationFilterInput downloads: LongOperationFilterInput entryType: EntryTypeOperationFilterInput @@ -232,6 +269,7 @@ input EntryFilterInput { layoutInfo: ListFilterInputTypeOfLayoutInfoFilterInput name: StringOperationFilterInput or: [EntryFilterInput!] + pluginInfo: PluginInfoFilterInput releases: ListFilterInputTypeOfReleaseFilterInput summary: StringOperationFilterInput tags: ListFilterInputTypeOfTagFilterInput @@ -250,6 +288,7 @@ input EntrySortInput { latestRelease: ReleaseSortInput latestReleaseId: SortEnumType name: SortEnumType + pluginInfo: PluginInfoSortInput summary: SortEnumType } @@ -322,6 +361,13 @@ input ListFilterInputTypeOfCategoryFilterInput { some: CategoryFilterInput } +input ListFilterInputTypeOfEntryFilterInput { + all: EntryFilterInput + any: Boolean + none: EntryFilterInput + some: EntryFilterInput +} + input ListFilterInputTypeOfImageFilterInput { all: ImageFilterInput any: Boolean @@ -372,6 +418,39 @@ input NullableOfKeyboardLayoutTypeOperationFilterInput { nin: [KeyboardLayoutType] } +input NullableOfPluginPlatformOperationFilterInput { + eq: PluginPlatform + in: [PluginPlatform] + neq: PluginPlatform + nin: [PluginPlatform] +} + +input PluginInfoFilterInput { + and: [PluginInfoFilterInput!] + api: IntOperationFilterInput + entry: EntryFilterInput + entryId: LongOperationFilterInput + helpPage: StringOperationFilterInput + or: [PluginInfoFilterInput!] + platforms: NullableOfPluginPlatformOperationFilterInput + pluginGuid: UuidOperationFilterInput + repository: StringOperationFilterInput + requiresAdmin: BooleanOperationFilterInput + website: StringOperationFilterInput +} + +input PluginInfoSortInput { + api: SortEnumType + entry: EntrySortInput + entryId: SortEnumType + helpPage: SortEnumType + platforms: SortEnumType + pluginGuid: SortEnumType + repository: SortEnumType + requiresAdmin: SortEnumType + website: SortEnumType +} + input RGBDeviceTypeOperationFilterInput { eq: RGBDeviceType in: [RGBDeviceType!] @@ -382,6 +461,7 @@ input RGBDeviceTypeOperationFilterInput { input ReleaseFilterInput { and: [ReleaseFilterInput!] createdAt: DateTimeOperationFilterInput + dependencies: ListFilterInputTypeOfEntryFilterInput downloadSize: LongOperationFilterInput downloads: LongOperationFilterInput entry: EntryFilterInput