diff --git a/src/Artemis.UI/Artemis.UI.csproj b/src/Artemis.UI/Artemis.UI.csproj
index d7bd7aafc..7408b305b 100644
--- a/src/Artemis.UI/Artemis.UI.csproj
+++ b/src/Artemis.UI/Artemis.UI.csproj
@@ -44,5 +44,22 @@
DeviceSelectionDialogView.axaml
Code
+
+ LayoutListView.axaml
+ Code
+
+
+ LayoutListView.axaml
+ Code
+
+
+ LayoutListView.axaml
+ Code
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Artemis.UI/Routing/Routes.cs b/src/Artemis.UI/Routing/Routes.cs
index 8973793b0..09a677350 100644
--- a/src/Artemis.UI/Routing/Routes.cs
+++ b/src/Artemis.UI/Routing/Routes.cs
@@ -7,11 +7,11 @@ using Artemis.UI.Screens.Settings.Updating;
using Artemis.UI.Screens.SurfaceEditor;
using Artemis.UI.Screens.Workshop;
using Artemis.UI.Screens.Workshop.Entries;
-using Artemis.UI.Screens.Workshop.Entries.Tabs;
using Artemis.UI.Screens.Workshop.Home;
using Artemis.UI.Screens.Workshop.Layout;
using Artemis.UI.Screens.Workshop.Library;
using Artemis.UI.Screens.Workshop.Library.Tabs;
+using Artemis.UI.Screens.Workshop.Plugins;
using Artemis.UI.Screens.Workshop.Profile;
using Artemis.UI.Shared.Routing;
using PluginDetailsViewModel = Artemis.UI.Screens.Workshop.Plugins.PluginDetailsViewModel;
diff --git a/src/Artemis.UI/Screens/Root/RootView.axaml.cs b/src/Artemis.UI/Screens/Root/RootView.axaml.cs
index 04acf1892..90cd6afb8 100644
--- a/src/Artemis.UI/Screens/Root/RootView.axaml.cs
+++ b/src/Artemis.UI/Screens/Root/RootView.axaml.cs
@@ -19,7 +19,7 @@ public partial class RootView : ReactiveUserControl
{
try
{
- Dispatcher.UIThread.Invoke(() => RootFrame.NavigateFromObject(viewModel));
+ RootFrame.NavigateFromObject(viewModel);
}
catch (Exception)
{
diff --git a/src/Artemis.UI/Screens/Settings/SettingsView.axaml.cs b/src/Artemis.UI/Screens/Settings/SettingsView.axaml.cs
index 6e04c8c28..cb03c7a44 100644
--- a/src/Artemis.UI/Screens/Settings/SettingsView.axaml.cs
+++ b/src/Artemis.UI/Screens/Settings/SettingsView.axaml.cs
@@ -18,7 +18,7 @@ public partial class SettingsView : ReactiveUserControl
private void Navigate(ViewModelBase viewModel)
{
- Dispatcher.UIThread.Invoke(() => TabFrame.NavigateFromObject(viewModel));
+ TabFrame.NavigateFromObject(viewModel);
}
private void NavigationView_OnBackRequested(object? sender, NavigationViewBackRequestedEventArgs e)
diff --git a/src/Artemis.UI/Screens/Settings/Tabs/ReleasesTabView.axaml.cs b/src/Artemis.UI/Screens/Settings/Tabs/ReleasesTabView.axaml.cs
index cebc6f402..aadd8b4a6 100644
--- a/src/Artemis.UI/Screens/Settings/Tabs/ReleasesTabView.axaml.cs
+++ b/src/Artemis.UI/Screens/Settings/Tabs/ReleasesTabView.axaml.cs
@@ -17,17 +17,13 @@ public partial class ReleasesTabView : ReactiveUserControl
private void Navigate(ViewModelBase viewModel)
{
- Dispatcher.UIThread.Invoke(() =>
+ try
{
- try
- {
- ReleaseFrame.NavigateFromObject(viewModel);
- }
- catch (Exception)
- {
- // ignored
- }
- });
+ ReleaseFrame.NavigateFromObject(viewModel);
+ }
+ catch (Exception)
+ {
+ // ignored
+ }
}
-
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryInfoViewModel.cs b/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryInfoViewModel.cs
index d5c4de433..cd37606ea 100644
--- a/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryInfoViewModel.cs
+++ b/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryInfoViewModel.cs
@@ -1,4 +1,5 @@
using System;
+using System.Linq;
using System.Threading.Tasks;
using Artemis.Core;
using Artemis.UI.Shared;
@@ -12,12 +13,12 @@ public class EntryInfoViewModel : ViewModelBase
private readonly INotificationService _notificationService;
public IEntryDetails Entry { get; }
public DateTimeOffset? UpdatedAt { get; }
-
+
public EntryInfoViewModel(IEntryDetails entry, INotificationService notificationService)
{
_notificationService = notificationService;
Entry = entry;
- UpdatedAt = Entry.LatestRelease?.CreatedAt ?? Entry.CreatedAt;
+ UpdatedAt = Entry.Releases.Any() ? Entry.Releases.Max(r => r.CreatedAt) : Entry.CreatedAt;
}
public async Task CopyShareLink()
diff --git a/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryReleasesView.axaml b/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryReleasesView.axaml
index 78944e621..5453ac531 100644
--- a/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryReleasesView.axaml
+++ b/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryReleasesView.axaml
@@ -6,6 +6,7 @@
xmlns:converters="clr-namespace:Artemis.UI.Converters"
xmlns:sharedConverters="clr-namespace:Artemis.UI.Shared.Converters;assembly=Artemis.UI.Shared"
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
+ xmlns:workshop="clr-namespace:Artemis.WebClient.Workshop;assembly=Artemis.WebClient.Workshop"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.Workshop.Entries.Details.EntryReleasesView"
x:DataType="details:EntryReleasesViewModel">
@@ -14,39 +15,74 @@
- Latest release
+ Releases
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryReleasesViewModel.cs b/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryReleasesViewModel.cs
index 12bd22b3a..8d35a9f38 100644
--- a/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryReleasesViewModel.cs
+++ b/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryReleasesViewModel.cs
@@ -1,8 +1,11 @@
using System;
+using System.Collections.Generic;
+using System.Linq;
using System.Reactive;
using System.Threading;
using System.Threading.Tasks;
using Artemis.UI.Shared;
+using Artemis.UI.Shared.Routing;
using Artemis.UI.Shared.Services;
using Artemis.UI.Shared.Services.Builders;
using Artemis.UI.Shared.Utilities;
@@ -19,34 +22,49 @@ public class EntryReleasesViewModel : ViewModelBase
private readonly EntryInstallationHandlerFactory _factory;
private readonly IWindowService _windowService;
private readonly INotificationService _notificationService;
+ private readonly IRouter _router;
- public EntryReleasesViewModel(IEntryDetails entry, EntryInstallationHandlerFactory factory, IWindowService windowService, INotificationService notificationService)
+ public EntryReleasesViewModel(IEntryDetails entry, EntryInstallationHandlerFactory factory, IWindowService windowService, INotificationService notificationService, IRouter router)
{
_factory = factory;
_windowService = windowService;
_notificationService = notificationService;
+ _router = router;
Entry = entry;
+ LatestRelease = Entry.Releases.MaxBy(r => r.CreatedAt);
+ OtherReleases = Entry.Releases.OrderByDescending(r => r.CreatedAt).Skip(1).Take(4).Cast().ToList();
+
DownloadLatestRelease = ReactiveCommand.CreateFromTask(ExecuteDownloadLatestRelease);
OnInstallationStarted = Confirm;
+ NavigateToRelease = ReactiveCommand.CreateFromTask(ExecuteNavigateToRelease);
}
public IEntryDetails Entry { get; }
- public ReactiveCommand DownloadLatestRelease { get; }
+ public IRelease? LatestRelease { get; }
+ public List OtherReleases { get; }
- public Func> OnInstallationStarted { get; set; }
+ public ReactiveCommand DownloadLatestRelease { get; }
+ public ReactiveCommand NavigateToRelease { get; }
+
+ public Func> OnInstallationStarted { get; set; }
public Func? OnInstallationFinished { get; set; }
+ private async Task ExecuteNavigateToRelease(IRelease release)
+ {
+ await _router.Navigate($"workshop/entries/{Entry.Id}/releases/{release.Id}");
+ }
+
private async Task ExecuteDownloadLatestRelease(CancellationToken cancellationToken)
{
- if (Entry.LatestRelease == null)
+ if (LatestRelease == null)
return;
-
- if (await OnInstallationStarted(Entry))
+
+ if (await OnInstallationStarted(Entry, LatestRelease))
return;
IEntryInstallationHandler installationHandler = _factory.CreateHandler(Entry.EntryType);
- EntryInstallResult result = await installationHandler.InstallAsync(Entry, Entry.LatestRelease, new Progress(), cancellationToken);
+ EntryInstallResult result = await installationHandler.InstallAsync(Entry, LatestRelease, new Progress(), cancellationToken);
if (result.IsSuccess && result.Entry != null)
{
if (OnInstallationFinished != null)
@@ -62,13 +80,13 @@ public class EntryReleasesViewModel : ViewModelBase
}
}
- private async Task Confirm(IEntryDetails entryDetails)
+ private async Task Confirm(IEntryDetails entryDetails, IRelease release)
{
bool confirm = await _windowService.ShowConfirmContentDialog(
"Install latest release",
- $"Are you sure you want to download and install version {entryDetails.LatestRelease?.Version} of {entryDetails.Name}?"
+ $"Are you sure you want to download and install version {release.Version} of {entryDetails.Name}?"
);
-
+
return !confirm;
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Workshop/Entries/EntriesView.axaml.cs b/src/Artemis.UI/Screens/Workshop/Entries/EntriesView.axaml.cs
index 3f2106645..1299973d2 100644
--- a/src/Artemis.UI/Screens/Workshop/Entries/EntriesView.axaml.cs
+++ b/src/Artemis.UI/Screens/Workshop/Entries/EntriesView.axaml.cs
@@ -18,7 +18,7 @@ public partial class EntriesView : ReactiveUserControl
private void Navigate(ViewModelBase viewModel)
{
- Dispatcher.UIThread.Invoke(() => TabFrame.NavigateFromObject(viewModel));
+ TabFrame.NavigateFromObject(viewModel);
}
private void NavigationView_OnBackRequested(object? sender, NavigationViewBackRequestedEventArgs e)
diff --git a/src/Artemis.UI/Screens/Workshop/Entries/EntriesViewModel.cs b/src/Artemis.UI/Screens/Workshop/Entries/EntriesViewModel.cs
index e76014c34..760193832 100644
--- a/src/Artemis.UI/Screens/Workshop/Entries/EntriesViewModel.cs
+++ b/src/Artemis.UI/Screens/Workshop/Entries/EntriesViewModel.cs
@@ -53,8 +53,8 @@ public partial class EntriesViewModel : RoutableHostScreen
public void GoBack()
{
- if (ViewingDetails)
- _router.GoBack();
+ if (ViewingDetails && SelectedTab != null)
+ _router.Navigate(SelectedTab.Path);
else
_router.Navigate("workshop");
}
diff --git a/src/Artemis.UI/Screens/Workshop/Entries/List/EntryListView.axaml b/src/Artemis.UI/Screens/Workshop/Entries/List/EntryListView.axaml
new file mode 100644
index 000000000..597282d98
--- /dev/null
+++ b/src/Artemis.UI/Screens/Workshop/Entries/List/EntryListView.axaml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+ Categories
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Looks like your current filters gave no results
+
+ Modify or clear your filters to view other entries
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Workshop/Entries/Tabs/LayoutListView.axaml.cs b/src/Artemis.UI/Screens/Workshop/Entries/List/EntryListView.axaml.cs
similarity index 51%
rename from src/Artemis.UI/Screens/Workshop/Entries/Tabs/LayoutListView.axaml.cs
rename to src/Artemis.UI/Screens/Workshop/Entries/List/EntryListView.axaml.cs
index a003f47bb..e4a15ed77 100644
--- a/src/Artemis.UI/Screens/Workshop/Entries/Tabs/LayoutListView.axaml.cs
+++ b/src/Artemis.UI/Screens/Workshop/Entries/List/EntryListView.axaml.cs
@@ -1,38 +1,30 @@
-using System;
-using System.Reactive.Disposables;
using System.Threading;
-using Artemis.UI.Shared.Routing;
using Avalonia.Controls;
using Avalonia.ReactiveUI;
-using Avalonia.Threading;
using ReactiveUI;
-namespace Artemis.UI.Screens.Workshop.Entries.Tabs;
+namespace Artemis.UI.Screens.Workshop.Entries.List;
-public partial class LayoutListView : ReactiveUserControl
+public partial class EntryListView : ReactiveUserControl
{
- public LayoutListView()
+ public EntryListView()
{
InitializeComponent();
EntriesScrollViewer.SizeChanged += (_, _) => UpdateEntriesPerFetch();
-
- this.WhenActivated(d =>
- {
- UpdateEntriesPerFetch();
- ViewModel.WhenAnyValue(vm => vm.Screen).WhereNotNull().Subscribe(Navigate).DisposeWith(d);
- });
+
+ this.WhenActivated(_ => UpdateEntriesPerFetch());
}
private void ScrollViewer_OnScrollChanged(object? sender, ScrollChangedEventArgs e)
{
+ if (ViewModel == null)
+ return;
+
// When near the bottom of EntriesScrollViewer, call FetchMore on the view model
if (EntriesScrollViewer.Offset.Y != 0 && EntriesScrollViewer.Extent.Height - (EntriesScrollViewer.Viewport.Height + EntriesScrollViewer.Offset.Y) < 100)
- ViewModel?.FetchMore(CancellationToken.None);
- }
+ ViewModel.FetchMore(CancellationToken.None);
- private void Navigate(RoutableScreen viewModel)
- {
- Dispatcher.UIThread.Invoke(() => RouterFrame.NavigateFromObject(viewModel), DispatcherPriority.ApplicationIdle);
+ ViewModel.ScrollOffset = EntriesScrollViewer.Offset;
}
private void UpdateEntriesPerFetch()
diff --git a/src/Artemis.UI/Screens/Workshop/Entries/List/EntryListViewModel.cs b/src/Artemis.UI/Screens/Workshop/Entries/List/EntryListViewModel.cs
index 92322920d..f335c9128 100644
--- a/src/Artemis.UI/Screens/Workshop/Entries/List/EntryListViewModel.cs
+++ b/src/Artemis.UI/Screens/Workshop/Entries/List/EntryListViewModel.cs
@@ -6,6 +6,7 @@ using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Threading;
using System.Threading.Tasks;
+using Artemis.UI.Extensions;
using Artemis.UI.Screens.Workshop.Categories;
using Artemis.UI.Shared.Routing;
using Artemis.UI.Shared.Services;
@@ -15,29 +16,28 @@ using DynamicData;
using PropertyChanged.SourceGenerator;
using ReactiveUI;
using StrawberryShake;
+using Vector = Avalonia.Vector;
namespace Artemis.UI.Screens.Workshop.Entries.List;
-public abstract partial class EntryListViewModel : RoutableHostScreen
+public partial class EntryListViewModel : RoutableScreen
{
private readonly SourceList _entries = new();
private readonly INotificationService _notificationService;
private readonly IWorkshopClient _workshopClient;
- private readonly string _route;
private IGetEntriesv2_EntriesV2_PageInfo? _currentPageInfo;
[Notify] private bool _initializing = true;
[Notify] private bool _fetchingMore;
[Notify] private int _entriesPerFetch;
+ [Notify] private Vector _scrollOffset;
- protected EntryListViewModel(string route,
- IWorkshopClient workshopClient,
+ protected EntryListViewModel(IWorkshopClient workshopClient,
CategoriesViewModel categoriesViewModel,
EntryListInputViewModel entryListInputViewModel,
INotificationService notificationService,
Func getEntryListViewModel)
{
- _route = route;
_workshopClient = workshopClient;
_notificationService = notificationService;
@@ -50,37 +50,31 @@ public abstract partial class EntryListViewModel : RoutableHostScreen
{
- // Respond to filter query input changes
InputViewModel.WhenAnyValue(vm => vm.Search).Skip(1).Throttle(TimeSpan.FromMilliseconds(200)).Subscribe(_ => Reset()).DisposeWith(d);
CategoriesViewModel.WhenAnyValue(vm => vm.CategoryFilters).Skip(1).Subscribe(_ => Reset()).DisposeWith(d);
});
+
+ // Load entries when the view model is first activated
+ this.WhenActivatedAsync(async _ =>
+ {
+ if (_entries.Count == 0)
+ {
+ await Task.Delay(250);
+ await FetchMore(CancellationToken.None);
+ Initializing = false;
+ }
+ });
}
public CategoriesViewModel CategoriesViewModel { get; }
public EntryListInputViewModel InputViewModel { get; }
+ public EntryType? EntryType { get; set; }
public ReadOnlyObservableCollection Entries { get; }
-
- public override async Task OnNavigating(NavigationArguments args, CancellationToken cancellationToken)
- {
- if (_entries.Count == 0)
- {
- await Task.Delay(250, cancellationToken);
- await FetchMore(cancellationToken);
- Initializing = false;
- }
- }
-
- public override Task OnClosing(NavigationArguments args)
- {
- // Clear search if not navigating to a child
- if (!args.Path.StartsWith(_route))
- InputViewModel.ClearLastSearch();
- return base.OnClosing(args);
- }
-
+
public async Task FetchMore(CancellationToken cancellationToken)
{
if (FetchingMore || _currentPageInfo != null && !_currentPageInfo.HasNextPage)
@@ -119,12 +113,19 @@ public abstract partial class EntryListViewModel : RoutableHostScreen GetSort()
+ private IReadOnlyList GetSort()
{
// Sort by created at
if (InputViewModel.SortBy == 1)
diff --git a/src/Artemis.UI/Screens/Workshop/Entries/Tabs/LayoutListView.axaml b/src/Artemis.UI/Screens/Workshop/Entries/Tabs/LayoutListView.axaml
deleted file mode 100644
index 1c0c4182c..000000000
--- a/src/Artemis.UI/Screens/Workshop/Entries/Tabs/LayoutListView.axaml
+++ /dev/null
@@ -1,67 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- Categories
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Looks like your current filters gave no results
-
- Modify or clear your filters to view other device layouts
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Workshop/Entries/Tabs/LayoutListViewModel.cs b/src/Artemis.UI/Screens/Workshop/Entries/Tabs/LayoutListViewModel.cs
deleted file mode 100644
index 11c97846c..000000000
--- a/src/Artemis.UI/Screens/Workshop/Entries/Tabs/LayoutListViewModel.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-using System;
-using Artemis.UI.Screens.Workshop.Categories;
-using Artemis.UI.Screens.Workshop.Entries.List;
-using Artemis.UI.Shared.Routing;
-using Artemis.UI.Shared.Services;
-using Artemis.WebClient.Workshop;
-
-namespace Artemis.UI.Screens.Workshop.Entries.Tabs;
-
-public class LayoutListViewModel : List.EntryListViewModel
-{
- public LayoutListViewModel(IWorkshopClient workshopClient,
- CategoriesViewModel categoriesViewModel,
- EntryListInputViewModel entryListInputViewModel,
- INotificationService notificationService,
- Func getEntryListViewModel)
- : base("workshop/entries/layouts", workshopClient, categoriesViewModel, entryListInputViewModel, notificationService, getEntryListViewModel)
- {
- entryListInputViewModel.SearchWatermark = "Search layouts";
- }
-
- protected override EntryFilterInput GetFilter()
- {
- return new EntryFilterInput
- {
- And = new[]
- {
- new EntryFilterInput {EntryType = new EntryTypeOperationFilterInput {Eq = EntryType.Layout}},
- new EntryFilterInput(){LatestReleaseId = new LongOperationFilterInput {Gt = 0}},
- base.GetFilter()
- }
- };
- }
-}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Workshop/Entries/Tabs/PluginListView.axaml b/src/Artemis.UI/Screens/Workshop/Entries/Tabs/PluginListView.axaml
deleted file mode 100644
index 7b6cb1f0c..000000000
--- a/src/Artemis.UI/Screens/Workshop/Entries/Tabs/PluginListView.axaml
+++ /dev/null
@@ -1,67 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- Categories
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Looks like your current filters gave no results
-
- Modify or clear your filters to view other plugins
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Workshop/Entries/Tabs/PluginListView.axaml.cs b/src/Artemis.UI/Screens/Workshop/Entries/Tabs/PluginListView.axaml.cs
deleted file mode 100644
index 8cfaa1696..000000000
--- a/src/Artemis.UI/Screens/Workshop/Entries/Tabs/PluginListView.axaml.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-using System;
-using System.Reactive.Disposables;
-using System.Threading;
-using Artemis.UI.Shared.Routing;
-using Avalonia.Controls;
-using Avalonia.ReactiveUI;
-using Avalonia.Threading;
-using ReactiveUI;
-
-namespace Artemis.UI.Screens.Workshop.Entries.Tabs;
-
-public partial class PluginListView : ReactiveUserControl
-{
- public PluginListView()
- {
- InitializeComponent();
- EntriesScrollViewer.SizeChanged += (_, _) => UpdateEntriesPerFetch();
-
- this.WhenActivated(d =>
- {
- UpdateEntriesPerFetch();
- ViewModel.WhenAnyValue(vm => vm.Screen).WhereNotNull().Subscribe(Navigate).DisposeWith(d);
- });
- }
-
- private void ScrollViewer_OnScrollChanged(object? sender, ScrollChangedEventArgs e)
- {
- // When near the bottom of EntriesScrollViewer, call FetchMore on the view model
- if (EntriesScrollViewer.Offset.Y != 0 && EntriesScrollViewer.Extent.Height - (EntriesScrollViewer.Viewport.Height + EntriesScrollViewer.Offset.Y) < 100)
- ViewModel?.FetchMore(CancellationToken.None);
- }
-
- private void Navigate(RoutableScreen viewModel)
- {
- Dispatcher.UIThread.Invoke(() => RouterFrame.NavigateFromObject(viewModel), DispatcherPriority.ApplicationIdle);
- }
-
- private void UpdateEntriesPerFetch()
- {
- if (ViewModel != null)
- ViewModel.EntriesPerFetch = (int) (EntriesScrollViewer.Viewport.Height / 120);
- }
-}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Workshop/Entries/Tabs/PluginListViewModel.cs b/src/Artemis.UI/Screens/Workshop/Entries/Tabs/PluginListViewModel.cs
deleted file mode 100644
index c7ea484a6..000000000
--- a/src/Artemis.UI/Screens/Workshop/Entries/Tabs/PluginListViewModel.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using System;
-using Artemis.UI.Screens.Workshop.Categories;
-using Artemis.UI.Screens.Workshop.Entries.List;
-using Artemis.UI.Shared.Routing;
-using Artemis.UI.Shared.Services;
-using Artemis.WebClient.Workshop;
-
-namespace Artemis.UI.Screens.Workshop.Entries.Tabs;
-
-public class PluginListViewModel : EntryListViewModel
-{
- public PluginListViewModel(IWorkshopClient workshopClient,
- CategoriesViewModel categoriesViewModel,
- EntryListInputViewModel entryListInputViewModel,
- INotificationService notificationService,
- Func getEntryListViewModel)
- : base("workshop/entries/plugins", workshopClient, categoriesViewModel, entryListInputViewModel, notificationService, getEntryListViewModel)
- {
- entryListInputViewModel.SearchWatermark = "Search plugins";
- }
-
- protected override EntryFilterInput GetFilter()
- {
- return new EntryFilterInput
- {
- And = new[]
- {
- new EntryFilterInput {EntryType = new EntryTypeOperationFilterInput {Eq = EntryType.Plugin}},
- base.GetFilter()
- }
- };
- }
-}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Workshop/Entries/Tabs/ProfileListView.axaml b/src/Artemis.UI/Screens/Workshop/Entries/Tabs/ProfileListView.axaml
deleted file mode 100644
index 03028d4b8..000000000
--- a/src/Artemis.UI/Screens/Workshop/Entries/Tabs/ProfileListView.axaml
+++ /dev/null
@@ -1,67 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- Categories
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Looks like your current filters gave no results
-
- Modify or clear your filters to view some awesome profiles
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Workshop/Entries/Tabs/ProfileListView.axaml.cs b/src/Artemis.UI/Screens/Workshop/Entries/Tabs/ProfileListView.axaml.cs
deleted file mode 100644
index b25ba45f3..000000000
--- a/src/Artemis.UI/Screens/Workshop/Entries/Tabs/ProfileListView.axaml.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-using System;
-using System.Reactive.Disposables;
-using System.Threading;
-using Artemis.UI.Shared.Routing;
-using Avalonia.Controls;
-using Avalonia.ReactiveUI;
-using Avalonia.Threading;
-using ReactiveUI;
-
-namespace Artemis.UI.Screens.Workshop.Entries.Tabs;
-
-public partial class ProfileListView : ReactiveUserControl
-{
- public ProfileListView()
- {
- InitializeComponent();
- EntriesScrollViewer.SizeChanged += (_, _) => UpdateEntriesPerFetch();
-
- this.WhenActivated(d =>
- {
- UpdateEntriesPerFetch();
- ViewModel.WhenAnyValue(vm => vm.Screen).WhereNotNull().Subscribe(Navigate).DisposeWith(d);
- });
- }
-
- private void ScrollViewer_OnScrollChanged(object? sender, ScrollChangedEventArgs e)
- {
- // When near the bottom of EntriesScrollViewer, call FetchMore on the view model
- if (EntriesScrollViewer.Offset.Y != 0 && EntriesScrollViewer.Extent.Height - (EntriesScrollViewer.Viewport.Height + EntriesScrollViewer.Offset.Y) < 100)
- ViewModel?.FetchMore(CancellationToken.None);
- }
-
- private void Navigate(RoutableScreen viewModel)
- {
- Dispatcher.UIThread.Invoke(() => RouterFrame.NavigateFromObject(viewModel), DispatcherPriority.ApplicationIdle);
- }
-
- private void UpdateEntriesPerFetch()
- {
- if (ViewModel != null)
- ViewModel.EntriesPerFetch = (int) (EntriesScrollViewer.Viewport.Height / 120);
- }
-}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Workshop/Entries/Tabs/ProfileListViewModel.cs b/src/Artemis.UI/Screens/Workshop/Entries/Tabs/ProfileListViewModel.cs
deleted file mode 100644
index 09ed5410b..000000000
--- a/src/Artemis.UI/Screens/Workshop/Entries/Tabs/ProfileListViewModel.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using System;
-using Artemis.UI.Screens.Workshop.Categories;
-using Artemis.UI.Screens.Workshop.Entries.List;
-using Artemis.UI.Shared.Routing;
-using Artemis.UI.Shared.Services;
-using Artemis.WebClient.Workshop;
-
-namespace Artemis.UI.Screens.Workshop.Entries.Tabs;
-
-public class ProfileListViewModel : List.EntryListViewModel
-{
- public ProfileListViewModel(IWorkshopClient workshopClient,
- CategoriesViewModel categoriesViewModel,
- EntryListInputViewModel entryListInputViewModel,
- INotificationService notificationService,
- Func getEntryListViewModel)
- : base("workshop/entries/profiles", workshopClient, categoriesViewModel, entryListInputViewModel, notificationService, getEntryListViewModel)
- {
- entryListInputViewModel.SearchWatermark = "Search profiles";
- }
-
- protected override EntryFilterInput GetFilter()
- {
- return new EntryFilterInput
- {
- And = new[]
- {
- new EntryFilterInput {EntryType = new EntryTypeOperationFilterInput {Eq = EntryType.Profile}},
- base.GetFilter()
- }
- };
- }
-}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Workshop/Layout/LayoutDetailsView.axaml b/src/Artemis.UI/Screens/Workshop/Layout/LayoutDetailsView.axaml
index 3dd205871..c8ed98401 100644
--- a/src/Artemis.UI/Screens/Workshop/Layout/LayoutDetailsView.axaml
+++ b/src/Artemis.UI/Screens/Workshop/Layout/LayoutDetailsView.axaml
@@ -12,7 +12,7 @@
-
+
diff --git a/src/Artemis.UI/Screens/Workshop/Layout/LayoutListView.axaml b/src/Artemis.UI/Screens/Workshop/Layout/LayoutListView.axaml
new file mode 100644
index 000000000..6c1b6e8ae
--- /dev/null
+++ b/src/Artemis.UI/Screens/Workshop/Layout/LayoutListView.axaml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Workshop/Layout/LayoutListView.axaml.cs b/src/Artemis.UI/Screens/Workshop/Layout/LayoutListView.axaml.cs
new file mode 100644
index 000000000..4adafd4f7
--- /dev/null
+++ b/src/Artemis.UI/Screens/Workshop/Layout/LayoutListView.axaml.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Reactive.Disposables;
+using Artemis.UI.Shared.Routing;
+using Avalonia.ReactiveUI;
+using Avalonia.Threading;
+using ReactiveUI;
+
+namespace Artemis.UI.Screens.Workshop.Layout;
+
+public partial class LayoutListView : ReactiveUserControl
+{
+ public LayoutListView()
+ {
+ InitializeComponent();
+ this.WhenActivated(d =>
+ {
+ ViewModel.WhenAnyValue(vm => vm.Screen).Subscribe(Navigate).DisposeWith(d);
+ });
+ }
+
+ private void Navigate(RoutableScreen? viewModel)
+ {
+ RouterFrame.NavigateFromObject(viewModel ?? ViewModel?.EntryListViewModel);
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Workshop/Layout/LayoutListViewModel.cs b/src/Artemis.UI/Screens/Workshop/Layout/LayoutListViewModel.cs
new file mode 100644
index 000000000..52806ca6a
--- /dev/null
+++ b/src/Artemis.UI/Screens/Workshop/Layout/LayoutListViewModel.cs
@@ -0,0 +1,16 @@
+using Artemis.UI.Screens.Workshop.Entries.List;
+using Artemis.UI.Shared.Routing;
+using Artemis.WebClient.Workshop;
+
+namespace Artemis.UI.Screens.Workshop.Layout;
+
+public class LayoutListViewModel : RoutableHostScreen
+{
+ public EntryListViewModel EntryListViewModel { get; }
+
+ public LayoutListViewModel(EntryListViewModel entryListViewModel)
+ {
+ EntryListViewModel = entryListViewModel;
+ EntryListViewModel.EntryType = EntryType.Layout;
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Workshop/Library/WorkshopLibraryVIew.axaml.cs b/src/Artemis.UI/Screens/Workshop/Library/WorkshopLibraryVIew.axaml.cs
index 7758b5729..5fa303000 100644
--- a/src/Artemis.UI/Screens/Workshop/Library/WorkshopLibraryVIew.axaml.cs
+++ b/src/Artemis.UI/Screens/Workshop/Library/WorkshopLibraryVIew.axaml.cs
@@ -18,9 +18,9 @@ public partial class WorkshopLibraryView : ReactiveUserControl TabFrame.NavigateFromObject(viewModel));
+ TabFrame.NavigateFromObject(viewModel);
}
-
+
private void NavigationView_OnBackRequested(object? sender, NavigationViewBackRequestedEventArgs e)
{
ViewModel?.GoBack();
diff --git a/src/Artemis.UI/Screens/Workshop/Plugins/PluginDetailsView.axaml b/src/Artemis.UI/Screens/Workshop/Plugins/PluginDetailsView.axaml
index dcbb4f5d1..1aa45690d 100644
--- a/src/Artemis.UI/Screens/Workshop/Plugins/PluginDetailsView.axaml
+++ b/src/Artemis.UI/Screens/Workshop/Plugins/PluginDetailsView.axaml
@@ -29,7 +29,7 @@
-
+
@@ -49,7 +49,13 @@
Used by these profiles
-
+
+
+
+
+
+
+
diff --git a/src/Artemis.UI/Screens/Workshop/Plugins/PluginDetailsViewModel.cs b/src/Artemis.UI/Screens/Workshop/Plugins/PluginDetailsViewModel.cs
index 64b556639..9a2d94314 100644
--- a/src/Artemis.UI/Screens/Workshop/Plugins/PluginDetailsViewModel.cs
+++ b/src/Artemis.UI/Screens/Workshop/Plugins/PluginDetailsViewModel.cs
@@ -33,7 +33,7 @@ public partial class PluginDetailsViewModel : RoutableScreen? _dependants;
-
+
public PluginDetailsViewModel(IWorkshopClient client,
IWindowService windowService,
IPluginManagementService pluginManagementService,
@@ -72,18 +72,21 @@ public partial class PluginDetailsViewModel : RoutableScreen? dependants = (await _client.GetDependantEntries.ExecuteAsync(entryId, 0, 25, cancellationToken)).Data?.Entries?.Items;
Dependants = dependants != null && dependants.Any()
- ? new ReadOnlyObservableCollection(new ObservableCollection(dependants.Select(_getEntryListViewModel)))
+ ? new ReadOnlyObservableCollection(new ObservableCollection(dependants
+ .Select(_getEntryListViewModel)
+ .OrderByDescending(d => d.Entry.Downloads)
+ .Take(10)))
: null;
}
- private async Task OnInstallationStarted(IEntryDetails entryDetails)
+ private async Task OnInstallationStarted(IEntryDetails entryDetails, IRelease release)
{
bool confirm = await _windowService.ShowConfirmContentDialog(
"Installing plugin",
- $"You are about to install version {entryDetails.LatestRelease?.Version} of {entryDetails.Name}. \r\n\r\n" +
+ $"You are about to install version {release.Version} of {entryDetails.Name}. \r\n\r\n" +
"Plugins are NOT verified by Artemis and could harm your PC, if you have doubts about a plugin please ask on Discord!",
"I trust this plugin, install it"
);
diff --git a/src/Artemis.UI/Screens/Workshop/Plugins/PluginListView.axaml b/src/Artemis.UI/Screens/Workshop/Plugins/PluginListView.axaml
new file mode 100644
index 000000000..da72fd3fe
--- /dev/null
+++ b/src/Artemis.UI/Screens/Workshop/Plugins/PluginListView.axaml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Workshop/Plugins/PluginListView.axaml.cs b/src/Artemis.UI/Screens/Workshop/Plugins/PluginListView.axaml.cs
new file mode 100644
index 000000000..27b52c560
--- /dev/null
+++ b/src/Artemis.UI/Screens/Workshop/Plugins/PluginListView.axaml.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Reactive.Disposables;
+using Artemis.UI.Shared.Routing;
+using Avalonia.ReactiveUI;
+using ReactiveUI;
+
+namespace Artemis.UI.Screens.Workshop.Plugins;
+
+public partial class PluginListView : ReactiveUserControl
+{
+ public PluginListView()
+ {
+ InitializeComponent();
+ this.WhenActivated(d =>
+ {
+ ViewModel.WhenAnyValue(vm => vm.Screen).Subscribe(Navigate).DisposeWith(d);
+ });
+ }
+
+ private void Navigate(RoutableScreen? viewModel)
+ {
+ RouterFrame.NavigateFromObject(viewModel ?? ViewModel?.EntryListViewModel);
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Workshop/Plugins/PluginListViewModel.cs b/src/Artemis.UI/Screens/Workshop/Plugins/PluginListViewModel.cs
new file mode 100644
index 000000000..a5e1216ec
--- /dev/null
+++ b/src/Artemis.UI/Screens/Workshop/Plugins/PluginListViewModel.cs
@@ -0,0 +1,16 @@
+using Artemis.UI.Screens.Workshop.Entries.List;
+using Artemis.UI.Shared.Routing;
+using Artemis.WebClient.Workshop;
+
+namespace Artemis.UI.Screens.Workshop.Plugins;
+
+public class PluginListViewModel : RoutableHostScreen
+{
+ public EntryListViewModel EntryListViewModel { get; }
+
+ public PluginListViewModel(EntryListViewModel entryListViewModel)
+ {
+ EntryListViewModel = entryListViewModel;
+ EntryListViewModel.EntryType = EntryType.Plugin;
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Workshop/Profile/ProfileDetailsView.axaml b/src/Artemis.UI/Screens/Workshop/Profile/ProfileDetailsView.axaml
index 499a5b978..9220a2b49 100644
--- a/src/Artemis.UI/Screens/Workshop/Profile/ProfileDetailsView.axaml
+++ b/src/Artemis.UI/Screens/Workshop/Profile/ProfileDetailsView.axaml
@@ -12,7 +12,7 @@
-
+
@@ -32,7 +32,13 @@
Required plugins
-
+
+
+
+
+
+
+
diff --git a/src/Artemis.UI/Screens/Workshop/Profile/ProfileListView.axaml b/src/Artemis.UI/Screens/Workshop/Profile/ProfileListView.axaml
new file mode 100644
index 000000000..70ca1997a
--- /dev/null
+++ b/src/Artemis.UI/Screens/Workshop/Profile/ProfileListView.axaml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Workshop/Profile/ProfileListView.axaml.cs b/src/Artemis.UI/Screens/Workshop/Profile/ProfileListView.axaml.cs
new file mode 100644
index 000000000..3f038ad94
--- /dev/null
+++ b/src/Artemis.UI/Screens/Workshop/Profile/ProfileListView.axaml.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Reactive.Disposables;
+using Artemis.UI.Shared.Routing;
+using Avalonia.ReactiveUI;
+using Avalonia.Threading;
+using ReactiveUI;
+
+namespace Artemis.UI.Screens.Workshop.Profile;
+
+public partial class ProfileListView : ReactiveUserControl
+{
+ public ProfileListView()
+ {
+ InitializeComponent();
+ this.WhenActivated(d =>
+ {
+ ViewModel.WhenAnyValue(vm => vm.Screen).Subscribe(Navigate).DisposeWith(d);
+ });
+ }
+
+ private void Navigate(RoutableScreen? viewModel)
+ {
+ RouterFrame.NavigateFromObject(viewModel ?? ViewModel?.EntryListViewModel);
+ }
+}
\ 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
new file mode 100644
index 000000000..f012bf65c
--- /dev/null
+++ b/src/Artemis.UI/Screens/Workshop/Profile/ProfileListViewModel.cs
@@ -0,0 +1,16 @@
+using Artemis.UI.Screens.Workshop.Entries.List;
+using Artemis.UI.Shared.Routing;
+using Artemis.WebClient.Workshop;
+
+namespace Artemis.UI.Screens.Workshop.Profile;
+
+public class ProfileListViewModel : RoutableHostScreen
+{
+ public EntryListViewModel EntryListViewModel { get; }
+
+ public ProfileListViewModel(EntryListViewModel entryListViewModel)
+ {
+ EntryListViewModel = entryListViewModel;
+ EntryListViewModel.EntryType = EntryType.Profile;
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/ReleaseWizardView.axaml.cs b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/ReleaseWizardView.axaml.cs
index 50bbc4ace..ca6667b66 100644
--- a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/ReleaseWizardView.axaml.cs
+++ b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/ReleaseWizardView.axaml.cs
@@ -8,7 +8,7 @@ using ReactiveUI;
namespace Artemis.UI.Screens.Workshop.SubmissionWizard;
-public partial class ReleaseWizardView: ReactiveAppWindow
+public partial class ReleaseWizardView : ReactiveAppWindow
{
public ReleaseWizardView()
{
@@ -25,7 +25,7 @@ public partial class ReleaseWizardView: ReactiveAppWindow Frame.NavigateFromObject(viewModel));
+ Frame.NavigateFromObject(viewModel);
}
catch (Exception e)
{
diff --git a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/SubmissionWizardView.axaml.cs b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/SubmissionWizardView.axaml.cs
index 6c7ece92f..377bc17cb 100644
--- a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/SubmissionWizardView.axaml.cs
+++ b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/SubmissionWizardView.axaml.cs
@@ -25,7 +25,7 @@ public partial class SubmissionWizardView : ReactiveAppWindow Frame.NavigateFromObject(viewModel));
+ Frame.NavigateFromObject(viewModel);
}
catch (Exception e)
{
diff --git a/src/Artemis.UI/Styles/Markdown.axaml b/src/Artemis.UI/Styles/Markdown.axaml
index 6f03f8291..9f1bd2470 100644
--- a/src/Artemis.UI/Styles/Markdown.axaml
+++ b/src/Artemis.UI/Styles/Markdown.axaml
@@ -2,6 +2,11 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:avalonia="clr-namespace:Markdown.Avalonia;assembly=Markdown.Avalonia"
xmlns:ctxt="clr-namespace:ColorTextBlock.Avalonia;assembly=ColorTextBlock.Avalonia">
+
+
+ Test
+
+
diff --git a/src/Artemis.WebClient.Workshop/Queries/Fragments.graphql b/src/Artemis.WebClient.Workshop/Queries/Fragments.graphql
index 0325293c5..ea41aa36a 100644
--- a/src/Artemis.WebClient.Workshop/Queries/Fragments.graphql
+++ b/src/Artemis.WebClient.Workshop/Queries/Fragments.graphql
@@ -54,12 +54,12 @@ fragment entryDetails on Entry {
categories {
...category
}
- latestRelease {
- ...release
- }
images {
...image
}
+ releases {
+ ...release
+ }
}
fragment release on Release {