mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-12 11:56:30 +00:00
Workshop - Implemented plugin browsing, installation and removal
This commit is contained in:
1 parent
d9df443970
commit
21b8112de5
21 files changed
+410
-35
No files matched your search
@@ -25,7 +25,8 @@ public partial class EntriesViewModel : RoutableHostScreen<RoutableScreen>
|
||||
Tabs = new ObservableCollection<RouteViewModel>
|
||||
{
|
||||
new("Profiles", "workshop/entries/profiles/1", "workshop/entries/profiles"),
|
||||
new("Layouts", "workshop/entries/layouts/1", "workshop/entries/layouts")
|
||||
new("Layouts", "workshop/entries/layouts/1", "workshop/entries/layouts"),
|
||||
new("Plugins", "workshop/entries/plugins/1", "workshop/entries/plugins"),
|
||||
};
|
||||
|
||||
this.WhenActivated(d =>
|
||||
|
||||
@@ -34,6 +34,7 @@ public class EntryListItemViewModel : ActivatableViewModelBase
|
||||
await _router.Navigate($"workshop/entries/profiles/details/{Entry.Id}");
|
||||
break;
|
||||
case EntryType.Plugin:
|
||||
await _router.Navigate($"workshop/entries/plugins/details/{Entry.Id}");
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
<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:tabs="clr-namespace:Artemis.UI.Screens.Workshop.Entries.Tabs"
|
||||
xmlns:pagination="clr-namespace:Artemis.UI.Shared.Pagination;assembly=Artemis.UI.Shared"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Artemis.UI.Screens.Workshop.Entries.Tabs.PluginListView"
|
||||
x:DataType="tabs:PluginListViewModel">
|
||||
<UserControl.Styles>
|
||||
<Styles>
|
||||
<Style Selector="StackPanel.empty-state > TextBlock">
|
||||
<Setter Property="TextAlignment" Value="Center"></Setter>
|
||||
<Setter Property="TextWrapping" Value="Wrap"></Setter>
|
||||
</Style>
|
||||
</Styles>
|
||||
</UserControl.Styles>
|
||||
<Grid ColumnDefinitions="300,*" RowDefinitions="Auto,*,Auto">
|
||||
<StackPanel Grid.Column="0" Grid.RowSpan="3" Margin="0 0 10 0" VerticalAlignment="Top">
|
||||
<Border Classes="card" VerticalAlignment="Stretch">
|
||||
<StackPanel>
|
||||
<TextBlock Theme="{StaticResource SubtitleTextBlockStyle}">Categories</TextBlock>
|
||||
<Border Classes="card-separator" />
|
||||
<ContentControl Content="{CompiledBinding CategoriesViewModel}"></ContentControl>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
|
||||
<ProgressBar Grid.Column="1" Grid.Row="0" VerticalAlignment="Top" Margin="0 0 20 0" IsVisible="{CompiledBinding IsLoading}" IsIndeterminate="True" />
|
||||
<ContentControl Grid.Column="1" Grid.Row="0" Margin="0 0 20 8" Content="{CompiledBinding InputViewModel}"/>
|
||||
|
||||
<ScrollViewer Grid.Column="1" Grid.Row="1">
|
||||
<ItemsControl ItemsSource="{CompiledBinding Entries}" Margin="0 0 20 0">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<VirtualizingStackPanel />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<ContentControl Content="{CompiledBinding}" Margin="0 0 0 5"></ContentControl>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</ScrollViewer>
|
||||
|
||||
<Panel Grid.Column="1" Grid.Row="1" IsVisible="{CompiledBinding !IsLoading}">
|
||||
<StackPanel IsVisible="{CompiledBinding !Entries.Count}" Margin="0 50 0 0" Classes="empty-state">
|
||||
<TextBlock Theme="{StaticResource TitleTextBlockStyle}">Looks like your current filters gave no results</TextBlock>
|
||||
<TextBlock>
|
||||
<Run>Modify or clear your filters to view other plugins</Run>
|
||||
</TextBlock>
|
||||
<Lottie Path="/Assets/Animations/empty.json" RepeatCount="1" Width="350" Height="350"></Lottie>
|
||||
</StackPanel>
|
||||
</Panel>
|
||||
|
||||
<pagination:Pagination Grid.Column="1"
|
||||
Grid.Row="2"
|
||||
Margin="0 20 0 10"
|
||||
IsVisible="{CompiledBinding ShowPagination}"
|
||||
Value="{CompiledBinding Page}"
|
||||
Maximum="{CompiledBinding TotalPages}"
|
||||
HorizontalAlignment="Center" />
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,14 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Screens.Workshop.Entries.Tabs;
|
||||
|
||||
public partial class PluginListView : ReactiveUserControl<PluginListViewModel>
|
||||
{
|
||||
public PluginListView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
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,
|
||||
IRouter router,
|
||||
CategoriesViewModel categoriesViewModel,
|
||||
EntryListInputViewModel entryListInputViewModel,
|
||||
INotificationService notificationService,
|
||||
Func<IGetEntries_Entries_Items, EntryListItemViewModel> getEntryListViewModel)
|
||||
: base("workshop/entries/plugins", workshopClient, router, 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()
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ public class ProfileListViewModel : List.EntryListViewModel
|
||||
public ProfileListViewModel(IWorkshopClient workshopClient,
|
||||
IRouter router,
|
||||
CategoriesViewModel categoriesViewModel,
|
||||
List.EntryListInputViewModel entryListInputViewModel,
|
||||
EntryListInputViewModel entryListInputViewModel,
|
||||
INotificationService notificationService,
|
||||
Func<IGetEntries_Entries_Items, EntryListItemViewModel> getEntryListViewModel)
|
||||
: base("workshop/entries/profiles", workshopClient, router, categoriesViewModel, entryListInputViewModel, notificationService, getEntryListViewModel)
|
||||
|
||||
@@ -57,6 +57,14 @@
|
||||
</StackPanel>
|
||||
</Button>
|
||||
|
||||
<Button Width="150" Height="180" Command="{CompiledBinding Navigate}" CommandParameter="workshop/entries/plugins/1" VerticalContentAlignment="Top">
|
||||
<StackPanel>
|
||||
<avalonia:MaterialIcon Kind="Plugin" HorizontalAlignment="Left" Width="60" Height="60" Margin="0 5" />
|
||||
<TextBlock TextWrapping="Wrap" FontSize="16" Margin="0 5">Plugins</TextBlock>
|
||||
<TextBlock TextWrapping="Wrap" FontSize="12" Opacity="0.8">Plugins add new functionality to Artemis.</TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
|
||||
<Button Width="150" Height="180" Command="{CompiledBinding Navigate}" CommandParameter="workshop/library" VerticalContentAlignment="Top">
|
||||
<StackPanel>
|
||||
<avalonia:MaterialIcon Kind="Bookshelf" HorizontalAlignment="Left" Width="60" Height="60" Margin="0 5" />
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
<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:plugin="clr-namespace:Artemis.UI.Screens.Workshop.Plugin"
|
||||
xmlns:mdxaml="https://github.com/whistyun/Markdown.Avalonia.Tight"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Artemis.UI.Screens.Workshop.Plugin.PluginDetailsView"
|
||||
x:DataType="plugin:PluginDetailsViewModel">
|
||||
<Grid ColumnDefinitions="300,*, 300" RowDefinitions="Auto,*">
|
||||
<StackPanel Grid.Row="1" Grid.Column="0" Spacing="10">
|
||||
<Border Classes="card" VerticalAlignment="Top">
|
||||
<ContentControl Content="{CompiledBinding EntryInfoViewModel}" />
|
||||
</Border>
|
||||
<Border Classes="card" VerticalAlignment="Top" IsVisible="{CompiledBinding Entry.LatestRelease, Converter={x:Static ObjectConverters.IsNotNull}}">
|
||||
<ContentControl Content="{CompiledBinding EntryReleasesViewModel}" />
|
||||
</Border>
|
||||
</StackPanel>
|
||||
|
||||
<Border Classes="card" Grid.Row="1" Grid.Column="1" Margin="10 0">
|
||||
<mdxaml:MarkdownScrollViewer Markdown="{CompiledBinding Entry.Description}" MarkdownStyleName="FluentAvalonia">
|
||||
<mdxaml:MarkdownScrollViewer.Styles>
|
||||
<StyleInclude Source="/Styles/Markdown.axaml" />
|
||||
</mdxaml:MarkdownScrollViewer.Styles>
|
||||
</mdxaml:MarkdownScrollViewer>
|
||||
</Border>
|
||||
|
||||
<ContentControl Grid.Row="1" Grid.Column="2" IsVisible="{CompiledBinding Entry.Images.Count}" Content="{CompiledBinding EntryImagesViewModel}" />
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,14 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.ReactiveUI;
|
||||
|
||||
namespace Artemis.UI.Screens.Workshop.Plugin;
|
||||
|
||||
public partial class PluginDetailsView : ReactiveUserControl<PluginDetailsViewModel>
|
||||
{
|
||||
public PluginDetailsView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.UI.Screens.Workshop.Entries.Details;
|
||||
using Artemis.UI.Screens.Workshop.Parameters;
|
||||
using Artemis.UI.Shared.Routing;
|
||||
using Artemis.WebClient.Workshop;
|
||||
using PropertyChanged.SourceGenerator;
|
||||
using StrawberryShake;
|
||||
|
||||
namespace Artemis.UI.Screens.Workshop.Plugin;
|
||||
|
||||
public partial class PluginDetailsViewModel : RoutableScreen<WorkshopDetailParameters>
|
||||
{
|
||||
private readonly IWorkshopClient _client;
|
||||
private readonly Func<IGetEntryById_Entry, EntryInfoViewModel> _getEntryInfoViewModel;
|
||||
private readonly Func<IGetEntryById_Entry, EntryReleasesViewModel> _getEntryReleasesViewModel;
|
||||
private readonly Func<IGetEntryById_Entry, EntryImagesViewModel> _getEntryImagesViewModel;
|
||||
[Notify] private IGetEntryById_Entry? _entry;
|
||||
[Notify] private EntryInfoViewModel? _entryInfoViewModel;
|
||||
[Notify] private EntryReleasesViewModel? _entryReleasesViewModel;
|
||||
[Notify] private EntryImagesViewModel? _entryImagesViewModel;
|
||||
|
||||
public PluginDetailsViewModel(IWorkshopClient client,
|
||||
Func<IGetEntryById_Entry, EntryInfoViewModel> getEntryInfoViewModel,
|
||||
Func<IGetEntryById_Entry, EntryReleasesViewModel> getEntryReleasesViewModel,
|
||||
Func<IGetEntryById_Entry, EntryImagesViewModel> getEntryImagesViewModel)
|
||||
{
|
||||
_client = client;
|
||||
_getEntryInfoViewModel = getEntryInfoViewModel;
|
||||
_getEntryReleasesViewModel = getEntryReleasesViewModel;
|
||||
_getEntryImagesViewModel = getEntryImagesViewModel;
|
||||
}
|
||||
|
||||
public override async Task OnNavigating(WorkshopDetailParameters parameters, NavigationArguments args, CancellationToken cancellationToken)
|
||||
{
|
||||
await GetEntry(parameters.EntryId, cancellationToken);
|
||||
}
|
||||
|
||||
private async Task GetEntry(long entryId, CancellationToken cancellationToken)
|
||||
{
|
||||
IOperationResult<IGetEntryByIdResult> result = await _client.GetEntryById.ExecuteAsync(entryId, cancellationToken);
|
||||
if (result.IsErrorResult())
|
||||
return;
|
||||
|
||||
Entry = result.Data?.Entry;
|
||||
if (Entry == null)
|
||||
{
|
||||
EntryInfoViewModel = null;
|
||||
EntryReleasesViewModel = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
EntryInfoViewModel = _getEntryInfoViewModel(Entry);
|
||||
EntryReleasesViewModel = _getEntryReleasesViewModel(Entry);
|
||||
EntryImagesViewModel = _getEntryImagesViewModel(Entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user