diff --git a/src/Artemis.Core/Constants.cs b/src/Artemis.Core/Constants.cs index 6ad386c9f..5699dbac4 100644 --- a/src/Artemis.Core/Constants.cs +++ b/src/Artemis.Core/Constants.cs @@ -40,7 +40,11 @@ public static class Constants /// /// The full path to the Artemis data folder /// +#if DEBUG public static readonly string DataFolder = Path.Combine(BaseFolder, "Artemis-dev"); +#else + public static readonly string DataFolder = Path.Combine(BaseFolder, "Artemis"); +#endif /// /// The full path to the Artemis logs folder diff --git a/src/Artemis.UI/Screens/Plugins/PluginViewModel.cs b/src/Artemis.UI/Screens/Plugins/PluginViewModel.cs index ae312a2be..c29963248 100644 --- a/src/Artemis.UI/Screens/Plugins/PluginViewModel.cs +++ b/src/Artemis.UI/Screens/Plugins/PluginViewModel.cs @@ -119,7 +119,7 @@ public partial class PluginViewModel : ActivatableViewModelBase Enabling = true; if (Plugin.Info.RequiresAdmin && !_coreService.IsElevated) { - bool confirmed = await _windowService.ShowConfirmContentDialog("Enable plugin", "This plugin requires admin rights, are you sure you want to enable it?"); + bool confirmed = await _windowService.ShowConfirmContentDialog("Enable plugin", "This plugin requires admin rights, are you sure you want to enable it? Artemis will need to restart.", "Confirm and restart"); if (!confirmed) return; } diff --git a/src/Artemis.UI/Screens/StartupWizard/Steps/DefaultEntriesStepView.axaml b/src/Artemis.UI/Screens/StartupWizard/Steps/DefaultEntriesStepView.axaml index 877ff9849..f474cfe5b 100644 --- a/src/Artemis.UI/Screens/StartupWizard/Steps/DefaultEntriesStepView.axaml +++ b/src/Artemis.UI/Screens/StartupWizard/Steps/DefaultEntriesStepView.axaml @@ -62,7 +62,6 @@ Currently installing: diff --git a/src/Artemis.UI/Screens/StartupWizard/Steps/DefaultEntriesStepViewModel.cs b/src/Artemis.UI/Screens/StartupWizard/Steps/DefaultEntriesStepViewModel.cs index 7a8c60467..5b631e1f9 100644 --- a/src/Artemis.UI/Screens/StartupWizard/Steps/DefaultEntriesStepViewModel.cs +++ b/src/Artemis.UI/Screens/StartupWizard/Steps/DefaultEntriesStepViewModel.cs @@ -41,7 +41,7 @@ public partial class DefaultEntriesStepViewModel : WizardStepViewModel _client = client; _getDefaultEntryItemViewModel = getDefaultEntryItemViewModel; _remainingEntries = this.WhenAnyValue(vm => vm.InstalledEntries, vm => vm.TotalEntries) - .Select(t => t.Item2 - t.Item1) + .Select(t => t.Item2 - t.Item1 + 1) .ToProperty(this, vm => vm.RemainingEntries); ContinueText = "Install selected entries"; diff --git a/src/Artemis.UI/Screens/StartupWizard/Steps/DefaultEntryItemViewModel.cs b/src/Artemis.UI/Screens/StartupWizard/Steps/DefaultEntryItemViewModel.cs index a96f28bd1..a93e8512c 100644 --- a/src/Artemis.UI/Screens/StartupWizard/Steps/DefaultEntryItemViewModel.cs +++ b/src/Artemis.UI/Screens/StartupWizard/Steps/DefaultEntryItemViewModel.cs @@ -31,7 +31,6 @@ public partial class DefaultEntryItemViewModel : ActivatableViewModelBase [Notify] private bool _isInstalled; [Notify] private bool _shouldInstall; - [Notify] private bool _enabling; [Notify] private float _installProgress; public DefaultEntryItemViewModel(ILogger logger, IEntrySummary entry, IWorkshopService workshopService, IWindowService windowService, IPluginManagementService pluginManagementService, @@ -70,9 +69,7 @@ public partial class DefaultEntryItemViewModel : ActivatableViewModelBase // If the entry is a plugin, enable the plugin and all features else if (result.Entry?.EntryType == EntryType.Plugin) { - Enabling = true; await EnablePluginAndFeatures(result.Entry); - Enabling = false; } return result.IsSuccess; diff --git a/src/Artemis.UI/Screens/Workshop/Categories/CategoriesViewModel.cs b/src/Artemis.UI/Screens/Workshop/Categories/CategoriesViewModel.cs index 74d0f629e..40f68116f 100644 --- a/src/Artemis.UI/Screens/Workshop/Categories/CategoriesViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/Categories/CategoriesViewModel.cs @@ -18,10 +18,10 @@ public class CategoriesViewModel : ActivatableViewModelBase { private ObservableAsPropertyHelper?>? _categoryFilters; - public CategoriesViewModel(IWorkshopClient client) + public CategoriesViewModel(EntryType entryType, IWorkshopClient client) { client.GetCategories - .Watch(ExecutionStrategy.CacheFirst) + .Watch(entryType, ExecutionStrategy.CacheFirst) .SelectOperationResult(c => c.Categories) .ToObservableChangeSet(c => c.Id) .Transform(c => new CategoryViewModel(c)) diff --git a/src/Artemis.UI/Screens/Workshop/Entries/Details/EntrySpecificationsViewModel.cs b/src/Artemis.UI/Screens/Workshop/Entries/Details/EntrySpecificationsViewModel.cs index d2cdd265f..aee4bb5b9 100644 --- a/src/Artemis.UI/Screens/Workshop/Entries/Details/EntrySpecificationsViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/Entries/Details/EntrySpecificationsViewModel.cs @@ -88,6 +88,7 @@ public partial class EntrySpecificationsViewModel : ValidatableViewModelBase public bool IsAdministrator { get; } public List PreselectedCategories { get; set; } = new(); + public EntryType EntryType { get; set; } private async Task ExecuteSelectIcon() { @@ -114,7 +115,7 @@ public partial class EntrySpecificationsViewModel : ValidatableViewModelBase private async Task PopulateCategories() { - IOperationResult categories = await _workshopClient.GetCategories.ExecuteAsync(); + IOperationResult categories = await _workshopClient.GetCategories.ExecuteAsync(EntryType); Categories.Clear(); if (categories.Data != null) Categories.AddRange(categories.Data.Categories.Select(c => new CategoryViewModel(c) {IsSelected = PreselectedCategories.Contains(c.Id)})); diff --git a/src/Artemis.UI/Screens/Workshop/Entries/List/EntryListView.axaml b/src/Artemis.UI/Screens/Workshop/Entries/List/EntryListView.axaml index fdbebe7ca..c8b0051c7 100644 --- a/src/Artemis.UI/Screens/Workshop/Entries/List/EntryListView.axaml +++ b/src/Artemis.UI/Screens/Workshop/Entries/List/EntryListView.axaml @@ -22,6 +22,7 @@ Categories - - - - Default entries - - - Categories - - + + + Include default entries + + diff --git a/src/Artemis.UI/Screens/Workshop/Entries/List/EntryListViewModel.cs b/src/Artemis.UI/Screens/Workshop/Entries/List/EntryListViewModel.cs index cf7f7f816..fd29fcd46 100644 --- a/src/Artemis.UI/Screens/Workshop/Entries/List/EntryListViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/Entries/List/EntryListViewModel.cs @@ -25,7 +25,7 @@ public partial class EntryListViewModel : RoutableScreen private readonly SourceList _entries = new(); private readonly INotificationService _notificationService; private readonly IWorkshopClient _workshopClient; - private IGetEntriesv2_EntriesV2_PageInfo? _currentPageInfo; + private IGetEntries_EntriesV2_PageInfo? _currentPageInfo; [Notify] private bool _initializing = true; [Notify] private bool _fetchingMore; @@ -33,18 +33,20 @@ public partial class EntryListViewModel : RoutableScreen [Notify] private bool _includeDefaultEntries; [Notify] private Vector _scrollOffset; - protected EntryListViewModel(IWorkshopClient workshopClient, - CategoriesViewModel categoriesViewModel, + protected EntryListViewModel(EntryType entryType, + IWorkshopClient workshopClient, EntryListInputViewModel entryListInputViewModel, INotificationService notificationService, + Func getCategoriesViewModel, Func getEntryListViewModel) { _workshopClient = workshopClient; _notificationService = notificationService; - CategoriesViewModel = categoriesViewModel; + CategoriesViewModel = getCategoriesViewModel(entryType); InputViewModel = entryListInputViewModel; - + EntryType = entryType; + _entries.Connect() .Transform(getEntryListViewModel) .Bind(out ReadOnlyObservableCollection entries) @@ -75,7 +77,7 @@ public partial class EntryListViewModel : RoutableScreen public CategoriesViewModel CategoriesViewModel { get; } public EntryListInputViewModel InputViewModel { get; } public bool ShowCategoryFilter { get; set; } = true; - public EntryType? EntryType { get; set; } + public EntryType EntryType { get; } public ReadOnlyObservableCollection Entries { get; } @@ -93,7 +95,7 @@ public partial class EntryListViewModel : RoutableScreen try { - IOperationResult entries = await _workshopClient.GetEntriesv2.ExecuteAsync(search, filter, sort, entriesPerFetch, _currentPageInfo?.EndCursor, cancellationToken); + IOperationResult entries = await _workshopClient.GetEntries.ExecuteAsync(search, IncludeDefaultEntries, filter, sort, entriesPerFetch, _currentPageInfo?.EndCursor, cancellationToken); entries.EnsureNoErrors(); _currentPageInfo = entries.Data?.EntriesV2?.PageInfo; @@ -124,7 +126,6 @@ public partial class EntryListViewModel : RoutableScreen And = [ new EntryFilterInput {EntryType = new EntryTypeOperationFilterInput {Eq = EntryType}}, - new EntryFilterInput {DefaultEntryInfo = IncludeDefaultEntries ? new DefaultEntryInfoFilterInput {EntryId = new LongOperationFilterInput {Ngt = 0}} : null}, ..CategoriesViewModel.CategoryFilters ?? [] ] }; diff --git a/src/Artemis.UI/Screens/Workshop/Home/WorkshopHomeViewModel.cs b/src/Artemis.UI/Screens/Workshop/Home/WorkshopHomeViewModel.cs index 3ab39b11b..4dee0a822 100644 --- a/src/Artemis.UI/Screens/Workshop/Home/WorkshopHomeViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/Home/WorkshopHomeViewModel.cs @@ -51,7 +51,7 @@ public partial class WorkshopHomeViewModel : RoutableScreen p.AddRange(popularResult.Data.PopularEntries.Take(8)); }); - IOperationResult latestResult = await client.GetEntriesv2.ExecuteAsync(null, null, [new EntrySortInput {CreatedAt = SortEnumType.Desc}], 8, null); + IOperationResult latestResult = await client.GetEntries.ExecuteAsync(null, null, null, [new EntrySortInput {CreatedAt = SortEnumType.Desc}], 8, null); latest.Edit(l => { l.Clear(); diff --git a/src/Artemis.UI/Screens/Workshop/Layout/LayoutListDefaultViewModel.cs b/src/Artemis.UI/Screens/Workshop/Layout/LayoutListDefaultViewModel.cs index b9521529c..c61eabef9 100644 --- a/src/Artemis.UI/Screens/Workshop/Layout/LayoutListDefaultViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/Layout/LayoutListDefaultViewModel.cs @@ -1,3 +1,4 @@ +using System; using Artemis.UI.Screens.Workshop.Entries.List; using Artemis.UI.Screens.Workshop.LayoutFinder; using Artemis.UI.Shared.Routing; @@ -7,11 +8,10 @@ namespace Artemis.UI.Screens.Workshop.Layout; public class LayoutListDefaultViewModel : RoutableScreen { - public LayoutListDefaultViewModel(LayoutFinderViewModel layoutFinderViewModel, EntryListViewModel entryListViewModel) + public LayoutListDefaultViewModel(LayoutFinderViewModel layoutFinderViewModel, Func getEntryListViewModel) { LayoutFinderViewModel = layoutFinderViewModel; - EntryListViewModel = entryListViewModel; - EntryListViewModel.EntryType = EntryType.Layout; + EntryListViewModel = getEntryListViewModel(EntryType.Layout); EntryListViewModel.ShowCategoryFilter = false; } diff --git a/src/Artemis.UI/Screens/Workshop/Library/SubmissionDetailsViewModel.cs b/src/Artemis.UI/Screens/Workshop/Library/SubmissionDetailsViewModel.cs index bcef82f2c..1c500fc7c 100644 --- a/src/Artemis.UI/Screens/Workshop/Library/SubmissionDetailsViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/Library/SubmissionDetailsViewModel.cs @@ -109,6 +109,7 @@ public partial class SubmissionDetailsViewModel : RoutableScreen specificationsViewModel.IsEssential = Entry.DefaultEntryInfo?.IsEssential ?? false; specificationsViewModel.IsDeviceProvider = Entry.DefaultEntryInfo?.IsDeviceProvider ?? false; specificationsViewModel.PreselectedCategories = Entry.Categories.Select(c => c.Id).ToList(); + specificationsViewModel.EntryType = Entry.EntryType; specificationsViewModel.Tags.Clear(); foreach (string tag in Entry.Tags.Select(c => c.Name)) diff --git a/src/Artemis.UI/Screens/Workshop/Plugins/PluginListViewModel.cs b/src/Artemis.UI/Screens/Workshop/Plugins/PluginListViewModel.cs index 7401c2659..422a67223 100644 --- a/src/Artemis.UI/Screens/Workshop/Plugins/PluginListViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/Plugins/PluginListViewModel.cs @@ -1,3 +1,4 @@ +using System; using Artemis.UI.Screens.Workshop.Entries.List; using Artemis.UI.Shared.Routing; using Artemis.WebClient.Workshop; @@ -9,9 +10,8 @@ public class PluginListViewModel : RoutableHostScreen private readonly EntryListViewModel _entryListViewModel; public override RoutableScreen DefaultScreen => _entryListViewModel; - public PluginListViewModel(EntryListViewModel entryListViewModel) + public PluginListViewModel(Func getEntryListViewModel) { - _entryListViewModel = entryListViewModel; - _entryListViewModel.EntryType = EntryType.Plugin; + _entryListViewModel = getEntryListViewModel(EntryType.Plugin); } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Workshop/Profile/ProfileListViewModel.cs b/src/Artemis.UI/Screens/Workshop/Profile/ProfileListViewModel.cs index 75faa19a1..d8b098761 100644 --- a/src/Artemis.UI/Screens/Workshop/Profile/ProfileListViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/Profile/ProfileListViewModel.cs @@ -1,3 +1,4 @@ +using System; using Artemis.UI.Screens.Workshop.Entries.List; using Artemis.UI.Shared.Routing; using Artemis.WebClient.Workshop; @@ -9,9 +10,8 @@ public class ProfileListViewModel : RoutableHostScreen private readonly EntryListViewModel _entryListViewModel; public override RoutableScreen DefaultScreen => _entryListViewModel; - public ProfileListViewModel(EntryListViewModel entryListViewModel) + public ProfileListViewModel(Func getEntryListViewModel) { - _entryListViewModel = entryListViewModel; - _entryListViewModel.EntryType = EntryType.Profile; + _entryListViewModel = getEntryListViewModel(EntryType.Profile); } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/SpecificationsStepViewModel.cs b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/SpecificationsStepViewModel.cs index 593b5255c..1b8c2a35c 100644 --- a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/SpecificationsStepViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/SpecificationsStepViewModel.cs @@ -75,6 +75,7 @@ public partial class SpecificationsStepViewModel : SubmissionViewModel // Categories viewModel.PreselectedCategories = State.Categories; + viewModel.EntryType = State.EntryType; // Icon if (State.Icon != null) diff --git a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/SubmitStepViewModel.cs b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/SubmitStepViewModel.cs index 5cbc4c1ef..111b9bb36 100644 --- a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/SubmitStepViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/SubmitStepViewModel.cs @@ -38,7 +38,7 @@ public partial class SubmitStepViewModel : SubmissionViewModel IconBitmap.DisposeWith(d); } - Observable.FromAsync(workshopClient.GetCategories.ExecuteAsync).Subscribe(PopulateCategories).DisposeWith(d); + Observable.FromAsync(() => workshopClient.GetCategories.ExecuteAsync(State.EntryType)).Subscribe(PopulateCategories).DisposeWith(d); }); } diff --git a/src/Artemis.WebClient.Workshop/Queries/GetCategories.graphql b/src/Artemis.WebClient.Workshop/Queries/GetCategories.graphql index 864caa217..1770bfcdc 100644 --- a/src/Artemis.WebClient.Workshop/Queries/GetCategories.graphql +++ b/src/Artemis.WebClient.Workshop/Queries/GetCategories.graphql @@ -1,5 +1,5 @@ -query GetCategories { - categories(order: {name: ASC}) { +query GetCategories($entryType: EntryType) { + categories(where: {entryType: {in: [$entryType, null]}} order: {name: ASC}) { id name icon diff --git a/src/Artemis.WebClient.Workshop/Queries/GetEntries.graphql b/src/Artemis.WebClient.Workshop/Queries/GetEntries.graphql index 782faa984..cdcda0581 100644 --- a/src/Artemis.WebClient.Workshop/Queries/GetEntries.graphql +++ b/src/Artemis.WebClient.Workshop/Queries/GetEntries.graphql @@ -1,5 +1,5 @@ -query GetEntriesv2($search: String $filter: EntryFilterInput $order: [EntrySortInput!] $first: Int $after: String) { - entriesV2(search: $search where: $filter order: $order first: $first after: $after) { +query GetEntries($search: String $includeDefaults: Boolean $filter: EntryFilterInput $order: [EntrySortInput!] $first: Int $after: String) { + entriesV2(search: $search includeDefaults: $includeDefaults where: $filter order: $order first: $first after: $after) { totalCount pageInfo { hasNextPage @@ -22,6 +22,7 @@ query GetPopularEntries { query GetDefaultEntries($first: Int, $after: String) { entriesV2( + includeDefaults: true where: { defaultEntryInfo: { entryId: { gt: 0 } } } first: $first after: $after diff --git a/src/Artemis.WebClient.Workshop/schema.graphql b/src/Artemis.WebClient.Workshop/schema.graphql index 3ca000dce..ebc1d6535 100644 --- a/src/Artemis.WebClient.Workshop/schema.graphql +++ b/src/Artemis.WebClient.Workshop/schema.graphql @@ -7,6 +7,7 @@ type Category { id: Long! name: String! icon: String! + entryType: EntryType } "Information about the offset pagination." @@ -166,7 +167,7 @@ type Query { skip: Int take: Int search: String - popular: Boolean + includeDefaults: Boolean order: [EntrySortInput!] @cost(weight: "10") where: EntryFilterInput @cost(weight: "10") ): EntriesCollectionSegment @@ -180,7 +181,7 @@ type Query { @cost(weight: "10") entriesV2( search: String - popular: Boolean + includeDefaults: Boolean "Returns the first _n_ elements from the list." first: Int "Returns the elements in the list that come after the specified cursor." @@ -273,12 +274,14 @@ input CategoryFilterInput { id: LongOperationFilterInput name: StringOperationFilterInput icon: StringOperationFilterInput + entryType: NullableOfEntryTypeOperationFilterInput } input CategorySortInput { id: SortEnumType @cost(weight: "10") name: SortEnumType @cost(weight: "10") icon: SortEnumType @cost(weight: "10") + entryType: SortEnumType @cost(weight: "10") } input CreateEntryInput { @@ -509,6 +512,13 @@ input LongOperationFilterInput { nlte: Long @cost(weight: "10") } +input NullableOfEntryTypeOperationFilterInput { + eq: EntryType @cost(weight: "10") + neq: EntryType @cost(weight: "10") + in: [EntryType] @cost(weight: "10") + nin: [EntryType] @cost(weight: "10") +} + input NullableOfKeyboardLayoutTypeOperationFilterInput { eq: KeyboardLayoutType @cost(weight: "10") neq: KeyboardLayoutType @cost(weight: "10")