From 4143cc2de839814d36ca9e0792cac87fcd6b888d Mon Sep 17 00:00:00 2001 From: Robert Date: Fri, 25 Aug 2023 22:54:56 +0200 Subject: [PATCH] Added profile details --- src/Artemis.UI/Artemis.UI.csproj | 3 +- .../Converters/DateTimeConverter.cs | 34 +++++ .../Updating/ReleaseDetailsView.axaml | 31 ++-- .../Settings/Updating/ReleaseView.axaml | 8 +- .../Workshop/Entries/EntryListView.axaml | 3 +- .../Workshop/Profile/ProfileDetailsView.axaml | 141 +++++++++++++----- .../Profile/ProfileDetailsViewModel.cs | 8 +- src/Artemis.UI/Styles/Markdown.axaml | 3 + .../Queries/GetEntries.graphql | 2 +- .../Queries/GetEntryById.graphql | 7 + .../Services/AuthenticationService.cs | 4 + .../WorkshopConstants.cs | 4 +- src/Artemis.WebClient.Workshop/schema.graphql | 4 + 13 files changed, 191 insertions(+), 61 deletions(-) create mode 100644 src/Artemis.UI/Converters/DateTimeConverter.cs diff --git a/src/Artemis.UI/Artemis.UI.csproj b/src/Artemis.UI/Artemis.UI.csproj index ec781ea8f..f7ffa8c34 100644 --- a/src/Artemis.UI/Artemis.UI.csproj +++ b/src/Artemis.UI/Artemis.UI.csproj @@ -32,7 +32,8 @@ - + + diff --git a/src/Artemis.UI/Converters/DateTimeConverter.cs b/src/Artemis.UI/Converters/DateTimeConverter.cs new file mode 100644 index 000000000..7baf68ebb --- /dev/null +++ b/src/Artemis.UI/Converters/DateTimeConverter.cs @@ -0,0 +1,34 @@ +using System; +using System.Globalization; +using Artemis.WebClient.Workshop; +using Avalonia.Data.Converters; +using Humanizer; + +namespace Artemis.UI.Converters; + +public class DateTimeConverter : IValueConverter +{ + public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + { + if (value is DateTimeOffset dateTimeOffset) + { + return parameter?.ToString() == "humanize" + ? dateTimeOffset.ToLocalTime().Humanize() + : dateTimeOffset.ToLocalTime().ToString(parameter?.ToString() ?? "g"); + } + + if (value is DateTime dateTime) + { + return parameter?.ToString() == "humanize" + ? dateTime.ToLocalTime().Humanize() + : dateTime.ToLocalTime().ToString(parameter?.ToString() ?? "g"); + } + + return value; + } + + public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + { + return value; + } +} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Settings/Updating/ReleaseDetailsView.axaml b/src/Artemis.UI/Screens/Settings/Updating/ReleaseDetailsView.axaml index 61fe4a5c1..ef4b22704 100644 --- a/src/Artemis.UI/Screens/Settings/Updating/ReleaseDetailsView.axaml +++ b/src/Artemis.UI/Screens/Settings/Updating/ReleaseDetailsView.axaml @@ -3,22 +3,23 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:updating="clr-namespace:Artemis.UI.Screens.Settings.Updating" - xmlns:avalonia="clr-namespace:Markdown.Avalonia;assembly=Markdown.Avalonia" - xmlns:avalonia1="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia" - xmlns:converters="clr-namespace:Artemis.UI.Shared.Converters;assembly=Artemis.UI.Shared" - xmlns:converters1="clr-namespace:Artemis.UI.Converters" + xmlns:shared="clr-namespace:Artemis.UI.Shared.Converters;assembly=Artemis.UI.Shared" + xmlns:converters="clr-namespace:Artemis.UI.Converters" + xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia" + xmlns:mdxaml="https://github.com/whistyun/Markdown.Avalonia.Tight" mc:Ignorable="d" d:DesignWidth="1000" d:DesignHeight="1400" x:Class="Artemis.UI.Screens.Settings.Updating.ReleaseDetailsView" x:DataType="updating:ReleaseDetailsViewModel"> - - + + + - @@ -103,16 +104,16 @@ - + Release date + Text="{CompiledBinding Release.CreatedAt, Converter={StaticResource DateTimeConverter}, FallbackValue=Loading...}" /> - + Source - + File size Release notes - - + + - - + + diff --git a/src/Artemis.UI/Screens/Settings/Updating/ReleaseView.axaml b/src/Artemis.UI/Screens/Settings/Updating/ReleaseView.axaml index 97e58bd65..47a02b961 100644 --- a/src/Artemis.UI/Screens/Settings/Updating/ReleaseView.axaml +++ b/src/Artemis.UI/Screens/Settings/Updating/ReleaseView.axaml @@ -4,13 +4,17 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:updating="clr-namespace:Artemis.UI.Screens.Settings.Updating" xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia" + xmlns:converters="clr-namespace:Artemis.UI.Converters" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="Artemis.UI.Screens.Settings.Updating.ReleaseView" x:DataType="updating:ReleaseViewModel"> + + + - + - + diff --git a/src/Artemis.UI/Screens/Workshop/Entries/EntryListView.axaml b/src/Artemis.UI/Screens/Workshop/Entries/EntryListView.axaml index 0c98ad6d0..e29a4f040 100644 --- a/src/Artemis.UI/Screens/Workshop/Entries/EntryListView.axaml +++ b/src/Artemis.UI/Screens/Workshop/Entries/EntryListView.axaml @@ -11,6 +11,7 @@ x:DataType="entries1:EntryListViewModel"> + + + + + + + + + + + + - - Profile details panel diff --git a/src/Artemis.UI/Screens/Workshop/Profile/ProfileDetailsViewModel.cs b/src/Artemis.UI/Screens/Workshop/Profile/ProfileDetailsViewModel.cs index 7f9a618d6..ed92162f8 100644 --- a/src/Artemis.UI/Screens/Workshop/Profile/ProfileDetailsViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/Profile/ProfileDetailsViewModel.cs @@ -1,11 +1,12 @@ using System; +using System.Reactive.Linq; using System.Threading; using System.Threading.Tasks; using Artemis.UI.Screens.Workshop.Parameters; using Artemis.UI.Shared; using Artemis.UI.Shared.Routing; using Artemis.WebClient.Workshop; -using Avalonia.Media.Imaging; +using ReactiveUI; using StrawberryShake; namespace Artemis.UI.Screens.Workshop.Profile; @@ -13,14 +14,17 @@ namespace Artemis.UI.Screens.Workshop.Profile; public class ProfileDetailsViewModel : RoutableScreen, IWorkshopViewModel { private readonly IWorkshopClient _client; + private readonly ObservableAsPropertyHelper _updatedAt; private IGetEntryById_Entry? _entry; - private Bitmap? _entryIcon; public ProfileDetailsViewModel(IWorkshopClient client) { _client = client; + _updatedAt = this.WhenAnyValue(vm => vm.Entry).Select(e => e?.LatestRelease?.CreatedAt ?? e?.CreatedAt).ToProperty(this, vm => vm.UpdatedAt); } + public DateTimeOffset? UpdatedAt => _updatedAt.Value; + public EntryType? EntryType => null; public IGetEntryById_Entry? Entry diff --git a/src/Artemis.UI/Styles/Markdown.axaml b/src/Artemis.UI/Styles/Markdown.axaml index 5374e71b0..6f03f8291 100644 --- a/src/Artemis.UI/Styles/Markdown.axaml +++ b/src/Artemis.UI/Styles/Markdown.axaml @@ -2,6 +2,9 @@ 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"> + diff --git a/src/Artemis.WebClient.Workshop/Queries/GetEntries.graphql b/src/Artemis.WebClient.Workshop/Queries/GetEntries.graphql index a1879e786..e5e0648be 100644 --- a/src/Artemis.WebClient.Workshop/Queries/GetEntries.graphql +++ b/src/Artemis.WebClient.Workshop/Queries/GetEntries.graphql @@ -8,7 +8,7 @@ query GetEntries($filter: EntryFilterInput $skip: Int $take: Int) { summary entryType downloads - createdAt + createdAt categories { name icon diff --git a/src/Artemis.WebClient.Workshop/Queries/GetEntryById.graphql b/src/Artemis.WebClient.Workshop/Queries/GetEntryById.graphql index c083be2d8..5933626a0 100644 --- a/src/Artemis.WebClient.Workshop/Queries/GetEntryById.graphql +++ b/src/Artemis.WebClient.Workshop/Queries/GetEntryById.graphql @@ -12,5 +12,12 @@ query GetEntryById($id: UUID!) { name icon } + latestRelease { + id + version + downloadSize + md5Hash + createdAt + } } } \ 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 f67af2d14..5a75e499c 100644 --- a/src/Artemis.WebClient.Workshop/Services/AuthenticationService.cs +++ b/src/Artemis.WebClient.Workshop/Services/AuthenticationService.cs @@ -245,6 +245,10 @@ internal class AuthenticationService : CorePropertyChanged, IAuthenticationServi listener.Stop(); listener.Close(); } + catch (HttpListenerException e) + { + throw new ArtemisWebClientException($"HTTP listener for login callback failed with error code {e.ErrorCode}", e); + } finally { _authLock.Release(); diff --git a/src/Artemis.WebClient.Workshop/WorkshopConstants.cs b/src/Artemis.WebClient.Workshop/WorkshopConstants.cs index 192a92b56..1dcfa737d 100644 --- a/src/Artemis.WebClient.Workshop/WorkshopConstants.cs +++ b/src/Artemis.WebClient.Workshop/WorkshopConstants.cs @@ -2,7 +2,7 @@ namespace Artemis.WebClient.Workshop; public static class WorkshopConstants { - public const string AUTHORITY_URL = "https://identity.artemis-rgb.com"; - public const string WORKSHOP_URL = "https://workshop.artemis-rgb.com"; + public const string AUTHORITY_URL = "https://localhost:5001"; + public const string WORKSHOP_URL = "https://localhost:7281"; public const string WORKSHOP_CLIENT_NAME = "WorkshopApiClient"; } \ No newline at end of file diff --git a/src/Artemis.WebClient.Workshop/schema.graphql b/src/Artemis.WebClient.Workshop/schema.graphql index 59efce290..8b99d85ea 100644 --- a/src/Artemis.WebClient.Workshop/schema.graphql +++ b/src/Artemis.WebClient.Workshop/schema.graphql @@ -37,8 +37,10 @@ type Entry { downloads: Long! entryType: EntryType! icon: Image + iconId: UUID id: UUID! images: [Image!]! + latestRelease: Release name: String! releases: [Release!]! summary: String! @@ -151,6 +153,7 @@ input EntryFilterInput { downloads: LongOperationFilterInput entryType: EntryTypeOperationFilterInput icon: ImageFilterInput + iconId: UuidOperationFilterInput id: UuidOperationFilterInput images: ListFilterInputTypeOfImageFilterInput name: StringOperationFilterInput @@ -168,6 +171,7 @@ input EntrySortInput { downloads: SortEnumType entryType: SortEnumType icon: ImageSortInput + iconId: SortEnumType id: SortEnumType name: SortEnumType summary: SortEnumType