mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Add AXAML hot reload (debug only)
Major progress on default entries too I guess lmao
This commit is contained in:
parent
20fb6b7662
commit
b351f685f7
@ -141,6 +141,11 @@ public static class Constants
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static ReadOnlyCollection<string> StartupArguments { get; set; } = null!;
|
public static ReadOnlyCollection<string> StartupArguments { get; set; } = null!;
|
||||||
|
|
||||||
|
public static string? GetStartupRoute()
|
||||||
|
{
|
||||||
|
return StartupArguments.FirstOrDefault(a => a.StartsWith("--route=artemis://"))?.Split("--route=artemis://")[1];
|
||||||
|
}
|
||||||
|
|
||||||
internal static readonly CorePluginFeature CorePluginFeature = new() {Plugin = CorePlugin, Profiler = CorePlugin.GetProfiler("Feature - Core")};
|
internal static readonly CorePluginFeature CorePluginFeature = new() {Plugin = CorePlugin, Profiler = CorePlugin.GetProfiler("Feature - Core")};
|
||||||
internal static readonly EffectPlaceholderPlugin EffectPlaceholderPlugin = new() {Plugin = CorePlugin, Profiler = CorePlugin.GetProfiler("Feature - Effect Placeholder")};
|
internal static readonly EffectPlaceholderPlugin EffectPlaceholderPlugin = new() {Plugin = CorePlugin, Profiler = CorePlugin.GetProfiler("Feature - Effect Placeholder")};
|
||||||
internal static readonly JsonSerializerOptions JsonConvertSettings = new() {Converters = {new SKColorConverter(), new NumericJsonConverter()}};
|
internal static readonly JsonSerializerOptions JsonConvertSettings = new() {Converters = {new SKColorConverter(), new NumericJsonConverter()}};
|
||||||
|
|||||||
@ -251,8 +251,14 @@ internal class Router : CorePropertyChanged, IRouter, IDisposable
|
|||||||
if (_previousWindowRoute != null && _currentRouteSubject.Value == "blank")
|
if (_previousWindowRoute != null && _currentRouteSubject.Value == "blank")
|
||||||
Dispatcher.UIThread.InvokeAsync(async () => await Navigate(_previousWindowRoute, new RouterNavigationOptions {AddToHistory = false, EnableLogging = false}));
|
Dispatcher.UIThread.InvokeAsync(async () => await Navigate(_previousWindowRoute, new RouterNavigationOptions {AddToHistory = false, EnableLogging = false}));
|
||||||
else if (_currentRouteSubject.Value == null || _currentRouteSubject.Value == "blank")
|
else if (_currentRouteSubject.Value == null || _currentRouteSubject.Value == "blank")
|
||||||
|
{
|
||||||
|
string? startupRoute = Constants.GetStartupRoute();
|
||||||
|
if (startupRoute != null)
|
||||||
|
Dispatcher.UIThread.InvokeAsync(async () => await Navigate(startupRoute, new RouterNavigationOptions {AddToHistory = false, EnableLogging = true}));
|
||||||
|
else
|
||||||
Dispatcher.UIThread.InvokeAsync(async () => await Navigate("home", new RouterNavigationOptions {AddToHistory = false, EnableLogging = true}));
|
Dispatcher.UIThread.InvokeAsync(async () => await Navigate("home", new RouterNavigationOptions {AddToHistory = false, EnableLogging = true}));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void MainWindowServiceOnMainWindowClosed(object? sender, EventArgs e)
|
private void MainWindowServiceOnMainWindowClosed(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -16,6 +16,7 @@ using Avalonia.Controls.ApplicationLifetimes;
|
|||||||
using Avalonia.Markup.Xaml;
|
using Avalonia.Markup.Xaml;
|
||||||
using Avalonia.ReactiveUI;
|
using Avalonia.ReactiveUI;
|
||||||
using DryIoc;
|
using DryIoc;
|
||||||
|
using HotAvalonia;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
|
|
||||||
namespace Artemis.UI.Windows;
|
namespace Artemis.UI.Windows;
|
||||||
@ -27,6 +28,8 @@ public class App : Application
|
|||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
|
this.EnableHotReload();
|
||||||
|
|
||||||
// If Artemis is already running, bring it to foreground and stop this process
|
// If Artemis is already running, bring it to foreground and stop this process
|
||||||
if (FocusExistingInstance())
|
if (FocusExistingInstance())
|
||||||
{
|
{
|
||||||
@ -89,7 +92,7 @@ public class App : Application
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
CancellationTokenSource cts = new();
|
CancellationTokenSource cts = new();
|
||||||
cts.CancelAfter(2000);
|
cts.CancelAfter(5000);
|
||||||
|
|
||||||
HttpResponseMessage httpResponseMessage = client.Send(new HttpRequestMessage(HttpMethod.Post, url + "remote/bring-to-foreground") {Content = new StringContent(route ?? "")}, cts.Token);
|
HttpResponseMessage httpResponseMessage = client.Send(new HttpRequestMessage(HttpMethod.Post, url + "remote/bring-to-foreground") {Content = new StringContent(route ?? "")}, cts.Token);
|
||||||
httpResponseMessage.EnsureSuccessStatusCode();
|
httpResponseMessage.EnsureSuccessStatusCode();
|
||||||
|
|||||||
@ -35,40 +35,4 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<AvaloniaResource Include="Assets\**" />
|
<AvaloniaResource Include="Assets\**" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Compile Update="Screens\Workshop\Plugin\Dialogs\DeviceProviderPickerDialogView.axaml.cs">
|
|
||||||
<DependentUpon>DeviceProviderPickerDialogView.axaml</DependentUpon>
|
|
||||||
<SubType>Code</SubType>
|
|
||||||
</Compile>
|
|
||||||
<Compile Update="Screens\Workshop\Plugin\Dialogs\DeviceSelectionDialogView.axaml.cs">
|
|
||||||
<DependentUpon>DeviceSelectionDialogView.axaml</DependentUpon>
|
|
||||||
<SubType>Code</SubType>
|
|
||||||
</Compile>
|
|
||||||
<Compile Update="Screens\Workshop\Layout\LayoutListView.axaml.cs">
|
|
||||||
<DependentUpon>LayoutListView.axaml</DependentUpon>
|
|
||||||
<SubType>Code</SubType>
|
|
||||||
</Compile>
|
|
||||||
<Compile Update="Screens\Workshop\Plugins\PluginListView.axaml.cs">
|
|
||||||
<DependentUpon>LayoutListView.axaml</DependentUpon>
|
|
||||||
<SubType>Code</SubType>
|
|
||||||
</Compile>
|
|
||||||
<Compile Update="Screens\Workshop\Profile\ProfileListView.axaml.cs">
|
|
||||||
<DependentUpon>LayoutListView.axaml</DependentUpon>
|
|
||||||
<SubType>Code</SubType>
|
|
||||||
</Compile>
|
|
||||||
<Compile Update="Screens\Workshop\EntryReleases\EntryReleasesView.axaml.cs">
|
|
||||||
<DependentUpon>EntryReleasesView.axaml</DependentUpon>
|
|
||||||
<SubType>Code</SubType>
|
|
||||||
</Compile>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<UpToDateCheckInput Remove="Screens\Workshop\Entries\Tabs\PluginListView.axaml" />
|
|
||||||
<UpToDateCheckInput Remove="Screens\Workshop\Entries\Tabs\ProfileListView.axaml" />
|
|
||||||
<UpToDateCheckInput Remove="Screens\Workshop\Plugins\Dialogs\PluginDialogView.axaml" />
|
|
||||||
<UpToDateCheckInput Remove="Screens\Scripting\Dialogs\ScriptConfigurationCreateView.axaml" />
|
|
||||||
<UpToDateCheckInput Remove="Screens\Scripting\Dialogs\ScriptConfigurationEditView.axaml" />
|
|
||||||
<UpToDateCheckInput Remove="Screens\Scripting\ScriptsDialogView.axaml" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
</Project>
|
||||||
@ -7,26 +7,52 @@
|
|||||||
x:Class="Artemis.UI.Screens.StartupWizard.Steps.DefaultEntriesStepView"
|
x:Class="Artemis.UI.Screens.StartupWizard.Steps.DefaultEntriesStepView"
|
||||||
x:DataType="steps:DefaultEntriesStepViewModel">
|
x:DataType="steps:DefaultEntriesStepViewModel">
|
||||||
<Border Classes="card">
|
<Border Classes="card">
|
||||||
<Grid RowDefinitions="Auto,Auto,Auto,Auto,*">
|
<Grid RowDefinitions="*,Auto">
|
||||||
<StackPanel Grid.Row="0">
|
<ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
|
||||||
|
<StackPanel>
|
||||||
<TextBlock TextWrapping="Wrap">
|
<TextBlock TextWrapping="Wrap">
|
||||||
Installing default plugins and profiles, these will provide you with a basic setup to get started with Artemis.
|
Below is a list of default features that can be installed to get you started with Artemis. You can always install or uninstall features later via the Workshop.
|
||||||
</TextBlock>
|
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<TextBlock Grid.Row="2">
|
|
||||||
<Run Text="Installed"/>
|
|
||||||
<Run Text="{CompiledBinding InstalledEntries}"/>
|
|
||||||
<Run Text=" of "/>
|
|
||||||
<Run Text="{CompiledBinding TotalEntries}"/>
|
|
||||||
<Run Text=" entries."/>
|
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
|
|
||||||
<ProgressBar Grid.Row="3" Minimum="0" Maximum="{CompiledBinding TotalEntries}" IsIndeterminate="{CompiledBinding FetchingDefaultEntries}" Value="{CompiledBinding InstalledEntries}" />
|
<TextBlock Classes="card-title" IsVisible="{CompiledBinding DeviceProviderEntryViewModels.Count}">
|
||||||
<StackPanel Grid.Row="4" Orientation="Vertical" IsVisible="{CompiledBinding CurrentEntry, Converter={x:Static ObjectConverters.IsNotNull}}" Margin="0 10">
|
Device providers
|
||||||
<TextBlock Text="{CompiledBinding CurrentEntry.Name, StringFormat='Currently installing: {0}'}" />
|
</TextBlock>
|
||||||
<ProgressBar Minimum="0" Maximum="100" Value="{CompiledBinding InstallProgress}" />
|
<ItemsControl ItemsSource="{CompiledBinding DeviceProviderEntryViewModels}" Margin="0,0,5,0">
|
||||||
|
<ItemsControl.ItemsPanel>
|
||||||
|
<ItemsPanelTemplate>
|
||||||
|
<UniformGrid Columns="2" ColumnSpacing="5" />
|
||||||
|
</ItemsPanelTemplate>
|
||||||
|
</ItemsControl.ItemsPanel>
|
||||||
|
</ItemsControl>
|
||||||
|
|
||||||
|
<TextBlock Classes="card-title" IsVisible="{CompiledBinding EssentialEntryViewModels.Count}">
|
||||||
|
Essentials
|
||||||
|
</TextBlock>
|
||||||
|
<ItemsControl ItemsSource="{CompiledBinding EssentialEntryViewModels}" Margin="0,0,5,0">
|
||||||
|
<ItemsControl.ItemsPanel>
|
||||||
|
<ItemsPanelTemplate>
|
||||||
|
<UniformGrid Columns="2" ColumnSpacing="5"/>
|
||||||
|
</ItemsPanelTemplate>
|
||||||
|
</ItemsControl.ItemsPanel>
|
||||||
|
</ItemsControl>
|
||||||
|
|
||||||
|
<TextBlock Classes="card-title" IsVisible="{CompiledBinding OtherEntryViewModels.Count}">
|
||||||
|
Other features
|
||||||
|
</TextBlock>
|
||||||
|
<ItemsControl ItemsSource="{CompiledBinding OtherEntryViewModels}" Margin="0,0,5,0">
|
||||||
|
<ItemsControl.ItemsPanel>
|
||||||
|
<ItemsPanelTemplate>
|
||||||
|
<UniformGrid Columns="2" ColumnSpacing="5"/>
|
||||||
|
</ItemsPanelTemplate>
|
||||||
|
</ItemsControl.ItemsPanel>
|
||||||
|
</ItemsControl>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
</ScrollViewer>
|
||||||
|
<ProgressBar Grid.Row="1"
|
||||||
|
Minimum="0"
|
||||||
|
Maximum="{CompiledBinding TotalEntries}"
|
||||||
|
IsIndeterminate="{CompiledBinding FetchingDefaultEntries}"
|
||||||
|
Value="{CompiledBinding CurrentEntries}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@ -8,7 +9,6 @@ using Artemis.UI.Extensions;
|
|||||||
using Artemis.UI.Shared.Services;
|
using Artemis.UI.Shared.Services;
|
||||||
using Artemis.UI.Shared.Utilities;
|
using Artemis.UI.Shared.Utilities;
|
||||||
using Artemis.WebClient.Workshop;
|
using Artemis.WebClient.Workshop;
|
||||||
using Artemis.WebClient.Workshop.Handlers.InstallationHandlers;
|
|
||||||
using Artemis.WebClient.Workshop.Services;
|
using Artemis.WebClient.Workshop.Services;
|
||||||
using PropertyChanged.SourceGenerator;
|
using PropertyChanged.SourceGenerator;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
@ -20,25 +20,31 @@ public partial class DefaultEntriesStepViewModel : WizardStepViewModel
|
|||||||
{
|
{
|
||||||
[Notify] private bool _workshopReachable;
|
[Notify] private bool _workshopReachable;
|
||||||
[Notify] private bool _fetchingDefaultEntries;
|
[Notify] private bool _fetchingDefaultEntries;
|
||||||
[Notify] private int _totalEntries;
|
[Notify] private bool _installed;
|
||||||
[Notify] private int _installedEntries;
|
[Notify] private int _currentEntries;
|
||||||
[Notify] private int _installProgress;
|
[Notify] private int _totalEntries = 1;
|
||||||
[Notify] private IEntrySummary? _currentEntry;
|
|
||||||
|
|
||||||
private readonly IWorkshopService _workshopService;
|
|
||||||
private readonly IWorkshopClient _client;
|
private readonly IWorkshopClient _client;
|
||||||
private readonly IWindowService _windowService;
|
private readonly Func<IEntrySummary, DefaultEntryItemViewModel> _getDefaultEntryItemViewModel;
|
||||||
private readonly Progress<StreamProgress> _currentEntryProgress = new();
|
|
||||||
|
|
||||||
|
public ObservableCollection<DefaultEntryItemViewModel> DeviceProviderEntryViewModels { get; } = [];
|
||||||
|
public ObservableCollection<DefaultEntryItemViewModel> EssentialEntryViewModels { get; } = [];
|
||||||
|
public ObservableCollection<DefaultEntryItemViewModel> OtherEntryViewModels { get; } = [];
|
||||||
|
|
||||||
public DefaultEntriesStepViewModel(IWorkshopService workshopService, IDeviceService deviceService, IWorkshopClient client, IWindowService windowService)
|
public DefaultEntriesStepViewModel(IWorkshopService workshopService, IDeviceService deviceService, IWorkshopClient client,
|
||||||
|
Func<IEntrySummary, DefaultEntryItemViewModel> getDefaultEntryItemViewModel)
|
||||||
{
|
{
|
||||||
_workshopService = workshopService;
|
|
||||||
_client = client;
|
_client = client;
|
||||||
_windowService = windowService;
|
_getDefaultEntryItemViewModel = getDefaultEntryItemViewModel;
|
||||||
_currentEntryProgress.ProgressChanged += (_, f) => InstallProgress = f.ProgressPercentage;
|
|
||||||
|
|
||||||
Continue = ReactiveCommand.Create(() => Wizard.ChangeScreen<SettingsStepViewModel>());
|
ContinueText = "Install selected entries";
|
||||||
|
Continue = ReactiveCommand.CreateFromTask(async ct =>
|
||||||
|
{
|
||||||
|
if (Installed)
|
||||||
|
Wizard.ChangeScreen<SettingsStepViewModel>();
|
||||||
|
else
|
||||||
|
await Install(ct);
|
||||||
|
});
|
||||||
GoBack = ReactiveCommand.Create(() =>
|
GoBack = ReactiveCommand.Create(() =>
|
||||||
{
|
{
|
||||||
if (deviceService.EnabledDevices.Count == 0)
|
if (deviceService.EnabledDevices.Count == 0)
|
||||||
@ -49,22 +55,57 @@ public partial class DefaultEntriesStepViewModel : WizardStepViewModel
|
|||||||
|
|
||||||
this.WhenActivatedAsync(async d =>
|
this.WhenActivatedAsync(async d =>
|
||||||
{
|
{
|
||||||
WorkshopReachable = await _workshopService.ValidateWorkshopStatus(d.AsCancellationToken());
|
WorkshopReachable = await workshopService.ValidateWorkshopStatus(d.AsCancellationToken());
|
||||||
if (WorkshopReachable)
|
if (WorkshopReachable)
|
||||||
{
|
{
|
||||||
await InstallDefaultEntries(d.AsCancellationToken());
|
await GetDefaultEntries(d.AsCancellationToken());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> InstallDefaultEntries(CancellationToken cancellationToken)
|
private async Task Install(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
FetchingDefaultEntries = true;
|
// Remove entries that aren't to be installed
|
||||||
TotalEntries = 0;
|
RemoveUnselectedEntries(DeviceProviderEntryViewModels);
|
||||||
InstalledEntries = 0;
|
RemoveUnselectedEntries(EssentialEntryViewModels);
|
||||||
|
RemoveUnselectedEntries(OtherEntryViewModels);
|
||||||
|
|
||||||
|
TotalEntries = DeviceProviderEntryViewModels.Count + EssentialEntryViewModels.Count + OtherEntryViewModels.Count;
|
||||||
|
CurrentEntries = 0;
|
||||||
|
|
||||||
|
// Install entries one by one, removing them from the list as we go
|
||||||
|
List<DefaultEntryItemViewModel> entries = [..DeviceProviderEntryViewModels, ..EssentialEntryViewModels, ..OtherEntryViewModels];
|
||||||
|
foreach (DefaultEntryItemViewModel defaultEntryItemViewModel in entries)
|
||||||
|
{
|
||||||
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
bool removeFromList = await defaultEntryItemViewModel.InstallEntry(cancellationToken);
|
||||||
|
if (!removeFromList)
|
||||||
|
break;
|
||||||
|
|
||||||
|
DeviceProviderEntryViewModels.Remove(defaultEntryItemViewModel);
|
||||||
|
EssentialEntryViewModels.Remove(defaultEntryItemViewModel);
|
||||||
|
OtherEntryViewModels.Remove(defaultEntryItemViewModel);
|
||||||
|
CurrentEntries++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Installed = true;
|
||||||
|
ContinueText = "Continue";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RemoveUnselectedEntries(ObservableCollection<DefaultEntryItemViewModel> entryViewModels)
|
||||||
|
{
|
||||||
|
List<DefaultEntryItemViewModel> toRemove = entryViewModels.Where(e => !e.ShouldInstall).ToList();
|
||||||
|
foreach (DefaultEntryItemViewModel defaultEntryItemViewModel in toRemove)
|
||||||
|
entryViewModels.Remove(defaultEntryItemViewModel);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task GetDefaultEntries(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
if (!WorkshopReachable)
|
if (!WorkshopReachable)
|
||||||
return false;
|
return;
|
||||||
|
|
||||||
|
FetchingDefaultEntries = true;
|
||||||
|
|
||||||
IOperationResult<IGetDefaultEntriesResult> result = await _client.GetDefaultEntries.ExecuteAsync(100, null, cancellationToken);
|
IOperationResult<IGetDefaultEntriesResult> result = await _client.GetDefaultEntries.ExecuteAsync(100, null, cancellationToken);
|
||||||
List<IEntrySummary> entries = result.Data?.EntriesV2?.Edges?.Select(e => e.Node).Cast<IEntrySummary>().ToList() ?? [];
|
List<IEntrySummary> entries = result.Data?.EntriesV2?.Edges?.Select(e => e.Node).Cast<IEntrySummary>().ToList() ?? [];
|
||||||
@ -75,41 +116,25 @@ public partial class DefaultEntriesStepViewModel : WizardStepViewModel
|
|||||||
entries.AddRange(result.Data.EntriesV2.Edges.Select(e => e.Node));
|
entries.AddRange(result.Data.EntriesV2.Edges.Select(e => e.Node));
|
||||||
}
|
}
|
||||||
|
|
||||||
await Task.Delay(1000);
|
DeviceProviderEntryViewModels.Clear();
|
||||||
FetchingDefaultEntries = false;
|
EssentialEntryViewModels.Clear();
|
||||||
TotalEntries = entries.Count;
|
OtherEntryViewModels.Clear();
|
||||||
|
|
||||||
if (entries.Count == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
foreach (IEntrySummary entry in entries)
|
foreach (IEntrySummary entry in entries)
|
||||||
{
|
{
|
||||||
if (cancellationToken.IsCancellationRequested)
|
if (entry.DefaultEntryInfo == null)
|
||||||
return false;
|
|
||||||
|
|
||||||
CurrentEntry = entry;
|
|
||||||
|
|
||||||
// Skip entries without a release and entries that are already installed
|
|
||||||
if (entry.LatestRelease == null || _workshopService.GetInstalledEntry(entry.Id) != null)
|
|
||||||
{
|
|
||||||
InstalledEntries++;
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
DefaultEntryItemViewModel viewModel = _getDefaultEntryItemViewModel(entry);
|
||||||
|
viewModel.ShouldInstall = entry.DefaultEntryInfo.IsEssential;
|
||||||
|
|
||||||
|
if (entry.DefaultEntryInfo.IsDeviceProvider)
|
||||||
|
DeviceProviderEntryViewModels.Add(viewModel);
|
||||||
|
else if (entry.DefaultEntryInfo.IsEssential)
|
||||||
|
EssentialEntryViewModels.Add(viewModel);
|
||||||
|
else
|
||||||
|
OtherEntryViewModels.Add(viewModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
EntryInstallResult installResult = await _workshopService.InstallEntry(entry, entry.LatestRelease, _currentEntryProgress, cancellationToken);
|
FetchingDefaultEntries = false;
|
||||||
|
|
||||||
// Unlikely as default entries do nothing fancy
|
|
||||||
if (!installResult.IsSuccess)
|
|
||||||
{
|
|
||||||
await _windowService.CreateContentDialog().WithTitle("Failed to install entry")
|
|
||||||
.WithContent($"Failed to install entry '{entry.Name}' ({entry.Id}): {installResult.Message}")
|
|
||||||
.WithCloseButtonText("Skip and continue")
|
|
||||||
.ShowAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
InstalledEntries++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -0,0 +1,72 @@
|
|||||||
|
<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:il="clr-namespace:AsyncImageLoader;assembly=AsyncImageLoader.Avalonia"
|
||||||
|
xmlns:converters="clr-namespace:Artemis.UI.Converters"
|
||||||
|
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
|
||||||
|
xmlns:steps="clr-namespace:Artemis.UI.Screens.StartupWizard.Steps"
|
||||||
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
|
x:Class="Artemis.UI.Screens.StartupWizard.Steps.DefaultEntryItemView"
|
||||||
|
x:DataType="steps:DefaultEntryItemViewModel">
|
||||||
|
<UserControl.Resources>
|
||||||
|
<converters:EntryIconUriConverter x:Key="EntryIconUriConverter" />
|
||||||
|
<converters:DateTimeConverter x:Key="DateTimeConverter" />
|
||||||
|
</UserControl.Resources>
|
||||||
|
<Border Classes="card" Padding="15" Margin="0 5">
|
||||||
|
<Grid ColumnDefinitions="Auto,*,Auto,Auto" RowDefinitions="*, Auto">
|
||||||
|
<!-- Icon -->
|
||||||
|
<Border Grid.Column="0"
|
||||||
|
Grid.Row="0"
|
||||||
|
Grid.RowSpan="2"
|
||||||
|
CornerRadius="6"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Margin="0 0 10 0"
|
||||||
|
Width="80"
|
||||||
|
Height="80"
|
||||||
|
ClipToBounds="True">
|
||||||
|
<Image Stretch="UniformToFill" il:ImageLoader.Source="{CompiledBinding Entry.Id, Converter={StaticResource EntryIconUriConverter}, Mode=OneWay}" />
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
<!-- Body -->
|
||||||
|
<Grid Grid.Column="1" Grid.Row="0" Grid.RowSpan="2" VerticalAlignment="Stretch" RowDefinitions="Auto,*,Auto">
|
||||||
|
<StackPanel Grid.Row="0" Orientation="Horizontal">
|
||||||
|
<TextBlock Classes="h5" Margin="0 0 0 5" TextTrimming="CharacterEllipsis" Text="{CompiledBinding Entry.Name, FallbackValue=Title}" />
|
||||||
|
</StackPanel>
|
||||||
|
<TextBlock Grid.Row="1"
|
||||||
|
Classes="subtitle"
|
||||||
|
TextWrapping="Wrap"
|
||||||
|
TextTrimming="CharacterEllipsis"
|
||||||
|
Text="{CompiledBinding Entry.Summary, FallbackValue=Summary}" />
|
||||||
|
|
||||||
|
<ItemsControl Grid.Row="2" ItemsSource="{CompiledBinding Entry.Categories}" Margin="0 8 0 0">
|
||||||
|
<ItemsControl.ItemsPanel>
|
||||||
|
<ItemsPanelTemplate>
|
||||||
|
<StackPanel Orientation="Horizontal" Spacing="8" />
|
||||||
|
</ItemsPanelTemplate>
|
||||||
|
</ItemsControl.ItemsPanel>
|
||||||
|
<ItemsControl.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<avalonia:MaterialIcon Kind="{CompiledBinding Icon}" Margin="0 0 3 0" />
|
||||||
|
<TextBlock Text="{CompiledBinding Name}" TextTrimming="CharacterEllipsis" />
|
||||||
|
</StackPanel>
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
</ItemsControl>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<!-- Management -->
|
||||||
|
<Border Grid.Column="3" Grid.Row="0" Grid.RowSpan="2" BorderBrush="{DynamicResource ButtonBorderBrush}" BorderThickness="1 0 0 0" Margin="10 0 0 0" Padding="10 0 0 0" IsVisible="{CompiledBinding !IsInstalled}">
|
||||||
|
<StackPanel VerticalAlignment="Center">
|
||||||
|
<CheckBox MinHeight="26" Margin="0 4 0 0" IsChecked="{CompiledBinding ShouldInstall}">Install</CheckBox>
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
|
<Border Grid.Column="3" Grid.Row="0" Grid.RowSpan="2" BorderBrush="{DynamicResource ButtonBorderBrush}" BorderThickness="1 0 0 0" Margin="10 0 0 0" Padding="10 0 0 0" IsVisible="{CompiledBinding IsInstalled}">
|
||||||
|
<StackPanel VerticalAlignment="Center">
|
||||||
|
<TextBlock>Already installed</TextBlock>
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
|
</UserControl>
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
using Avalonia.ReactiveUI;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Screens.StartupWizard.Steps;
|
||||||
|
|
||||||
|
public partial class DefaultEntryItemView : ReactiveUserControl<StartupWizard.Steps.DefaultEntryItemViewModel>
|
||||||
|
{
|
||||||
|
public DefaultEntryItemView()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,86 @@
|
|||||||
|
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 StrawberryShake;
|
||||||
|
|
||||||
|
namespace Artemis.UI.Screens.StartupWizard.Steps;
|
||||||
|
|
||||||
|
public partial class DefaultEntryItemViewModel : ActivatableViewModelBase
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
public DefaultEntryItemViewModel(IEntrySummary entry, IWorkshopService workshopService, IWindowService windowService, IPluginManagementService pluginManagementService, ISettingsVmFactory settingsVmFactory)
|
||||||
|
{
|
||||||
|
_workshopService = workshopService;
|
||||||
|
_windowService = windowService;
|
||||||
|
_pluginManagementService = pluginManagementService;
|
||||||
|
_settingsVmFactory = settingsVmFactory;
|
||||||
|
Entry = entry;
|
||||||
|
|
||||||
|
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 quick it looks broken without a small delay
|
||||||
|
Task minimumDelay = Task.Delay(100, 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
|
||||||
|
else if (result.Entry?.EntryType == EntryType.Plugin)
|
||||||
|
{
|
||||||
|
await EnablePlugin(result.Entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.IsSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task EnablePlugin(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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -64,7 +64,11 @@
|
|||||||
<Label Target="Summary" Margin="0 5 0 0">Summary</Label>
|
<Label Target="Summary" Margin="0 5 0 0">Summary</Label>
|
||||||
<TextBox Name="Summary" Text="{CompiledBinding Summary}"></TextBox>
|
<TextBox Name="Summary" Text="{CompiledBinding Summary}"></TextBox>
|
||||||
|
|
||||||
<CheckBox IsVisible="{CompiledBinding IsAdministrator}" IsChecked="{CompiledBinding IsDefault}">Download by default (admin only)</CheckBox>
|
<StackPanel IsVisible="{CompiledBinding IsAdministrator}" Orientation="Horizontal">
|
||||||
|
<CheckBox IsChecked="{CompiledBinding IsDefault}">Download by default (admin only)</CheckBox>
|
||||||
|
<CheckBox IsEnabled="{CompiledBinding IsDefault}" IsChecked="{CompiledBinding IsEssential}">Essential</CheckBox>
|
||||||
|
<CheckBox IsEnabled="{CompiledBinding IsDefault}" IsChecked="{CompiledBinding IsDeviceProvider}">Device provider</CheckBox>
|
||||||
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
|||||||
@ -36,6 +36,8 @@ public partial class EntrySpecificationsViewModel : ValidatableViewModelBase
|
|||||||
[Notify] private string _summary = string.Empty;
|
[Notify] private string _summary = string.Empty;
|
||||||
[Notify] private string _description = string.Empty;
|
[Notify] private string _description = string.Empty;
|
||||||
[Notify] private bool _isDefault;
|
[Notify] private bool _isDefault;
|
||||||
|
[Notify] private bool _isEssential;
|
||||||
|
[Notify] private bool _isDeviceProvider;
|
||||||
[Notify] private Bitmap? _iconBitmap;
|
[Notify] private Bitmap? _iconBitmap;
|
||||||
[Notify(Setter.Private)] private bool _iconChanged;
|
[Notify(Setter.Private)] private bool _iconChanged;
|
||||||
|
|
||||||
|
|||||||
@ -105,7 +105,9 @@ public partial class SubmissionDetailsViewModel : RoutableScreen
|
|||||||
specificationsViewModel.Name = Entry.Name;
|
specificationsViewModel.Name = Entry.Name;
|
||||||
specificationsViewModel.Summary = Entry.Summary;
|
specificationsViewModel.Summary = Entry.Summary;
|
||||||
specificationsViewModel.Description = Entry.Description;
|
specificationsViewModel.Description = Entry.Description;
|
||||||
specificationsViewModel.IsDefault = Entry.IsDefault;
|
specificationsViewModel.IsDefault = Entry.DefaultEntryInfo != null;
|
||||||
|
specificationsViewModel.IsEssential = Entry.DefaultEntryInfo?.IsEssential ?? false;
|
||||||
|
specificationsViewModel.IsDeviceProvider = Entry.DefaultEntryInfo?.IsDeviceProvider ?? false;
|
||||||
specificationsViewModel.PreselectedCategories = Entry.Categories.Select(c => c.Id).ToList();
|
specificationsViewModel.PreselectedCategories = Entry.Categories.Select(c => c.Id).ToList();
|
||||||
|
|
||||||
specificationsViewModel.Tags.Clear();
|
specificationsViewModel.Tags.Clear();
|
||||||
@ -170,14 +172,29 @@ public partial class SubmissionDetailsViewModel : RoutableScreen
|
|||||||
HasChanges = EntrySpecificationsViewModel.Name != Entry.Name ||
|
HasChanges = EntrySpecificationsViewModel.Name != Entry.Name ||
|
||||||
EntrySpecificationsViewModel.Description != Entry.Description ||
|
EntrySpecificationsViewModel.Description != Entry.Description ||
|
||||||
EntrySpecificationsViewModel.Summary != Entry.Summary ||
|
EntrySpecificationsViewModel.Summary != Entry.Summary ||
|
||||||
EntrySpecificationsViewModel.IsDefault != Entry.IsDefault ||
|
|
||||||
EntrySpecificationsViewModel.IconChanged ||
|
EntrySpecificationsViewModel.IconChanged ||
|
||||||
|
HasAdminChanges() ||
|
||||||
!tags.SequenceEqual(Entry.Tags.Select(t => t.Name).OrderBy(t => t)) ||
|
!tags.SequenceEqual(Entry.Tags.Select(t => t.Name).OrderBy(t => t)) ||
|
||||||
!categories.SequenceEqual(Entry.Categories.Select(c => c.Id).OrderBy(c => c)) ||
|
!categories.SequenceEqual(Entry.Categories.Select(c => c.Id).OrderBy(c => c)) ||
|
||||||
Images.Any(i => i.HasChanges) ||
|
Images.Any(i => i.HasChanges) ||
|
||||||
_removedImages.Any();
|
_removedImages.Any();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool HasAdminChanges()
|
||||||
|
{
|
||||||
|
if (EntrySpecificationsViewModel == null || Entry == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool isDefault = Entry.DefaultEntryInfo != null;
|
||||||
|
bool isEssential = Entry.DefaultEntryInfo?.IsEssential ?? false;
|
||||||
|
bool isDeviceProvider = Entry.DefaultEntryInfo?.IsDeviceProvider ?? false;
|
||||||
|
|
||||||
|
return EntrySpecificationsViewModel.IsDefault != isDefault ||
|
||||||
|
(EntrySpecificationsViewModel.IsDefault && (
|
||||||
|
EntrySpecificationsViewModel.IsEssential != isEssential ||
|
||||||
|
EntrySpecificationsViewModel.IsDeviceProvider != isDeviceProvider));
|
||||||
|
}
|
||||||
|
|
||||||
private async Task ExecuteDiscardChanges()
|
private async Task ExecuteDiscardChanges()
|
||||||
{
|
{
|
||||||
await ApplyDetailsFromEntry(CancellationToken.None);
|
await ApplyDetailsFromEntry(CancellationToken.None);
|
||||||
@ -194,9 +211,15 @@ public partial class SubmissionDetailsViewModel : RoutableScreen
|
|||||||
Name = EntrySpecificationsViewModel.Name,
|
Name = EntrySpecificationsViewModel.Name,
|
||||||
Summary = EntrySpecificationsViewModel.Summary,
|
Summary = EntrySpecificationsViewModel.Summary,
|
||||||
Description = EntrySpecificationsViewModel.Description,
|
Description = EntrySpecificationsViewModel.Description,
|
||||||
IsDefault = EntrySpecificationsViewModel.IsDefault,
|
|
||||||
Categories = EntrySpecificationsViewModel.SelectedCategories,
|
Categories = EntrySpecificationsViewModel.SelectedCategories,
|
||||||
Tags = EntrySpecificationsViewModel.Tags
|
Tags = EntrySpecificationsViewModel.Tags,
|
||||||
|
DefaultEntryInfo = EntrySpecificationsViewModel.IsDefault
|
||||||
|
? new DefaultEntryInfoInput
|
||||||
|
{
|
||||||
|
IsEssential = EntrySpecificationsViewModel.IsEssential,
|
||||||
|
IsDeviceProvider = EntrySpecificationsViewModel.IsDeviceProvider
|
||||||
|
}
|
||||||
|
: null
|
||||||
};
|
};
|
||||||
|
|
||||||
IOperationResult<IUpdateEntryResult> result = await _client.UpdateEntry.ExecuteAsync(input, cancellationToken);
|
IOperationResult<IUpdateEntryResult> result = await _client.UpdateEntry.ExecuteAsync(input, cancellationToken);
|
||||||
|
|||||||
@ -33,6 +33,8 @@ public class SubmissionWizardState : IDisposable
|
|||||||
public string Summary { get; set; } = string.Empty;
|
public string Summary { get; set; } = string.Empty;
|
||||||
public string Description { get; set; } = string.Empty;
|
public string Description { get; set; } = string.Empty;
|
||||||
public bool IsDefault { get; set; }
|
public bool IsDefault { get; set; }
|
||||||
|
public bool IsEssential { get; set; }
|
||||||
|
public bool IsDeviceProvider { get; set; }
|
||||||
|
|
||||||
public List<long> Categories { get; set; } = new();
|
public List<long> Categories { get; set; } = new();
|
||||||
public List<string> Tags { get; set; } = new();
|
public List<string> Tags { get; set; } = new();
|
||||||
|
|||||||
@ -66,6 +66,8 @@ public partial class SpecificationsStepViewModel : SubmissionViewModel
|
|||||||
viewModel.Summary = State.Summary;
|
viewModel.Summary = State.Summary;
|
||||||
viewModel.Description = State.Description;
|
viewModel.Description = State.Description;
|
||||||
viewModel.IsDefault = State.IsDefault;
|
viewModel.IsDefault = State.IsDefault;
|
||||||
|
viewModel.IsEssential = State.IsEssential;
|
||||||
|
viewModel.IsDeviceProvider = State.IsDeviceProvider;
|
||||||
|
|
||||||
// Tags
|
// Tags
|
||||||
viewModel.Tags.Clear();
|
viewModel.Tags.Clear();
|
||||||
@ -95,6 +97,8 @@ public partial class SpecificationsStepViewModel : SubmissionViewModel
|
|||||||
State.Summary = EntrySpecificationsViewModel.Summary;
|
State.Summary = EntrySpecificationsViewModel.Summary;
|
||||||
State.Description = EntrySpecificationsViewModel.Description;
|
State.Description = EntrySpecificationsViewModel.Description;
|
||||||
State.IsDefault = EntrySpecificationsViewModel.IsDefault;
|
State.IsDefault = EntrySpecificationsViewModel.IsDefault;
|
||||||
|
State.IsEssential = EntrySpecificationsViewModel.IsEssential;
|
||||||
|
State.IsDeviceProvider = EntrySpecificationsViewModel.IsDeviceProvider;
|
||||||
|
|
||||||
// Categories and tasks
|
// Categories and tasks
|
||||||
State.Categories = EntrySpecificationsViewModel.Categories.Where(c => c.IsSelected).Select(c => c.Id).ToList();
|
State.Categories = EntrySpecificationsViewModel.Categories.Where(c => c.IsSelected).Select(c => c.Id).ToList();
|
||||||
|
|||||||
@ -105,7 +105,14 @@ public partial class UploadStepViewModel : SubmissionViewModel
|
|||||||
Summary = State.Summary,
|
Summary = State.Summary,
|
||||||
Description = State.Description,
|
Description = State.Description,
|
||||||
Categories = State.Categories,
|
Categories = State.Categories,
|
||||||
Tags = State.Tags
|
Tags = State.Tags,
|
||||||
|
DefaultEntryInfo = State.IsDefault
|
||||||
|
? new DefaultEntryInfoInput
|
||||||
|
{
|
||||||
|
IsEssential = State.IsEssential,
|
||||||
|
IsDeviceProvider = State.IsDeviceProvider
|
||||||
|
}
|
||||||
|
: null
|
||||||
}, cancellationToken);
|
}, cancellationToken);
|
||||||
|
|
||||||
result.EnsureNoErrors();
|
result.EnsureNoErrors();
|
||||||
|
|||||||
@ -26,7 +26,9 @@ fragment submittedEntry on Entry {
|
|||||||
entryType
|
entryType
|
||||||
downloads
|
downloads
|
||||||
createdAt
|
createdAt
|
||||||
isDefault
|
defaultEntryInfo {
|
||||||
|
...defaultEntryInfo
|
||||||
|
}
|
||||||
latestRelease {
|
latestRelease {
|
||||||
...release
|
...release
|
||||||
}
|
}
|
||||||
@ -48,6 +50,9 @@ fragment entrySummary on Entry {
|
|||||||
categories {
|
categories {
|
||||||
...category
|
...category
|
||||||
}
|
}
|
||||||
|
defaultEntryInfo {
|
||||||
|
...defaultEntryInfo
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fragment entryDetails on Entry {
|
fragment entryDetails on Entry {
|
||||||
@ -96,3 +101,8 @@ fragment pluginInfo on PluginInfo {
|
|||||||
supportsLinux
|
supportsLinux
|
||||||
supportsOSX
|
supportsOSX
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fragment defaultEntryInfo on DefaultEntryInfo {
|
||||||
|
isEssential
|
||||||
|
isDeviceProvider
|
||||||
|
}
|
||||||
@ -20,8 +20,12 @@ query GetPopularEntries {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
query GetDefaultEntries($first: Int $after: String) {
|
query GetDefaultEntries($first: Int, $after: String) {
|
||||||
entriesV2(where: {isDefault: {eq: true}} first: $first after: $after) {
|
entriesV2(
|
||||||
|
where: { defaultEntryInfo: { entryId: { gt: 0 } } }
|
||||||
|
first: $first
|
||||||
|
after: $after
|
||||||
|
) {
|
||||||
totalCount
|
totalCount
|
||||||
pageInfo {
|
pageInfo {
|
||||||
hasNextPage
|
hasNextPage
|
||||||
|
|||||||
@ -2,10 +2,10 @@ namespace Artemis.WebClient.Workshop;
|
|||||||
|
|
||||||
public static class WorkshopConstants
|
public static class WorkshopConstants
|
||||||
{
|
{
|
||||||
// public const string AUTHORITY_URL = "https://localhost:5001";
|
public const string AUTHORITY_URL = "https://localhost:5001";
|
||||||
// public const string WORKSHOP_URL = "https://localhost:7281";
|
public const string WORKSHOP_URL = "https://localhost:7281";
|
||||||
public const string AUTHORITY_URL = "https://identity.artemis-rgb.com";
|
// public const string AUTHORITY_URL = "https://identity.artemis-rgb.com";
|
||||||
public const string WORKSHOP_URL = "https://workshop.artemis-rgb.com";
|
// public const string WORKSHOP_URL = "https://workshop.artemis-rgb.com";
|
||||||
public const string IDENTITY_CLIENT_NAME = "IdentityApiClient";
|
public const string IDENTITY_CLIENT_NAME = "IdentityApiClient";
|
||||||
public const string WORKSHOP_CLIENT_NAME = "WorkshopApiClient";
|
public const string WORKSHOP_CLIENT_NAME = "WorkshopApiClient";
|
||||||
}
|
}
|
||||||
@ -2,7 +2,7 @@ schema: schema.graphql
|
|||||||
extensions:
|
extensions:
|
||||||
endpoints:
|
endpoints:
|
||||||
Default GraphQL Endpoint:
|
Default GraphQL Endpoint:
|
||||||
url: https://workshop.artemis-rgb.com/graphql
|
url: https://localhost:7281/graphql/
|
||||||
headers:
|
headers:
|
||||||
user-agent: JS GraphQL
|
user-agent: JS GraphQL
|
||||||
introspect: true
|
introspect: true
|
||||||
|
|||||||
@ -6,9 +6,9 @@ schema {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Category {
|
type Category {
|
||||||
icon: String!
|
|
||||||
id: Long!
|
id: Long!
|
||||||
name: String!
|
name: String!
|
||||||
|
icon: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
"Information about the offset pagination."
|
"Information about the offset pagination."
|
||||||
@ -19,25 +19,31 @@ type CollectionSegmentInfo {
|
|||||||
hasPreviousPage: Boolean!
|
hasPreviousPage: Boolean!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DefaultEntryInfo {
|
||||||
|
entryId: Long!
|
||||||
|
isEssential: Boolean!
|
||||||
|
isDeviceProvider: Boolean!
|
||||||
|
}
|
||||||
|
|
||||||
"A segment of a collection."
|
"A segment of a collection."
|
||||||
type EntriesCollectionSegment {
|
type EntriesCollectionSegment {
|
||||||
"A flattened list of the items."
|
|
||||||
items: [Entry!]
|
|
||||||
"Information to aid in pagination."
|
"Information to aid in pagination."
|
||||||
pageInfo: CollectionSegmentInfo!
|
pageInfo: CollectionSegmentInfo!
|
||||||
totalCount: Int!
|
"A flattened list of the items."
|
||||||
|
items: [Entry!]
|
||||||
|
totalCount: Int! @cost(weight: "10")
|
||||||
}
|
}
|
||||||
|
|
||||||
"A connection to a list of items."
|
"A connection to a list of items."
|
||||||
type EntriesV2Connection {
|
type EntriesV2Connection {
|
||||||
|
"Information to aid in pagination."
|
||||||
|
pageInfo: PageInfo!
|
||||||
"A list of edges."
|
"A list of edges."
|
||||||
edges: [EntriesV2Edge!]
|
edges: [EntriesV2Edge!]
|
||||||
"A flattened list of the nodes."
|
"A flattened list of the nodes."
|
||||||
nodes: [Entry!]
|
nodes: [Entry!]
|
||||||
"Information to aid in pagination."
|
|
||||||
pageInfo: PageInfo!
|
|
||||||
"Identifies the total count of items in the connection."
|
"Identifies the total count of items in the connection."
|
||||||
totalCount: Int!
|
totalCount: Int! @cost(weight: "10")
|
||||||
}
|
}
|
||||||
|
|
||||||
"An edge in a connection."
|
"An edge in a connection."
|
||||||
@ -49,142 +55,128 @@ type EntriesV2Edge {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Entry {
|
type Entry {
|
||||||
author: String!
|
id: Long!
|
||||||
authorId: UUID!
|
entryType: EntryType!
|
||||||
categories: [Category!]!
|
|
||||||
createdAt: DateTime!
|
createdAt: DateTime!
|
||||||
dependantReleases: [Release!]!
|
authorId: UUID!
|
||||||
|
author: String!
|
||||||
|
isOfficial: Boolean!
|
||||||
|
name: String!
|
||||||
|
summary: String!
|
||||||
description: String!
|
description: String!
|
||||||
downloads: Long!
|
downloads: Long!
|
||||||
entryType: EntryType!
|
|
||||||
icon: Image
|
|
||||||
iconId: UUID
|
iconId: UUID
|
||||||
id: Long!
|
icon: Image
|
||||||
images: [Image!]!
|
|
||||||
isDefault: Boolean!
|
|
||||||
isOfficial: Boolean!
|
|
||||||
latestRelease: Release
|
|
||||||
latestReleaseId: Long
|
latestReleaseId: Long
|
||||||
layoutInfo: [LayoutInfo!]!
|
latestRelease: Release
|
||||||
name: String!
|
|
||||||
pluginInfo: PluginInfo
|
pluginInfo: PluginInfo
|
||||||
popularityScore: Float!
|
layoutInfo: [LayoutInfo!]!
|
||||||
releases: [Release!]!
|
defaultEntryInfo: DefaultEntryInfo
|
||||||
summary: String!
|
categories: [Category!]!
|
||||||
tags: [Tag!]!
|
tags: [Tag!]!
|
||||||
|
images: [Image!]!
|
||||||
|
releases: [Release!]!
|
||||||
|
dependantReleases: [Release!]!
|
||||||
}
|
}
|
||||||
|
|
||||||
type Image {
|
type Image {
|
||||||
|
id: UUID!
|
||||||
|
name: String!
|
||||||
description: String
|
description: String
|
||||||
|
width: Int!
|
||||||
|
height: Int!
|
||||||
|
size: Long!
|
||||||
|
mimeType: String!
|
||||||
entry: Entry
|
entry: Entry
|
||||||
entryId: Long
|
entryId: Long
|
||||||
height: Int!
|
|
||||||
id: UUID!
|
|
||||||
mimeType: String!
|
|
||||||
name: String!
|
|
||||||
size: Long!
|
|
||||||
width: Int!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type LayoutInfo {
|
type LayoutInfo {
|
||||||
|
id: Long!
|
||||||
deviceProvider: UUID!
|
deviceProvider: UUID!
|
||||||
deviceType: RGBDeviceType!
|
deviceType: RGBDeviceType!
|
||||||
entry: Entry!
|
vendor: String!
|
||||||
entryId: Long!
|
|
||||||
id: Long!
|
|
||||||
logicalLayout: String
|
|
||||||
model: String!
|
model: String!
|
||||||
physicalLayout: KeyboardLayoutType
|
physicalLayout: KeyboardLayoutType
|
||||||
vendor: String!
|
logicalLayout: String
|
||||||
|
entryId: Long!
|
||||||
|
entry: Entry!
|
||||||
}
|
}
|
||||||
|
|
||||||
type Mutation {
|
type Mutation {
|
||||||
addEntry(input: CreateEntryInput!): Entry
|
addEntry(input: CreateEntryInput!): Entry @authorize @cost(weight: "10")
|
||||||
addLayoutInfo(input: CreateLayoutInfoInput!): LayoutInfo
|
updateEntry(input: UpdateEntryInput!): Entry @authorize @cost(weight: "10")
|
||||||
removeEntry(id: Long!): Entry
|
removeEntry(id: Long!): Entry @authorize @cost(weight: "10")
|
||||||
removeLayoutInfo(id: Long!): LayoutInfo!
|
updateEntryImage(input: UpdateEntryImageInput!): Image @authorize @cost(weight: "10")
|
||||||
removeRelease(id: Long!): Release!
|
setLayoutInfo(input: SetLayoutInfoInput!): [LayoutInfo!]! @authorize @cost(weight: "10")
|
||||||
setLayoutInfo(input: SetLayoutInfoInput!): [LayoutInfo!]!
|
addLayoutInfo(input: CreateLayoutInfoInput!): LayoutInfo @authorize @cost(weight: "10")
|
||||||
updateEntry(input: UpdateEntryInput!): Entry
|
removeLayoutInfo(id: Long!): LayoutInfo! @authorize @cost(weight: "10")
|
||||||
updateEntryImage(input: UpdateEntryImageInput!): Image
|
updateRelease(input: UpdateReleaseInput!): Release @authorize @cost(weight: "10")
|
||||||
updateRelease(input: UpdateReleaseInput!): Release
|
removeRelease(id: Long!): Release! @authorize @cost(weight: "10")
|
||||||
}
|
}
|
||||||
|
|
||||||
"Information about pagination in a connection."
|
"Information about pagination in a connection."
|
||||||
type PageInfo {
|
type PageInfo {
|
||||||
"When paginating forwards, the cursor to continue."
|
|
||||||
endCursor: String
|
|
||||||
"Indicates whether more edges exist following the set defined by the clients arguments."
|
"Indicates whether more edges exist following the set defined by the clients arguments."
|
||||||
hasNextPage: Boolean!
|
hasNextPage: Boolean!
|
||||||
"Indicates whether more edges exist prior the set defined by the clients arguments."
|
"Indicates whether more edges exist prior the set defined by the clients arguments."
|
||||||
hasPreviousPage: Boolean!
|
hasPreviousPage: Boolean!
|
||||||
"When paginating backwards, the cursor to continue."
|
"When paginating backwards, the cursor to continue."
|
||||||
startCursor: String
|
startCursor: String
|
||||||
|
"When paginating forwards, the cursor to continue."
|
||||||
|
endCursor: String
|
||||||
}
|
}
|
||||||
|
|
||||||
type PluginInfo {
|
type PluginInfo {
|
||||||
api: Int
|
|
||||||
entry: Entry!
|
|
||||||
entryId: Long!
|
entryId: Long!
|
||||||
helpPage: String
|
entry: Entry!
|
||||||
minmumVersion: String
|
|
||||||
pluginGuid: UUID!
|
pluginGuid: UUID!
|
||||||
|
api: Int
|
||||||
|
minmumVersion: String
|
||||||
|
website: String
|
||||||
|
helpPage: String
|
||||||
repository: String
|
repository: String
|
||||||
requiresAdmin: Boolean!
|
requiresAdmin: Boolean!
|
||||||
|
supportsWindows: Boolean!
|
||||||
supportsLinux: Boolean!
|
supportsLinux: Boolean!
|
||||||
supportsOSX: Boolean!
|
supportsOSX: Boolean!
|
||||||
supportsWindows: Boolean!
|
|
||||||
website: String
|
|
||||||
}
|
}
|
||||||
|
|
||||||
"A segment of a collection."
|
"A segment of a collection."
|
||||||
type PluginInfosCollectionSegment {
|
type PluginInfosCollectionSegment {
|
||||||
"A flattened list of the items."
|
|
||||||
items: [PluginInfo!]
|
|
||||||
"Information to aid in pagination."
|
"Information to aid in pagination."
|
||||||
pageInfo: CollectionSegmentInfo!
|
pageInfo: CollectionSegmentInfo!
|
||||||
totalCount: Int!
|
"A flattened list of the items."
|
||||||
|
items: [PluginInfo!]
|
||||||
|
totalCount: Int! @cost(weight: "10")
|
||||||
}
|
}
|
||||||
|
|
||||||
type Query {
|
type Query {
|
||||||
categories(order: [CategorySortInput!], where: CategoryFilterInput): [Category!]!
|
categories(order: [CategorySortInput!] @cost(weight: "10") where: CategoryFilterInput @cost(weight: "10")): [Category!]! @cost(weight: "10")
|
||||||
entries(order: [EntrySortInput!], popular: Boolean, search: String, skip: Int, take: Int, where: EntryFilterInput): EntriesCollectionSegment
|
entries(skip: Int take: Int search: String popular: Boolean order: [EntrySortInput!] @cost(weight: "10") where: EntryFilterInput @cost(weight: "10")): EntriesCollectionSegment @listSize(assumedSize: 100, slicingArguments: [ "take" ], slicingArgumentDefaultValue: 10, sizedFields: [ "items" ], requireOneSlicingArgument: false) @cost(weight: "10")
|
||||||
entriesV2(
|
entriesV2(search: String popular: Boolean "Returns the first _n_ elements from the list." first: Int "Returns the elements in the list that come after the specified cursor." after: String "Returns the last _n_ elements from the list." last: Int "Returns the elements in the list that come before the specified cursor." before: String order: [EntrySortInput!] @cost(weight: "10") where: EntryFilterInput @cost(weight: "10")): EntriesV2Connection @listSize(assumedSize: 100, slicingArguments: [ "first", "last" ], slicingArgumentDefaultValue: 10, sizedFields: [ "edges", "nodes" ], requireOneSlicingArgument: false) @cost(weight: "10")
|
||||||
"Returns the elements in the list that come after the specified cursor."
|
entry(id: Long!): Entry @cost(weight: "10")
|
||||||
after: String,
|
submittedEntries(order: [EntrySortInput!] @cost(weight: "10") where: EntryFilterInput @cost(weight: "10")): [Entry!]! @authorize @cost(weight: "10")
|
||||||
"Returns the elements in the list that come before the specified cursor."
|
popularEntries(where: EntryFilterInput @cost(weight: "10")): [Entry!]! @cost(weight: "10")
|
||||||
before: String,
|
searchEntries(input: String! type: EntryType order: [EntrySortInput!] @cost(weight: "10") where: EntryFilterInput @cost(weight: "10")): [Entry!]! @cost(weight: "10")
|
||||||
"Returns the first _n_ elements from the list."
|
searchLayout(deviceProvider: UUID! deviceType: RGBDeviceType! vendor: String! model: String!): LayoutInfo @cost(weight: "10")
|
||||||
first: Int,
|
searchKeyboardLayout(deviceProvider: UUID! vendor: String! model: String! physicalLayout: KeyboardLayoutType! logicalLayout: String): LayoutInfo @cost(weight: "10")
|
||||||
"Returns the last _n_ elements from the list."
|
pluginInfos(skip: Int take: Int order: [PluginInfoSortInput!] @cost(weight: "10") where: PluginInfoFilterInput @cost(weight: "10")): PluginInfosCollectionSegment @listSize(assumedSize: 100, slicingArguments: [ "take" ], slicingArgumentDefaultValue: 10, sizedFields: [ "items" ], requireOneSlicingArgument: false) @cost(weight: "10")
|
||||||
last: Int,
|
pluginInfo(pluginGuid: UUID!): PluginInfo @cost(weight: "10")
|
||||||
order: [EntrySortInput!],
|
release(id: Long!): Release @cost(weight: "10")
|
||||||
popular: Boolean,
|
|
||||||
search: String,
|
|
||||||
where: EntryFilterInput
|
|
||||||
): EntriesV2Connection
|
|
||||||
entry(id: Long!): Entry
|
|
||||||
pluginInfo(pluginGuid: UUID!): PluginInfo
|
|
||||||
pluginInfos(order: [PluginInfoSortInput!], skip: Int, take: Int, where: PluginInfoFilterInput): PluginInfosCollectionSegment
|
|
||||||
popularEntries(where: EntryFilterInput): [Entry!]!
|
|
||||||
release(id: Long!): Release
|
|
||||||
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
|
|
||||||
submittedEntries(order: [EntrySortInput!], where: EntryFilterInput): [Entry!]!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Release {
|
type Release {
|
||||||
|
id: Long!
|
||||||
|
version: String!
|
||||||
changelog: String
|
changelog: String
|
||||||
createdAt: DateTime!
|
createdAt: DateTime!
|
||||||
dependencies: [Entry!]!
|
|
||||||
downloadSize: Long!
|
|
||||||
downloads: Long!
|
downloads: Long!
|
||||||
|
downloadSize: Long!
|
||||||
|
md5Hash: String
|
||||||
entry: Entry!
|
entry: Entry!
|
||||||
entryId: Long!
|
entryId: Long!
|
||||||
id: Long!
|
dependencies: [Entry!]!
|
||||||
md5Hash: String
|
|
||||||
version: String!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Tag {
|
type Tag {
|
||||||
@ -192,379 +184,324 @@ type Tag {
|
|||||||
name: String!
|
name: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ApplyPolicy {
|
|
||||||
AFTER_RESOLVER
|
|
||||||
BEFORE_RESOLVER
|
|
||||||
VALIDATION
|
|
||||||
}
|
|
||||||
|
|
||||||
enum EntryType {
|
|
||||||
LAYOUT
|
|
||||||
PLUGIN
|
|
||||||
PROFILE
|
|
||||||
}
|
|
||||||
|
|
||||||
enum KeyboardLayoutType {
|
|
||||||
ABNT
|
|
||||||
ANSI
|
|
||||||
ISO
|
|
||||||
JIS
|
|
||||||
KS
|
|
||||||
UNKNOWN
|
|
||||||
}
|
|
||||||
|
|
||||||
enum RGBDeviceType {
|
|
||||||
ALL
|
|
||||||
COOLER
|
|
||||||
DRAM
|
|
||||||
FAN
|
|
||||||
GAME_CONTROLLER
|
|
||||||
GRAPHICS_CARD
|
|
||||||
HEADSET
|
|
||||||
HEADSET_STAND
|
|
||||||
KEYBOARD
|
|
||||||
KEYPAD
|
|
||||||
LED_CONTROLLER
|
|
||||||
LED_MATRIX
|
|
||||||
LED_STRIPE
|
|
||||||
MAINBOARD
|
|
||||||
MONITOR
|
|
||||||
MOUSE
|
|
||||||
MOUSEPAD
|
|
||||||
NONE
|
|
||||||
SPEAKER
|
|
||||||
UNKNOWN
|
|
||||||
}
|
|
||||||
|
|
||||||
enum SortEnumType {
|
|
||||||
ASC
|
|
||||||
DESC
|
|
||||||
}
|
|
||||||
|
|
||||||
"The `DateTime` scalar represents an ISO-8601 compliant date time type."
|
|
||||||
scalar DateTime
|
|
||||||
|
|
||||||
"The `Long` scalar type represents non-fractional signed whole 64-bit numeric values. Long can represent values between -(2^63) and 2^63 - 1."
|
|
||||||
scalar Long
|
|
||||||
|
|
||||||
scalar UUID
|
|
||||||
|
|
||||||
input BooleanOperationFilterInput {
|
input BooleanOperationFilterInput {
|
||||||
eq: Boolean
|
eq: Boolean @cost(weight: "10")
|
||||||
neq: Boolean
|
neq: Boolean @cost(weight: "10")
|
||||||
}
|
}
|
||||||
|
|
||||||
input CategoryFilterInput {
|
input CategoryFilterInput {
|
||||||
and: [CategoryFilterInput!]
|
and: [CategoryFilterInput!]
|
||||||
icon: StringOperationFilterInput
|
or: [CategoryFilterInput!]
|
||||||
id: LongOperationFilterInput
|
id: LongOperationFilterInput
|
||||||
name: StringOperationFilterInput
|
name: StringOperationFilterInput
|
||||||
or: [CategoryFilterInput!]
|
icon: StringOperationFilterInput
|
||||||
}
|
}
|
||||||
|
|
||||||
input CategorySortInput {
|
input CategorySortInput {
|
||||||
icon: SortEnumType
|
id: SortEnumType @cost(weight: "10")
|
||||||
id: SortEnumType
|
name: SortEnumType @cost(weight: "10")
|
||||||
name: SortEnumType
|
icon: SortEnumType @cost(weight: "10")
|
||||||
}
|
}
|
||||||
|
|
||||||
input CreateEntryInput {
|
input CreateEntryInput {
|
||||||
categories: [Long!]!
|
|
||||||
description: String!
|
|
||||||
entryType: EntryType!
|
entryType: EntryType!
|
||||||
isDefault: Boolean!
|
|
||||||
name: String!
|
name: String!
|
||||||
summary: String!
|
summary: String!
|
||||||
|
description: String!
|
||||||
|
categories: [Long!]!
|
||||||
tags: [String!]!
|
tags: [String!]!
|
||||||
|
defaultEntryInfo: DefaultEntryInfoInput
|
||||||
}
|
}
|
||||||
|
|
||||||
input CreateLayoutInfoInput {
|
input CreateLayoutInfoInput {
|
||||||
|
entryId: Long!
|
||||||
deviceProvider: UUID!
|
deviceProvider: UUID!
|
||||||
deviceType: RGBDeviceType!
|
deviceType: RGBDeviceType!
|
||||||
entryId: Long!
|
vendor: String!
|
||||||
logicalLayout: String
|
|
||||||
model: String!
|
model: String!
|
||||||
physicalLayout: KeyboardLayoutType
|
physicalLayout: KeyboardLayoutType
|
||||||
vendor: String!
|
logicalLayout: String
|
||||||
}
|
}
|
||||||
|
|
||||||
input DateTimeOperationFilterInput {
|
input DateTimeOperationFilterInput {
|
||||||
eq: DateTime
|
eq: DateTime @cost(weight: "10")
|
||||||
gt: DateTime
|
neq: DateTime @cost(weight: "10")
|
||||||
gte: DateTime
|
in: [DateTime] @cost(weight: "10")
|
||||||
in: [DateTime]
|
nin: [DateTime] @cost(weight: "10")
|
||||||
lt: DateTime
|
gt: DateTime @cost(weight: "10")
|
||||||
lte: DateTime
|
ngt: DateTime @cost(weight: "10")
|
||||||
neq: DateTime
|
gte: DateTime @cost(weight: "10")
|
||||||
ngt: DateTime
|
ngte: DateTime @cost(weight: "10")
|
||||||
ngte: DateTime
|
lt: DateTime @cost(weight: "10")
|
||||||
nin: [DateTime]
|
nlt: DateTime @cost(weight: "10")
|
||||||
nlt: DateTime
|
lte: DateTime @cost(weight: "10")
|
||||||
nlte: DateTime
|
nlte: DateTime @cost(weight: "10")
|
||||||
|
}
|
||||||
|
|
||||||
|
input DefaultEntryInfoFilterInput {
|
||||||
|
and: [DefaultEntryInfoFilterInput!]
|
||||||
|
or: [DefaultEntryInfoFilterInput!]
|
||||||
|
entryId: LongOperationFilterInput
|
||||||
|
isEssential: BooleanOperationFilterInput
|
||||||
|
isDeviceProvider: BooleanOperationFilterInput
|
||||||
|
}
|
||||||
|
|
||||||
|
input DefaultEntryInfoInput {
|
||||||
|
isEssential: Boolean!
|
||||||
|
isDeviceProvider: Boolean!
|
||||||
|
}
|
||||||
|
|
||||||
|
input DefaultEntryInfoSortInput {
|
||||||
|
entryId: SortEnumType @cost(weight: "10")
|
||||||
|
isEssential: SortEnumType @cost(weight: "10")
|
||||||
|
isDeviceProvider: SortEnumType @cost(weight: "10")
|
||||||
}
|
}
|
||||||
|
|
||||||
input EntryFilterInput {
|
input EntryFilterInput {
|
||||||
and: [EntryFilterInput!]
|
and: [EntryFilterInput!]
|
||||||
author: StringOperationFilterInput
|
or: [EntryFilterInput!]
|
||||||
authorId: UuidOperationFilterInput
|
id: LongOperationFilterInput
|
||||||
categories: ListFilterInputTypeOfCategoryFilterInput
|
entryType: EntryTypeOperationFilterInput
|
||||||
createdAt: DateTimeOperationFilterInput
|
createdAt: DateTimeOperationFilterInput
|
||||||
dependantReleases: ListFilterInputTypeOfReleaseFilterInput
|
authorId: UuidOperationFilterInput
|
||||||
|
author: StringOperationFilterInput
|
||||||
|
isOfficial: BooleanOperationFilterInput
|
||||||
|
name: StringOperationFilterInput
|
||||||
|
summary: StringOperationFilterInput
|
||||||
description: StringOperationFilterInput
|
description: StringOperationFilterInput
|
||||||
downloads: LongOperationFilterInput
|
downloads: LongOperationFilterInput
|
||||||
entryType: EntryTypeOperationFilterInput
|
|
||||||
icon: ImageFilterInput
|
|
||||||
iconId: UuidOperationFilterInput
|
iconId: UuidOperationFilterInput
|
||||||
id: LongOperationFilterInput
|
icon: ImageFilterInput
|
||||||
images: ListFilterInputTypeOfImageFilterInput
|
|
||||||
isDefault: BooleanOperationFilterInput
|
|
||||||
isOfficial: BooleanOperationFilterInput
|
|
||||||
latestRelease: ReleaseFilterInput
|
|
||||||
latestReleaseId: LongOperationFilterInput
|
latestReleaseId: LongOperationFilterInput
|
||||||
layoutInfo: ListFilterInputTypeOfLayoutInfoFilterInput
|
latestRelease: ReleaseFilterInput
|
||||||
name: StringOperationFilterInput
|
|
||||||
or: [EntryFilterInput!]
|
|
||||||
pluginInfo: PluginInfoFilterInput
|
pluginInfo: PluginInfoFilterInput
|
||||||
popularityScore: FloatOperationFilterInput
|
layoutInfo: ListFilterInputTypeOfLayoutInfoFilterInput
|
||||||
releases: ListFilterInputTypeOfReleaseFilterInput
|
defaultEntryInfo: DefaultEntryInfoFilterInput
|
||||||
summary: StringOperationFilterInput
|
categories: ListFilterInputTypeOfCategoryFilterInput
|
||||||
tags: ListFilterInputTypeOfTagFilterInput
|
tags: ListFilterInputTypeOfTagFilterInput
|
||||||
|
images: ListFilterInputTypeOfImageFilterInput
|
||||||
|
releases: ListFilterInputTypeOfReleaseFilterInput
|
||||||
|
dependantReleases: ListFilterInputTypeOfReleaseFilterInput
|
||||||
}
|
}
|
||||||
|
|
||||||
input EntrySortInput {
|
input EntrySortInput {
|
||||||
author: SortEnumType
|
id: SortEnumType @cost(weight: "10")
|
||||||
authorId: SortEnumType
|
entryType: SortEnumType @cost(weight: "10")
|
||||||
createdAt: SortEnumType
|
createdAt: SortEnumType @cost(weight: "10")
|
||||||
description: SortEnumType
|
authorId: SortEnumType @cost(weight: "10")
|
||||||
downloads: SortEnumType
|
author: SortEnumType @cost(weight: "10")
|
||||||
entryType: SortEnumType
|
isOfficial: SortEnumType @cost(weight: "10")
|
||||||
icon: ImageSortInput
|
name: SortEnumType @cost(weight: "10")
|
||||||
iconId: SortEnumType
|
summary: SortEnumType @cost(weight: "10")
|
||||||
id: SortEnumType
|
description: SortEnumType @cost(weight: "10")
|
||||||
isDefault: SortEnumType
|
downloads: SortEnumType @cost(weight: "10")
|
||||||
isOfficial: SortEnumType
|
iconId: SortEnumType @cost(weight: "10")
|
||||||
latestRelease: ReleaseSortInput
|
icon: ImageSortInput @cost(weight: "10")
|
||||||
latestReleaseId: SortEnumType
|
latestReleaseId: SortEnumType @cost(weight: "10")
|
||||||
name: SortEnumType
|
latestRelease: ReleaseSortInput @cost(weight: "10")
|
||||||
pluginInfo: PluginInfoSortInput
|
pluginInfo: PluginInfoSortInput @cost(weight: "10")
|
||||||
popularityScore: SortEnumType
|
defaultEntryInfo: DefaultEntryInfoSortInput @cost(weight: "10")
|
||||||
summary: SortEnumType
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input EntryTypeOperationFilterInput {
|
input EntryTypeOperationFilterInput {
|
||||||
eq: EntryType
|
eq: EntryType @cost(weight: "10")
|
||||||
in: [EntryType!]
|
neq: EntryType @cost(weight: "10")
|
||||||
neq: EntryType
|
in: [EntryType!] @cost(weight: "10")
|
||||||
nin: [EntryType!]
|
nin: [EntryType!] @cost(weight: "10")
|
||||||
}
|
|
||||||
|
|
||||||
input FloatOperationFilterInput {
|
|
||||||
eq: Float
|
|
||||||
gt: Float
|
|
||||||
gte: Float
|
|
||||||
in: [Float]
|
|
||||||
lt: Float
|
|
||||||
lte: Float
|
|
||||||
neq: Float
|
|
||||||
ngt: Float
|
|
||||||
ngte: Float
|
|
||||||
nin: [Float]
|
|
||||||
nlt: Float
|
|
||||||
nlte: Float
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input ImageFilterInput {
|
input ImageFilterInput {
|
||||||
and: [ImageFilterInput!]
|
and: [ImageFilterInput!]
|
||||||
|
or: [ImageFilterInput!]
|
||||||
|
id: UuidOperationFilterInput
|
||||||
|
name: StringOperationFilterInput
|
||||||
description: StringOperationFilterInput
|
description: StringOperationFilterInput
|
||||||
|
width: IntOperationFilterInput
|
||||||
|
height: IntOperationFilterInput
|
||||||
|
size: LongOperationFilterInput
|
||||||
|
mimeType: StringOperationFilterInput
|
||||||
entry: EntryFilterInput
|
entry: EntryFilterInput
|
||||||
entryId: LongOperationFilterInput
|
entryId: LongOperationFilterInput
|
||||||
height: IntOperationFilterInput
|
|
||||||
id: UuidOperationFilterInput
|
|
||||||
mimeType: StringOperationFilterInput
|
|
||||||
name: StringOperationFilterInput
|
|
||||||
or: [ImageFilterInput!]
|
|
||||||
size: LongOperationFilterInput
|
|
||||||
width: IntOperationFilterInput
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input ImageSortInput {
|
input ImageSortInput {
|
||||||
description: SortEnumType
|
id: SortEnumType @cost(weight: "10")
|
||||||
entry: EntrySortInput
|
name: SortEnumType @cost(weight: "10")
|
||||||
entryId: SortEnumType
|
description: SortEnumType @cost(weight: "10")
|
||||||
height: SortEnumType
|
width: SortEnumType @cost(weight: "10")
|
||||||
id: SortEnumType
|
height: SortEnumType @cost(weight: "10")
|
||||||
mimeType: SortEnumType
|
size: SortEnumType @cost(weight: "10")
|
||||||
name: SortEnumType
|
mimeType: SortEnumType @cost(weight: "10")
|
||||||
size: SortEnumType
|
entry: EntrySortInput @cost(weight: "10")
|
||||||
width: SortEnumType
|
entryId: SortEnumType @cost(weight: "10")
|
||||||
}
|
}
|
||||||
|
|
||||||
input IntOperationFilterInput {
|
input IntOperationFilterInput {
|
||||||
eq: Int
|
eq: Int @cost(weight: "10")
|
||||||
gt: Int
|
neq: Int @cost(weight: "10")
|
||||||
gte: Int
|
in: [Int] @cost(weight: "10")
|
||||||
in: [Int]
|
nin: [Int] @cost(weight: "10")
|
||||||
lt: Int
|
gt: Int @cost(weight: "10")
|
||||||
lte: Int
|
ngt: Int @cost(weight: "10")
|
||||||
neq: Int
|
gte: Int @cost(weight: "10")
|
||||||
ngt: Int
|
ngte: Int @cost(weight: "10")
|
||||||
ngte: Int
|
lt: Int @cost(weight: "10")
|
||||||
nin: [Int]
|
nlt: Int @cost(weight: "10")
|
||||||
nlt: Int
|
lte: Int @cost(weight: "10")
|
||||||
nlte: Int
|
nlte: Int @cost(weight: "10")
|
||||||
}
|
}
|
||||||
|
|
||||||
input LayoutInfoFilterInput {
|
input LayoutInfoFilterInput {
|
||||||
and: [LayoutInfoFilterInput!]
|
and: [LayoutInfoFilterInput!]
|
||||||
|
or: [LayoutInfoFilterInput!]
|
||||||
|
id: LongOperationFilterInput
|
||||||
deviceProvider: UuidOperationFilterInput
|
deviceProvider: UuidOperationFilterInput
|
||||||
deviceType: RGBDeviceTypeOperationFilterInput
|
deviceType: RGBDeviceTypeOperationFilterInput
|
||||||
entry: EntryFilterInput
|
|
||||||
entryId: LongOperationFilterInput
|
|
||||||
id: LongOperationFilterInput
|
|
||||||
logicalLayout: StringOperationFilterInput
|
|
||||||
model: StringOperationFilterInput
|
|
||||||
or: [LayoutInfoFilterInput!]
|
|
||||||
physicalLayout: NullableOfKeyboardLayoutTypeOperationFilterInput
|
|
||||||
vendor: StringOperationFilterInput
|
vendor: StringOperationFilterInput
|
||||||
|
model: StringOperationFilterInput
|
||||||
|
physicalLayout: NullableOfKeyboardLayoutTypeOperationFilterInput
|
||||||
|
logicalLayout: StringOperationFilterInput
|
||||||
|
entryId: LongOperationFilterInput
|
||||||
|
entry: EntryFilterInput
|
||||||
}
|
}
|
||||||
|
|
||||||
input LayoutInfoInput {
|
input LayoutInfoInput {
|
||||||
deviceProvider: UUID!
|
deviceProvider: UUID!
|
||||||
deviceType: RGBDeviceType!
|
deviceType: RGBDeviceType!
|
||||||
logicalLayout: String
|
vendor: String!
|
||||||
model: String!
|
model: String!
|
||||||
physicalLayout: KeyboardLayoutType
|
physicalLayout: KeyboardLayoutType
|
||||||
vendor: String!
|
logicalLayout: String
|
||||||
}
|
}
|
||||||
|
|
||||||
input ListFilterInputTypeOfCategoryFilterInput {
|
input ListFilterInputTypeOfCategoryFilterInput {
|
||||||
all: CategoryFilterInput
|
all: CategoryFilterInput @cost(weight: "10")
|
||||||
any: Boolean
|
none: CategoryFilterInput @cost(weight: "10")
|
||||||
none: CategoryFilterInput
|
some: CategoryFilterInput @cost(weight: "10")
|
||||||
some: CategoryFilterInput
|
any: Boolean @cost(weight: "10")
|
||||||
}
|
}
|
||||||
|
|
||||||
input ListFilterInputTypeOfEntryFilterInput {
|
input ListFilterInputTypeOfEntryFilterInput {
|
||||||
all: EntryFilterInput
|
all: EntryFilterInput @cost(weight: "10")
|
||||||
any: Boolean
|
none: EntryFilterInput @cost(weight: "10")
|
||||||
none: EntryFilterInput
|
some: EntryFilterInput @cost(weight: "10")
|
||||||
some: EntryFilterInput
|
any: Boolean @cost(weight: "10")
|
||||||
}
|
}
|
||||||
|
|
||||||
input ListFilterInputTypeOfImageFilterInput {
|
input ListFilterInputTypeOfImageFilterInput {
|
||||||
all: ImageFilterInput
|
all: ImageFilterInput @cost(weight: "10")
|
||||||
any: Boolean
|
none: ImageFilterInput @cost(weight: "10")
|
||||||
none: ImageFilterInput
|
some: ImageFilterInput @cost(weight: "10")
|
||||||
some: ImageFilterInput
|
any: Boolean @cost(weight: "10")
|
||||||
}
|
}
|
||||||
|
|
||||||
input ListFilterInputTypeOfLayoutInfoFilterInput {
|
input ListFilterInputTypeOfLayoutInfoFilterInput {
|
||||||
all: LayoutInfoFilterInput
|
all: LayoutInfoFilterInput @cost(weight: "10")
|
||||||
any: Boolean
|
none: LayoutInfoFilterInput @cost(weight: "10")
|
||||||
none: LayoutInfoFilterInput
|
some: LayoutInfoFilterInput @cost(weight: "10")
|
||||||
some: LayoutInfoFilterInput
|
any: Boolean @cost(weight: "10")
|
||||||
}
|
}
|
||||||
|
|
||||||
input ListFilterInputTypeOfReleaseFilterInput {
|
input ListFilterInputTypeOfReleaseFilterInput {
|
||||||
all: ReleaseFilterInput
|
all: ReleaseFilterInput @cost(weight: "10")
|
||||||
any: Boolean
|
none: ReleaseFilterInput @cost(weight: "10")
|
||||||
none: ReleaseFilterInput
|
some: ReleaseFilterInput @cost(weight: "10")
|
||||||
some: ReleaseFilterInput
|
any: Boolean @cost(weight: "10")
|
||||||
}
|
}
|
||||||
|
|
||||||
input ListFilterInputTypeOfTagFilterInput {
|
input ListFilterInputTypeOfTagFilterInput {
|
||||||
all: TagFilterInput
|
all: TagFilterInput @cost(weight: "10")
|
||||||
any: Boolean
|
none: TagFilterInput @cost(weight: "10")
|
||||||
none: TagFilterInput
|
some: TagFilterInput @cost(weight: "10")
|
||||||
some: TagFilterInput
|
any: Boolean @cost(weight: "10")
|
||||||
}
|
}
|
||||||
|
|
||||||
input LongOperationFilterInput {
|
input LongOperationFilterInput {
|
||||||
eq: Long
|
eq: Long @cost(weight: "10")
|
||||||
gt: Long
|
neq: Long @cost(weight: "10")
|
||||||
gte: Long
|
in: [Long] @cost(weight: "10")
|
||||||
in: [Long]
|
nin: [Long] @cost(weight: "10")
|
||||||
lt: Long
|
gt: Long @cost(weight: "10")
|
||||||
lte: Long
|
ngt: Long @cost(weight: "10")
|
||||||
neq: Long
|
gte: Long @cost(weight: "10")
|
||||||
ngt: Long
|
ngte: Long @cost(weight: "10")
|
||||||
ngte: Long
|
lt: Long @cost(weight: "10")
|
||||||
nin: [Long]
|
nlt: Long @cost(weight: "10")
|
||||||
nlt: Long
|
lte: Long @cost(weight: "10")
|
||||||
nlte: Long
|
nlte: Long @cost(weight: "10")
|
||||||
}
|
}
|
||||||
|
|
||||||
input NullableOfKeyboardLayoutTypeOperationFilterInput {
|
input NullableOfKeyboardLayoutTypeOperationFilterInput {
|
||||||
eq: KeyboardLayoutType
|
eq: KeyboardLayoutType @cost(weight: "10")
|
||||||
in: [KeyboardLayoutType]
|
neq: KeyboardLayoutType @cost(weight: "10")
|
||||||
neq: KeyboardLayoutType
|
in: [KeyboardLayoutType] @cost(weight: "10")
|
||||||
nin: [KeyboardLayoutType]
|
nin: [KeyboardLayoutType] @cost(weight: "10")
|
||||||
}
|
}
|
||||||
|
|
||||||
input PluginInfoFilterInput {
|
input PluginInfoFilterInput {
|
||||||
and: [PluginInfoFilterInput!]
|
and: [PluginInfoFilterInput!]
|
||||||
api: IntOperationFilterInput
|
|
||||||
entry: EntryFilterInput
|
|
||||||
entryId: LongOperationFilterInput
|
|
||||||
helpPage: StringOperationFilterInput
|
|
||||||
minmumVersion: StringOperationFilterInput
|
|
||||||
or: [PluginInfoFilterInput!]
|
or: [PluginInfoFilterInput!]
|
||||||
|
entryId: LongOperationFilterInput
|
||||||
|
entry: EntryFilterInput
|
||||||
pluginGuid: UuidOperationFilterInput
|
pluginGuid: UuidOperationFilterInput
|
||||||
|
api: IntOperationFilterInput
|
||||||
|
minmumVersion: StringOperationFilterInput
|
||||||
|
website: StringOperationFilterInput
|
||||||
|
helpPage: StringOperationFilterInput
|
||||||
repository: StringOperationFilterInput
|
repository: StringOperationFilterInput
|
||||||
requiresAdmin: BooleanOperationFilterInput
|
requiresAdmin: BooleanOperationFilterInput
|
||||||
|
supportsWindows: BooleanOperationFilterInput
|
||||||
supportsLinux: BooleanOperationFilterInput
|
supportsLinux: BooleanOperationFilterInput
|
||||||
supportsOSX: BooleanOperationFilterInput
|
supportsOSX: BooleanOperationFilterInput
|
||||||
supportsWindows: BooleanOperationFilterInput
|
|
||||||
website: StringOperationFilterInput
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input PluginInfoSortInput {
|
input PluginInfoSortInput {
|
||||||
api: SortEnumType
|
entryId: SortEnumType @cost(weight: "10")
|
||||||
entry: EntrySortInput
|
entry: EntrySortInput @cost(weight: "10")
|
||||||
entryId: SortEnumType
|
pluginGuid: SortEnumType @cost(weight: "10")
|
||||||
helpPage: SortEnumType
|
api: SortEnumType @cost(weight: "10")
|
||||||
minmumVersion: SortEnumType
|
minmumVersion: SortEnumType @cost(weight: "10")
|
||||||
pluginGuid: SortEnumType
|
website: SortEnumType @cost(weight: "10")
|
||||||
repository: SortEnumType
|
helpPage: SortEnumType @cost(weight: "10")
|
||||||
requiresAdmin: SortEnumType
|
repository: SortEnumType @cost(weight: "10")
|
||||||
supportsLinux: SortEnumType
|
requiresAdmin: SortEnumType @cost(weight: "10")
|
||||||
supportsOSX: SortEnumType
|
supportsWindows: SortEnumType @cost(weight: "10")
|
||||||
supportsWindows: SortEnumType
|
supportsLinux: SortEnumType @cost(weight: "10")
|
||||||
website: SortEnumType
|
supportsOSX: SortEnumType @cost(weight: "10")
|
||||||
}
|
}
|
||||||
|
|
||||||
input RGBDeviceTypeOperationFilterInput {
|
input RGBDeviceTypeOperationFilterInput {
|
||||||
eq: RGBDeviceType
|
eq: RGBDeviceType @cost(weight: "10")
|
||||||
in: [RGBDeviceType!]
|
neq: RGBDeviceType @cost(weight: "10")
|
||||||
neq: RGBDeviceType
|
in: [RGBDeviceType!] @cost(weight: "10")
|
||||||
nin: [RGBDeviceType!]
|
nin: [RGBDeviceType!] @cost(weight: "10")
|
||||||
}
|
}
|
||||||
|
|
||||||
input ReleaseFilterInput {
|
input ReleaseFilterInput {
|
||||||
and: [ReleaseFilterInput!]
|
and: [ReleaseFilterInput!]
|
||||||
|
or: [ReleaseFilterInput!]
|
||||||
|
id: LongOperationFilterInput
|
||||||
|
version: StringOperationFilterInput
|
||||||
changelog: StringOperationFilterInput
|
changelog: StringOperationFilterInput
|
||||||
createdAt: DateTimeOperationFilterInput
|
createdAt: DateTimeOperationFilterInput
|
||||||
dependencies: ListFilterInputTypeOfEntryFilterInput
|
|
||||||
downloadSize: LongOperationFilterInput
|
|
||||||
downloads: LongOperationFilterInput
|
downloads: LongOperationFilterInput
|
||||||
|
downloadSize: LongOperationFilterInput
|
||||||
|
md5Hash: StringOperationFilterInput
|
||||||
entry: EntryFilterInput
|
entry: EntryFilterInput
|
||||||
entryId: LongOperationFilterInput
|
entryId: LongOperationFilterInput
|
||||||
id: LongOperationFilterInput
|
dependencies: ListFilterInputTypeOfEntryFilterInput
|
||||||
md5Hash: StringOperationFilterInput
|
|
||||||
or: [ReleaseFilterInput!]
|
|
||||||
version: StringOperationFilterInput
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input ReleaseSortInput {
|
input ReleaseSortInput {
|
||||||
changelog: SortEnumType
|
id: SortEnumType @cost(weight: "10")
|
||||||
createdAt: SortEnumType
|
version: SortEnumType @cost(weight: "10")
|
||||||
downloadSize: SortEnumType
|
changelog: SortEnumType @cost(weight: "10")
|
||||||
downloads: SortEnumType
|
createdAt: SortEnumType @cost(weight: "10")
|
||||||
entry: EntrySortInput
|
downloads: SortEnumType @cost(weight: "10")
|
||||||
entryId: SortEnumType
|
downloadSize: SortEnumType @cost(weight: "10")
|
||||||
id: SortEnumType
|
md5Hash: SortEnumType @cost(weight: "10")
|
||||||
md5Hash: SortEnumType
|
entry: EntrySortInput @cost(weight: "10")
|
||||||
version: SortEnumType
|
entryId: SortEnumType @cost(weight: "10")
|
||||||
}
|
}
|
||||||
|
|
||||||
input SetLayoutInfoInput {
|
input SetLayoutInfoInput {
|
||||||
@ -574,58 +511,131 @@ input SetLayoutInfoInput {
|
|||||||
|
|
||||||
input StringOperationFilterInput {
|
input StringOperationFilterInput {
|
||||||
and: [StringOperationFilterInput!]
|
and: [StringOperationFilterInput!]
|
||||||
contains: String
|
|
||||||
endsWith: String
|
|
||||||
eq: String
|
|
||||||
in: [String]
|
|
||||||
ncontains: String
|
|
||||||
nendsWith: String
|
|
||||||
neq: String
|
|
||||||
nin: [String]
|
|
||||||
nstartsWith: String
|
|
||||||
or: [StringOperationFilterInput!]
|
or: [StringOperationFilterInput!]
|
||||||
startsWith: String
|
eq: String @cost(weight: "10")
|
||||||
|
neq: String @cost(weight: "10")
|
||||||
|
contains: String @cost(weight: "20")
|
||||||
|
ncontains: String @cost(weight: "20")
|
||||||
|
in: [String] @cost(weight: "10")
|
||||||
|
nin: [String] @cost(weight: "10")
|
||||||
|
startsWith: String @cost(weight: "20")
|
||||||
|
nstartsWith: String @cost(weight: "20")
|
||||||
|
endsWith: String @cost(weight: "20")
|
||||||
|
nendsWith: String @cost(weight: "20")
|
||||||
}
|
}
|
||||||
|
|
||||||
input TagFilterInput {
|
input TagFilterInput {
|
||||||
and: [TagFilterInput!]
|
and: [TagFilterInput!]
|
||||||
|
or: [TagFilterInput!]
|
||||||
id: LongOperationFilterInput
|
id: LongOperationFilterInput
|
||||||
name: StringOperationFilterInput
|
name: StringOperationFilterInput
|
||||||
or: [TagFilterInput!]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input UpdateEntryImageInput {
|
input UpdateEntryImageInput {
|
||||||
description: String
|
|
||||||
id: UUID!
|
id: UUID!
|
||||||
name: String!
|
name: String!
|
||||||
|
description: String
|
||||||
}
|
}
|
||||||
|
|
||||||
input UpdateEntryInput {
|
input UpdateEntryInput {
|
||||||
categories: [Long!]!
|
|
||||||
description: String!
|
|
||||||
id: Long!
|
id: Long!
|
||||||
isDefault: Boolean!
|
|
||||||
name: String!
|
name: String!
|
||||||
summary: String!
|
summary: String!
|
||||||
|
description: String!
|
||||||
|
categories: [Long!]!
|
||||||
tags: [String!]!
|
tags: [String!]!
|
||||||
|
defaultEntryInfo: DefaultEntryInfoInput
|
||||||
}
|
}
|
||||||
|
|
||||||
input UpdateReleaseInput {
|
input UpdateReleaseInput {
|
||||||
changelog: String
|
|
||||||
id: Long!
|
id: Long!
|
||||||
|
changelog: String
|
||||||
}
|
}
|
||||||
|
|
||||||
input UuidOperationFilterInput {
|
input UuidOperationFilterInput {
|
||||||
eq: UUID
|
eq: UUID @cost(weight: "10")
|
||||||
gt: UUID
|
neq: UUID @cost(weight: "10")
|
||||||
gte: UUID
|
in: [UUID] @cost(weight: "10")
|
||||||
in: [UUID]
|
nin: [UUID] @cost(weight: "10")
|
||||||
lt: UUID
|
gt: UUID @cost(weight: "10")
|
||||||
lte: UUID
|
ngt: UUID @cost(weight: "10")
|
||||||
neq: UUID
|
gte: UUID @cost(weight: "10")
|
||||||
ngt: UUID
|
ngte: UUID @cost(weight: "10")
|
||||||
ngte: UUID
|
lt: UUID @cost(weight: "10")
|
||||||
nin: [UUID]
|
nlt: UUID @cost(weight: "10")
|
||||||
nlt: UUID
|
lte: UUID @cost(weight: "10")
|
||||||
nlte: UUID
|
nlte: UUID @cost(weight: "10")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"Defines when a policy shall be executed."
|
||||||
|
enum ApplyPolicy {
|
||||||
|
"Before the resolver was executed."
|
||||||
|
BEFORE_RESOLVER
|
||||||
|
"After the resolver was executed."
|
||||||
|
AFTER_RESOLVER
|
||||||
|
"The policy is applied in the validation step before the execution."
|
||||||
|
VALIDATION
|
||||||
|
}
|
||||||
|
|
||||||
|
enum EntryType {
|
||||||
|
PLUGIN
|
||||||
|
PROFILE
|
||||||
|
LAYOUT
|
||||||
|
}
|
||||||
|
|
||||||
|
enum KeyboardLayoutType {
|
||||||
|
UNKNOWN
|
||||||
|
ANSI
|
||||||
|
ISO
|
||||||
|
JIS
|
||||||
|
ABNT
|
||||||
|
KS
|
||||||
|
}
|
||||||
|
|
||||||
|
enum RGBDeviceType {
|
||||||
|
NONE
|
||||||
|
KEYBOARD
|
||||||
|
MOUSE
|
||||||
|
HEADSET
|
||||||
|
MOUSEPAD
|
||||||
|
LED_STRIPE
|
||||||
|
LED_MATRIX
|
||||||
|
MAINBOARD
|
||||||
|
GRAPHICS_CARD
|
||||||
|
DRAM
|
||||||
|
HEADSET_STAND
|
||||||
|
KEYPAD
|
||||||
|
FAN
|
||||||
|
SPEAKER
|
||||||
|
COOLER
|
||||||
|
MONITOR
|
||||||
|
LED_CONTROLLER
|
||||||
|
GAME_CONTROLLER
|
||||||
|
UNKNOWN
|
||||||
|
ALL
|
||||||
|
}
|
||||||
|
|
||||||
|
enum SortEnumType {
|
||||||
|
ASC
|
||||||
|
DESC
|
||||||
|
}
|
||||||
|
|
||||||
|
"The authorize directive."
|
||||||
|
directive @authorize("The name of the authorization policy that determines access to the annotated resource." policy: String "Roles that are allowed to access the annotated resource." roles: [String!] "Defines when when the authorize directive shall be applied.By default the authorize directives are applied during the validation phase." apply: ApplyPolicy! = BEFORE_RESOLVER) repeatable on OBJECT | FIELD_DEFINITION
|
||||||
|
|
||||||
|
"The purpose of the `cost` directive is to define a `weight` for GraphQL types, fields, and arguments. Static analysis can use these weights when calculating the overall cost of a query or response."
|
||||||
|
directive @cost("The `weight` argument defines what value to add to the overall cost for every appearance, or possible appearance, of a type, field, argument, etc." weight: String!) on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM | INPUT_FIELD_DEFINITION
|
||||||
|
|
||||||
|
"The purpose of the `@listSize` directive is to either inform the static analysis about the size of returned lists (if that information is statically available), or to point the analysis to where to find that information."
|
||||||
|
directive @listSize("The `assumedSize` argument can be used to statically define the maximum length of a list returned by a field." assumedSize: Int "The `slicingArguments` argument can be used to define which of the field's arguments with numeric type are slicing arguments, so that their value determines the size of the list returned by that field. It may specify a list of multiple slicing arguments." slicingArguments: [String!] "The `slicingArgumentDefaultValue` argument can be used to define a default value for a slicing argument, which is used if the argument is not present in a query." slicingArgumentDefaultValue: Int "The `sizedFields` argument can be used to define that the value of the `assumedSize` argument or of a slicing argument does not affect the size of a list returned by a field itself, but that of a list returned by one of its sub-fields." sizedFields: [String!] "The `requireOneSlicingArgument` argument can be used to inform the static analysis that it should expect that exactly one of the defined slicing arguments is present in a query. If that is not the case (i.e., if none or multiple slicing arguments are present), the static analysis may throw an error." requireOneSlicingArgument: Boolean! = true) on FIELD_DEFINITION
|
||||||
|
|
||||||
|
"The `@specifiedBy` directive is used within the type system definition language to provide a URL for specifying the behavior of custom scalar definitions."
|
||||||
|
directive @specifiedBy("The specifiedBy URL points to a human-readable specification. This field will only read a result for scalar types." url: String!) on SCALAR
|
||||||
|
|
||||||
|
"The `DateTime` scalar represents an ISO-8601 compliant date time type."
|
||||||
|
scalar DateTime @specifiedBy(url: "https:\/\/www.graphql-scalars.com\/date-time")
|
||||||
|
|
||||||
|
"The `Long` scalar type represents non-fractional signed whole 64-bit numeric values. Long can represent values between -(2^63) and 2^63 - 1."
|
||||||
|
scalar Long
|
||||||
|
|
||||||
|
scalar UUID @specifiedBy(url: "https:\/\/tools.ietf.org\/html\/rfc4122")
|
||||||
@ -27,6 +27,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
|||||||
Artemis.sln.DotSettings.user = Artemis.sln.DotSettings.user
|
Artemis.sln.DotSettings.user = Artemis.sln.DotSettings.user
|
||||||
Directory.Packages.props = Directory.Packages.props
|
Directory.Packages.props = Directory.Packages.props
|
||||||
Directory.Build.props = Directory.Build.props
|
Directory.Build.props = Directory.Build.props
|
||||||
|
Directory.Build.targets = Directory.Build.targets
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Artemis.Storage.Legacy", "Artemis.Storage.Legacy\Artemis.Storage.Legacy.csproj", "{D7B0966D-774A-40E4-9455-00C1261ACB6A}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Artemis.Storage.Legacy", "Artemis.Storage.Legacy\Artemis.Storage.Legacy.csproj", "{D7B0966D-774A-40E4-9455-00C1261ACB6A}"
|
||||||
|
|||||||
12
src/Directory.Build.targets
Normal file
12
src/Directory.Build.targets
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<Project>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
|
||||||
|
<!-- If you're a .vbproj user, replace ';' with ',' -->
|
||||||
|
<DefineConstants>$(DefineConstants);ENABLE_XAML_HOT_RELOAD</DefineConstants>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Condition="$(DefineConstants.Contains(ENABLE_XAML_HOT_RELOAD))" Include="Avalonia.Markup.Xaml.Loader" />
|
||||||
|
<PackageReference Condition="$(DefineConstants.Contains(ENABLE_XAML_HOT_RELOAD))" Include="HotAvalonia" />
|
||||||
|
<PackageReference Include="HotAvalonia.Extensions" PrivateAssets="All" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
@ -66,5 +66,9 @@
|
|||||||
<PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="8.11.0" />
|
<PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="8.11.0" />
|
||||||
<PackageVersion Include="System.Text.Json" Version="9.0.5" />
|
<PackageVersion Include="System.Text.Json" Version="9.0.5" />
|
||||||
<PackageVersion Include="TextMateSharp.Grammars" Version="1.0.68" />
|
<PackageVersion Include="TextMateSharp.Grammars" Version="1.0.68" />
|
||||||
|
|
||||||
|
<PackageVersion Include="Avalonia.Markup.Xaml.Loader" Version="11.3.0" />
|
||||||
|
<PackageVersion Include="HotAvalonia" Version="2.1.0" />
|
||||||
|
<PackageVersion Include="HotAvalonia.Extensions" Version="2.1.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
Loading…
x
Reference in New Issue
Block a user