Workshop - Added dedicated release page

This commit is contained in:
RobertBeekman committed 2024-03-27 21:43:45 +01:00
1 parent 9c04932afa
commit 9e994840f6
36 files changed
+535 -190

No files matched your search

@@ -0,0 +1,35 @@
<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:profile="clr-namespace:Artemis.UI.Screens.Workshop.Profile"
xmlns:mdxaml="https://github.com/whistyun/Markdown.Avalonia.Tight"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.Workshop.Profile.ProfileDescriptionView"
x:DataType="profile:ProfileDescriptionViewModel">
<StackPanel Spacing="10">
<Border Classes="card">
<mdxaml:MarkdownScrollViewer Markdown="{CompiledBinding Entry.Description}" MarkdownStyleName="FluentAvalonia">
<mdxaml:MarkdownScrollViewer.Styles>
<StyleInclude Source="/Styles/Markdown.axaml" />
</mdxaml:MarkdownScrollViewer.Styles>
</mdxaml:MarkdownScrollViewer>
</Border>
<Border Classes="card" VerticalAlignment="Top" IsVisible="{CompiledBinding Dependencies, Converter={x:Static ObjectConverters.IsNotNull}}">
<StackPanel>
<TextBlock Theme="{StaticResource SubtitleTextBlockStyle}">Required plugins</TextBlock>
<Border Classes="card-separator" />
<ScrollViewer>
<ItemsControl ItemsSource="{CompiledBinding Dependencies}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Spacing="5"></StackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
</StackPanel>
</Border>
</StackPanel>
</UserControl>
@@ -0,0 +1,14 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
namespace Artemis.UI.Screens.Workshop.Profile;
public partial class ProfileDescriptionView : ReactiveUserControl<ProfileDescriptionViewModel>
{
public ProfileDescriptionView()
{
InitializeComponent();
}
}
@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Artemis.UI.Screens.Workshop.Entries.List;
using Artemis.UI.Shared.Routing;
using Artemis.WebClient.Workshop;
using PropertyChanged.SourceGenerator;
namespace Artemis.UI.Screens.Workshop.Profile;
public partial class ProfileDescriptionViewModel : RoutableScreen
{
private readonly IWorkshopClient _client;
private readonly Func<IEntrySummary, EntryListItemViewModel> _getEntryListViewModel;
[Notify] private IEntryDetails? _entry;
[Notify] private List<EntryListItemViewModel>? _dependencies;
public ProfileDescriptionViewModel(IWorkshopClient client, Func<IEntrySummary, EntryListItemViewModel> getEntryListViewModel)
{
_client = client;
_getEntryListViewModel = getEntryListViewModel;
}
public async Task SetEntry(IEntryDetails? entry, CancellationToken cancellationToken)
{
Entry = entry;
if (entry != null)
{
IReadOnlyList<IEntrySummary>? dependencies = (await _client.GetLatestDependencies.ExecuteAsync(entry.Id, cancellationToken)).Data?.Entry?.LatestRelease?.Dependencies;
Dependencies = dependencies != null && dependencies.Any() ? dependencies.Select(_getEntryListViewModel).ToList() : null;
}
else
{
Dependencies = null;
}
}
}
@@ -4,6 +4,8 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:profile="clr-namespace:Artemis.UI.Screens.Workshop.Profile"
xmlns:mdxaml="https://github.com/whistyun/Markdown.Avalonia.Tight"
xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:ui="clr-namespace:Artemis.UI"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="800"
x:Class="Artemis.UI.Screens.Workshop.Profile.ProfileDetailsView"
x:DataType="profile:ProfileDetailsViewModel">
@@ -18,33 +20,12 @@
</StackPanel>
<ScrollViewer Grid.Row="1" Grid.Column="1">
<StackPanel Margin="10 0" Spacing="10">
<Border Classes="card">
<mdxaml:MarkdownScrollViewer Markdown="{CompiledBinding Entry.Description}" MarkdownStyleName="FluentAvalonia">
<mdxaml:MarkdownScrollViewer.Styles>
<StyleInclude Source="/Styles/Markdown.axaml" />
</mdxaml:MarkdownScrollViewer.Styles>
</mdxaml:MarkdownScrollViewer>
</Border>
<Border Classes="card" VerticalAlignment="Top" IsVisible="{CompiledBinding Dependencies, Converter={x:Static ObjectConverters.IsNotNull}}">
<StackPanel>
<TextBlock Theme="{StaticResource SubtitleTextBlockStyle}">Required plugins</TextBlock>
<Border Classes="card-separator" />
<ScrollViewer>
<ItemsControl ItemsSource="{CompiledBinding Dependencies}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Spacing="5"></StackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
</StackPanel>
</Border>
</StackPanel>
<controls:Frame Name="RouterFrame" IsNavigationStackEnabled="False" CacheSize="0" Margin="10 0">
<controls:Frame.NavigationPageFactory>
<ui:PageFactory />
</controls:Frame.NavigationPageFactory>
</controls:Frame>
</ScrollViewer>
<ContentControl Grid.Row="1" Grid.Column="2" IsVisible="{CompiledBinding Entry.Images.Count}" Content="{CompiledBinding EntryImagesViewModel}" />
</Grid>
@@ -1,4 +1,7 @@
using System;
using System.Reactive.Disposables;
using Avalonia.ReactiveUI;
using ReactiveUI;
namespace Artemis.UI.Screens.Workshop.Profile;
@@ -7,5 +10,8 @@ public partial class ProfileDetailsView : ReactiveUserControl<ProfileDetailsView
public ProfileDetailsView()
{
InitializeComponent();
this.WhenActivated(d => ViewModel.WhenAnyValue(vm => vm.Screen)
.Subscribe(screen => RouterFrame.NavigateFromObject(screen ?? ViewModel?.ProfileDescriptionViewModel))
.DisposeWith(d));
}
}
@@ -5,7 +5,6 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Artemis.UI.Screens.Workshop.Entries.Details;
using Artemis.UI.Screens.Workshop.Entries.List;
using Artemis.UI.Screens.Workshop.Parameters;
using Artemis.UI.Shared.Routing;
using Artemis.WebClient.Workshop;
@@ -14,36 +13,38 @@ using StrawberryShake;
namespace Artemis.UI.Screens.Workshop.Profile;
public partial class ProfileDetailsViewModel : RoutableScreen<WorkshopDetailParameters>
public partial class ProfileDetailsViewModel : RoutableHostScreen<RoutableScreen, WorkshopDetailParameters>
{
private readonly IWorkshopClient _client;
private readonly Func<IEntryDetails, EntryInfoViewModel> _getEntryInfoViewModel;
private readonly Func<IEntryDetails, EntryReleasesViewModel> _getEntryReleasesViewModel;
private readonly Func<IEntryDetails, EntryImagesViewModel> _getEntryImagesViewModel;
private readonly Func<IEntrySummary, EntryListItemViewModel> _getEntryListViewModel;
[Notify] private IEntryDetails? _entry;
[Notify] private EntryInfoViewModel? _entryInfoViewModel;
[Notify] private EntryReleasesViewModel? _entryReleasesViewModel;
[Notify] private EntryImagesViewModel? _entryImagesViewModel;
[Notify] private ReadOnlyObservableCollection<EntryListItemViewModel>? _dependencies;
public ProfileDetailsViewModel(IWorkshopClient client,
ProfileDescriptionViewModel profileDescriptionViewModel,
Func<IEntryDetails, EntryInfoViewModel> getEntryInfoViewModel,
Func<IEntryDetails, EntryReleasesViewModel> getEntryReleasesViewModel,
Func<IEntryDetails, EntryImagesViewModel> getEntryImagesViewModel,
Func<IEntrySummary, EntryListItemViewModel> getEntryListViewModel)
Func<IEntryDetails, EntryImagesViewModel> getEntryImagesViewModel)
{
ProfileDescriptionViewModel = profileDescriptionViewModel;
_client = client;
_getEntryInfoViewModel = getEntryInfoViewModel;
_getEntryReleasesViewModel = getEntryReleasesViewModel;
_getEntryImagesViewModel = getEntryImagesViewModel;
_getEntryListViewModel = getEntryListViewModel;
}
public ProfileDescriptionViewModel ProfileDescriptionViewModel { get; }
public override async Task OnNavigating(WorkshopDetailParameters parameters, NavigationArguments args, CancellationToken cancellationToken)
{
await GetEntry(parameters.EntryId, cancellationToken);
if (Entry?.Id != parameters.EntryId)
await GetEntry(parameters.EntryId, cancellationToken);
}
private async Task GetEntry(long entryId, CancellationToken cancellationToken)
@@ -56,10 +57,7 @@ public partial class ProfileDetailsViewModel : RoutableScreen<WorkshopDetailPara
EntryInfoViewModel = Entry != null ? _getEntryInfoViewModel(Entry) : null;
EntryReleasesViewModel = Entry != null ? _getEntryReleasesViewModel(Entry) : null;
EntryImagesViewModel = Entry != null ? _getEntryImagesViewModel(Entry) : null;
IReadOnlyList<IEntrySummary>? dependencies = (await _client.GetLatestDependencies.ExecuteAsync(entryId, cancellationToken)).Data?.Entry?.LatestRelease?.Dependencies;
Dependencies = dependencies != null && dependencies.Any()
? new ReadOnlyObservableCollection<EntryListItemViewModel>(new ObservableCollection<EntryListItemViewModel>(dependencies.Select(_getEntryListViewModel)))
: null;
await ProfileDescriptionViewModel.SetEntry(Entry, cancellationToken);
}
}
@@ -1,8 +1,6 @@
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;
@@ -12,14 +10,8 @@ public partial class ProfileListView : ReactiveUserControl<ProfileListViewModel>
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);
this.WhenActivated(d => ViewModel.WhenAnyValue(vm => vm.Screen)
.Subscribe(screen => RouterFrame.NavigateFromObject(screen ?? ViewModel?.EntryListViewModel))
.DisposeWith(d));
}
}