diff --git a/src/Artemis.UI.Windows/Providers/WindowsUpdateNotificationProvider.cs b/src/Artemis.UI.Windows/Providers/WindowsUpdateNotificationProvider.cs
index c98a0d6df..95f16b5cb 100644
--- a/src/Artemis.UI.Windows/Providers/WindowsUpdateNotificationProvider.cs
+++ b/src/Artemis.UI.Windows/Providers/WindowsUpdateNotificationProvider.cs
@@ -175,7 +175,7 @@ public class WindowsUpdateNotificationProvider : IUpdateNotificationProvider
else if (action == "disable-workshop-notifications")
_workshopUpdateService.DisableNotifications();
else if (action == "view-library")
- NavigateToRoute("workshop/library");
+ NavigateToRoute("workshop/library/recently-updated");
}
private void NavigateToRoute(string route)
diff --git a/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryInfoViewModel.cs b/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryInfoViewModel.cs
index 13703c684..38b10e17d 100644
--- a/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryInfoViewModel.cs
+++ b/src/Artemis.UI/Screens/Workshop/Entries/Details/EntryInfoViewModel.cs
@@ -39,7 +39,7 @@ public partial class EntryInfoViewModel : ActivatableViewModelBase
.DisposeWith(d);
});
- IsAdministrator = authenticationService.GetRoles().Contains("Administrator");
+ IsAdministrator = authenticationService.Roles.Contains("Administrator");
}
public bool IsAdministrator { get; }
diff --git a/src/Artemis.UI/Screens/Workshop/Entries/Details/EntrySpecificationsViewModel.cs b/src/Artemis.UI/Screens/Workshop/Entries/Details/EntrySpecificationsViewModel.cs
index 446e32067..08a744f93 100644
--- a/src/Artemis.UI/Screens/Workshop/Entries/Details/EntrySpecificationsViewModel.cs
+++ b/src/Artemis.UI/Screens/Workshop/Entries/Details/EntrySpecificationsViewModel.cs
@@ -69,7 +69,7 @@ public partial class EntrySpecificationsViewModel : ValidatableViewModelBase
_categoriesValid = categoriesRule.ValidationChanged.Select(c => c.IsValid).ToProperty(this, vm => vm.CategoriesValid);
_descriptionValid = descriptionRule.ValidationChanged.Select(c => c.IsValid).ToProperty(this, vm => vm.DescriptionValid);
- IsAdministrator = authenticationService.GetRoles().Contains("Administrator");
+ IsAdministrator = authenticationService.Roles.Contains("Administrator");
this.WhenActivatedAsync(async _ => await PopulateCategories());
this.WhenAnyValue(vm => vm.Fit).Subscribe(_ => UpdateIcon());
}
diff --git a/src/Artemis.UI/Screens/Workshop/Library/Tabs/RecentlyUpdatedItemView.axaml b/src/Artemis.UI/Screens/Workshop/Library/Tabs/RecentlyUpdatedItemView.axaml
index 0f1598426..a4856478f 100644
--- a/src/Artemis.UI/Screens/Workshop/Library/Tabs/RecentlyUpdatedItemView.axaml
+++ b/src/Artemis.UI/Screens/Workshop/Library/Tabs/RecentlyUpdatedItemView.axaml
@@ -8,6 +8,7 @@
xmlns:converters="clr-namespace:Artemis.UI.Converters"
xmlns:mdxaml="https://github.com/whistyun/Markdown.Avalonia.Tight"
xmlns:ui="clr-namespace:Artemis.UI"
+ 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.Library.Tabs.RecentlyUpdatedItemView"
x:DataType="tabs:RecentlyUpdatedItemViewModel">
@@ -16,27 +17,43 @@
-
+
+
+
+
+
-
-
+
-
-
+
+
by
@@ -44,46 +61,54 @@
IsVisible="{CompiledBinding Entry.IsOfficial}"
Kind="ShieldStar"
Foreground="{DynamicResource SystemAccentColorLight1}"
- Margin="2 -2 0 0"
+ Margin="0 -2 0 0"
Width="18"
Height="18"
HorizontalAlignment="Left"
ToolTip.Tip="Official entry by the Artemis team" />
-
-
-
-
-
-
-
-
-
-
-
-
-
- not yet installed
-
-
+
+
+
+
-
-
-
- There are no release notes for this release.
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+ There are no release notes for this release.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Workshop/Library/Tabs/RecentlyUpdatedItemView.axaml.cs b/src/Artemis.UI/Screens/Workshop/Library/Tabs/RecentlyUpdatedItemView.axaml.cs
index 2896638d6..5cebd4123 100644
--- a/src/Artemis.UI/Screens/Workshop/Library/Tabs/RecentlyUpdatedItemView.axaml.cs
+++ b/src/Artemis.UI/Screens/Workshop/Library/Tabs/RecentlyUpdatedItemView.axaml.cs
@@ -1,4 +1,8 @@
-using ReactiveUI.Avalonia;
+using System.Threading.Tasks;
+using Artemis.WebClient.Workshop;
+using Avalonia.Controls;
+using Avalonia.Input;
+using ReactiveUI.Avalonia;
namespace Artemis.UI.Screens.Workshop.Library.Tabs;
@@ -8,4 +12,15 @@ public partial class RecentlyUpdatedItemView : ReactiveUserControl r.Id == entry.LatestReleaseId);
+ NotYetInstalled = InstalledEntry.ReleaseId != Releases.Max(r => r.Id);
}
- public bool NotYetInstalled => InstalledEntry.ReleaseId < Release.Id;
+
+ public InstalledEntry InstalledEntry { get; }
+ public IGetRecentUpdates_Entries Entry { get; }
+ public IReadOnlyList Releases { get; set; }
+ public IGetRecentUpdates_Entries_Releases LatestRelease { get; }
+
+ public async Task NavigateToEntry()
+ {
+ await _workshopService.NavigateToEntry(Entry.Id, Entry.EntryType);
+ }
+
+ public async Task NavigateToRelease(IGetRecentUpdates_Entries_Releases? release)
+ {
+ if (release == null)
+ return;
+
+ await _router.Navigate($"workshop/entries/{Entry.EntryType.ToString()}s/details/{Entry.Id}/releases/{release.Id}");
+ }
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Workshop/Library/Tabs/RecentlyUpdatedView.axaml b/src/Artemis.UI/Screens/Workshop/Library/Tabs/RecentlyUpdatedView.axaml
index b64fb619d..1fc1f6c2a 100644
--- a/src/Artemis.UI/Screens/Workshop/Library/Tabs/RecentlyUpdatedView.axaml
+++ b/src/Artemis.UI/Screens/Workshop/Library/Tabs/RecentlyUpdatedView.axaml
@@ -15,8 +15,8 @@
-
-
+
+
@@ -34,7 +34,7 @@
-
+
diff --git a/src/Artemis.UI/Screens/Workshop/Library/Tabs/RecentlyUpdatedViewModel.cs b/src/Artemis.UI/Screens/Workshop/Library/Tabs/RecentlyUpdatedViewModel.cs
index 2dc398dff..11cb140d8 100644
--- a/src/Artemis.UI/Screens/Workshop/Library/Tabs/RecentlyUpdatedViewModel.cs
+++ b/src/Artemis.UI/Screens/Workshop/Library/Tabs/RecentlyUpdatedViewModel.cs
@@ -51,7 +51,7 @@ public partial class RecentlyUpdatedViewModel : RoutableScreen
.Transform(getRecentlyUpdatedItemViewModel)
.SortAndBind(
out ReadOnlyObservableCollection entries,
- SortExpressionComparer.Descending(p => p.Release.CreatedAt)
+ SortExpressionComparer.Descending(p => p.LatestRelease.CreatedAt)
)
.Subscribe();
diff --git a/src/Artemis.WebClient.Workshop/Queries/GetEntries.graphql b/src/Artemis.WebClient.Workshop/Queries/GetEntries.graphql
index d9d95c3b8..d2bc3507e 100644
--- a/src/Artemis.WebClient.Workshop/Queries/GetEntries.graphql
+++ b/src/Artemis.WebClient.Workshop/Queries/GetEntries.graphql
@@ -44,28 +44,4 @@ query GetDefaultPlugins {
pluginGuid
}
}
-}
-
-query GetRecentUpdates($entryIds: [Long!]!, $cutoff: DateTime!) {
- entries(
- includeDefaults: true
- where: {
- and: [
- { id: { in: $entryIds } }
- { latestRelease: { createdAt: { gte: $cutoff } } }
- ]
- }
- ) {
- id
- author
- isOfficial
- name
- summary
- entryType
- createdAt
- latestRelease {
- ...release
- changelog
- }
- }
}
\ No newline at end of file
diff --git a/src/Artemis.WebClient.Workshop/Queries/GetRecentUpdates.graphql b/src/Artemis.WebClient.Workshop/Queries/GetRecentUpdates.graphql
new file mode 100644
index 000000000..17bf9d845
--- /dev/null
+++ b/src/Artemis.WebClient.Workshop/Queries/GetRecentUpdates.graphql
@@ -0,0 +1,27 @@
+query GetRecentUpdates($entryIds: [Long!]!, $cutoff: DateTime!) {
+ entries(
+ includeDefaults: true
+ order: [{ latestRelease: { createdAt: DESC } }]
+ where: {
+ and: [
+ { id: { in: $entryIds } }
+ { releases: { some: { createdAt: { gte: $cutoff } } } }
+ ]
+ }
+ ) {
+ id
+ author
+ isOfficial
+ name
+ summary
+ entryType
+ latestReleaseId
+ releases(
+ order: [{ createdAt: DESC }]
+ where: { createdAt: { gte: $cutoff } }
+ ) {
+ ...release
+ changelog
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.WebClient.Workshop/Services/AuthenticationService.cs b/src/Artemis.WebClient.Workshop/Services/AuthenticationService.cs
index 3f7e65735..3182f5c03 100644
--- a/src/Artemis.WebClient.Workshop/Services/AuthenticationService.cs
+++ b/src/Artemis.WebClient.Workshop/Services/AuthenticationService.cs
@@ -23,7 +23,8 @@ internal class AuthenticationService : CorePropertyChanged, IAuthenticationServi
private readonly IAuthenticationRepository _authenticationRepository;
private readonly SemaphoreSlim _authLock = new(1, 1);
private readonly SourceList _claims;
-
+ private readonly SourceList _roles;
+
private readonly IDiscoveryCache _discoveryCache;
private readonly ILogger _logger;
private readonly IHttpClientFactory _httpClientFactory;
@@ -41,7 +42,10 @@ internal class AuthenticationService : CorePropertyChanged, IAuthenticationServi
_claims = new SourceList();
_claims.Connect().Bind(out ReadOnlyObservableCollection claims).Subscribe();
+ _roles = new SourceList();
+ _roles.Connect().Bind(out ReadOnlyObservableCollection roles).Subscribe();
Claims = claims;
+ Roles = roles;
}
private async Task GetDiscovery()
@@ -68,6 +72,11 @@ internal class AuthenticationService : CorePropertyChanged, IAuthenticationServi
c.Clear();
c.AddRange(token.Claims);
});
+ _roles.Edit(r =>
+ {
+ r.Clear();
+ r.AddRange(_claims.Items.Where(c => c.Type == JwtClaimTypes.Role).Select(c => c.Value));
+ });
_isLoggedInSubject.OnNext(true);
}
@@ -118,7 +127,10 @@ internal class AuthenticationService : CorePropertyChanged, IAuthenticationServi
///
public ReadOnlyObservableCollection Claims { get; }
-
+
+ ///
+ public ReadOnlyObservableCollection Roles { get; }
+
///
public IObservable GetClaim(string type)
{
@@ -278,6 +290,7 @@ internal class AuthenticationService : CorePropertyChanged, IAuthenticationServi
_token = null;
_claims.Clear();
+ _roles.Clear();
SetStoredRefreshToken(null);
_isLoggedInSubject.OnNext(false);
}
@@ -289,12 +302,6 @@ internal class AuthenticationService : CorePropertyChanged, IAuthenticationServi
return emailVerified?.Value.ToLower() == "true";
}
- ///
- public List GetRoles()
- {
- return Claims.Where(c => c.Type == JwtClaimTypes.Role).Select(c => c.Value).ToList();
- }
-
private async Task InternalAutoLogin(bool force = false)
{
if (!force && _isLoggedInSubject.Value)
diff --git a/src/Artemis.WebClient.Workshop/Services/Interfaces/IAuthenticationService.cs b/src/Artemis.WebClient.Workshop/Services/Interfaces/IAuthenticationService.cs
index 66e1392be..b698ebca6 100644
--- a/src/Artemis.WebClient.Workshop/Services/Interfaces/IAuthenticationService.cs
+++ b/src/Artemis.WebClient.Workshop/Services/Interfaces/IAuthenticationService.cs
@@ -8,6 +8,7 @@ public interface IAuthenticationService : IProtectedArtemisService
{
IObservable IsLoggedIn { get; }
ReadOnlyObservableCollection Claims { get; }
+ ReadOnlyObservableCollection Roles { get; }
IObservable GetClaim(string type);
Task GetBearer();
@@ -15,5 +16,4 @@ public interface IAuthenticationService : IProtectedArtemisService
Task Login(CancellationToken cancellationToken);
Task Logout();
bool GetIsEmailVerified();
- List GetRoles();
}
\ No newline at end of file
diff --git a/src/Artemis.WebClient.Workshop/schema.graphql b/src/Artemis.WebClient.Workshop/schema.graphql
index e20b76968..06d063edf 100644
--- a/src/Artemis.WebClient.Workshop/schema.graphql
+++ b/src/Artemis.WebClient.Workshop/schema.graphql
@@ -65,7 +65,10 @@ type Entry {
categories: [Category!]!
tags: [Tag!]!
images: [Image!]!
- releases: [Release!]!
+ releases(
+ order: [ReleaseSortInput!] @cost(weight: "10")
+ where: ReleaseFilterInput @cost(weight: "10")
+ ): [Release!]!
dependantReleases: [Release!]!
}