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:plugins="clr-namespace:Artemis.UI.Screens.Workshop.Plugins"
xmlns:mdxaml="https://github.com/whistyun/Markdown.Avalonia.Tight"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.Workshop.Plugins.PluginDescriptionView"
x:DataType="plugins:PluginDescriptionViewModel">
<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 Dependants, Converter={x:Static ObjectConverters.IsNotNull}}">
<StackPanel>
<TextBlock Theme="{StaticResource SubtitleTextBlockStyle}">Used by these profiles</TextBlock>
<Border Classes="card-separator" />
<ScrollViewer>
<ItemsControl ItemsSource="{CompiledBinding Dependants}">
<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.Plugins;
public partial class PluginDescriptionView : ReactiveUserControl<PluginDescriptionViewModel>
{
public PluginDescriptionView()
{
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.Plugins;
public partial class PluginDescriptionViewModel : RoutableScreen
{
[Notify] private IEntryDetails? _entry;
[Notify] private List<EntryListItemViewModel>? _dependants;
private readonly IWorkshopClient _client;
private readonly Func<IEntrySummary, EntryListItemViewModel> _getEntryListViewModel;
public PluginDescriptionViewModel(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>? dependants = (await _client.GetDependantEntries.ExecuteAsync(entry.Id, 0, 25, cancellationToken)).Data?.Entries?.Items;
Dependants = dependants != null && dependants.Any() ? dependants.Select(_getEntryListViewModel).OrderByDescending(d => d.Entry.Downloads).Take(10).ToList() : null;
}
else
{
Dependants = null;
}
}
}
@@ -5,6 +5,8 @@
xmlns:mdxaml="https://github.com/whistyun/Markdown.Avalonia.Tight"
xmlns:plugins="clr-namespace:Artemis.UI.Screens.Workshop.Plugins"
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:ui="clr-namespace:Artemis.UI"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.Workshop.Plugins.PluginDetailsView"
x:DataType="plugins:PluginDetailsViewModel">
@@ -35,31 +37,11 @@
</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 Dependants, Converter={x:Static ObjectConverters.IsNotNull}}">
<StackPanel>
<TextBlock Theme="{StaticResource SubtitleTextBlockStyle}">Used by these profiles</TextBlock>
<Border Classes="card-separator" />
<ScrollViewer>
<ItemsControl ItemsSource="{CompiledBinding Dependants}">
<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}" />
@@ -1,4 +1,7 @@
using System;
using System.Reactive.Disposables;
using Avalonia.ReactiveUI;
using ReactiveUI;
namespace Artemis.UI.Screens.Workshop.Plugins;
@@ -7,5 +10,8 @@ public partial class PluginDetailsView : ReactiveUserControl<PluginDetailsViewMo
public PluginDetailsView()
{
InitializeComponent();
this.WhenActivated(d => ViewModel.WhenAnyValue(vm => vm.Screen)
.Subscribe(screen => RouterFrame.NavigateFromObject(screen ?? ViewModel?.PluginDescriptionViewModel))
.DisposeWith(d));
}
}
@@ -19,7 +19,7 @@ using StrawberryShake;
namespace Artemis.UI.Screens.Workshop.Plugins;
public partial class PluginDetailsViewModel : RoutableScreen<WorkshopDetailParameters>
public partial class PluginDetailsViewModel : RoutableHostScreen<RoutableScreen, WorkshopDetailParameters>
{
private readonly IWorkshopClient _client;
private readonly IWindowService _windowService;
@@ -27,7 +27,6 @@ public partial class PluginDetailsViewModel : RoutableScreen<WorkshopDetailParam
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 IGetPluginEntryById_Entry? _entry;
[Notify] private EntryInfoViewModel? _entryInfoViewModel;
[Notify] private EntryReleasesViewModel? _entryReleasesViewModel;
@@ -37,23 +36,26 @@ public partial class PluginDetailsViewModel : RoutableScreen<WorkshopDetailParam
public PluginDetailsViewModel(IWorkshopClient client,
IWindowService windowService,
IPluginManagementService pluginManagementService,
PluginDescriptionViewModel pluginDescriptionViewModel,
Func<IEntryDetails, EntryInfoViewModel> getEntryInfoViewModel,
Func<IEntryDetails, EntryReleasesViewModel> getEntryReleasesViewModel,
Func<IEntryDetails, EntryImagesViewModel> getEntryImagesViewModel,
Func<IEntrySummary, EntryListItemViewModel> getEntryListViewModel)
Func<IEntryDetails, EntryImagesViewModel> getEntryImagesViewModel)
{
PluginDescriptionViewModel = pluginDescriptionViewModel;
_client = client;
_windowService = windowService;
_pluginManagementService = pluginManagementService;
_getEntryInfoViewModel = getEntryInfoViewModel;
_getEntryReleasesViewModel = getEntryReleasesViewModel;
_getEntryImagesViewModel = getEntryImagesViewModel;
_getEntryListViewModel = getEntryListViewModel;
}
public PluginDescriptionViewModel PluginDescriptionViewModel { 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)
@@ -73,13 +75,7 @@ public partial class PluginDetailsViewModel : RoutableScreen<WorkshopDetailParam
EntryReleasesViewModel.OnInstallationFinished = OnInstallationFinished;
}
IReadOnlyList<IEntrySummary>? dependants = (await _client.GetDependantEntries.ExecuteAsync(entryId, 0, 25, cancellationToken)).Data?.Entries?.Items;
Dependants = dependants != null && dependants.Any()
? new ReadOnlyObservableCollection<EntryListItemViewModel>(new ObservableCollection<EntryListItemViewModel>(dependants
.Select(_getEntryListViewModel)
.OrderByDescending(d => d.Entry.Downloads)
.Take(10)))
: null;
await PluginDescriptionViewModel.SetEntry(Entry, cancellationToken);
}
private async Task<bool> OnInstallationStarted(IEntryDetails entryDetails, IRelease release)
@@ -1,6 +1,5 @@
using System;
using System.Reactive.Disposables;
using Artemis.UI.Shared.Routing;
using Avalonia.ReactiveUI;
using ReactiveUI;
@@ -11,14 +10,8 @@ public partial class PluginListView : ReactiveUserControl<PluginListViewModel>
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);
this.WhenActivated(d => ViewModel.WhenAnyValue(vm => vm.Screen)
.Subscribe(screen => RouterFrame.NavigateFromObject(screen ?? ViewModel?.EntryListViewModel))
.DisposeWith(d));
}
}