Added basic profile list

This commit is contained in:
Robert committed 2023-07-09 12:54:07 +02:00
1 parent 65f81ab768
commit 428bbd73e3
12 files changed
+231 -22

No files matched your search

@@ -0,0 +1,39 @@
<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:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
xmlns:profile="clr-namespace:Artemis.UI.Screens.Workshop.Profile"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="120"
x:Class="Artemis.UI.Screens.Workshop.Profile.ProfileListEntryView"
x:DataType="profile:ProfileListEntryViewModel">
<Border Classes="card">
<Grid ColumnDefinitions="Auto,*,Auto">
<avalonia:MaterialIcon Kind="Abacus" Width="80" Height="80" Margin="0 0 10 0" Grid.Column="0" VerticalAlignment="Center" />
<StackPanel Grid.Column="1" VerticalAlignment="Center">
<TextBlock Classes="h4 no-margin" Text="{CompiledBinding Entry.Name, FallbackValue=Title}"></TextBlock>
<TextBlock Classes="subtitle" Text="{CompiledBinding Entry.Summary, FallbackValue=Summary}"></TextBlock>
<ItemsControl ItemsSource="{CompiledBinding Entry.Categories}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" Spacing="8"></StackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<avalonia:MaterialIcon Kind="{CompiledBinding Icon}" Margin="0 0 3 0"></avalonia:MaterialIcon>
<TextBlock Text="{CompiledBinding Name}"></TextBlock>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
<StackPanel Grid.Column="2">
<TextBlock>Downloads</TextBlock>
<TextBlock>Last updated</TextBlock>
</StackPanel>
</Grid>
</Border>
</UserControl>
@@ -0,0 +1,18 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace Artemis.UI.Screens.Workshop.Profile;
public partial class ProfileListEntryView : UserControl
{
public ProfileListEntryView()
{
InitializeComponent();
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
}
@@ -0,0 +1,14 @@
using Artemis.UI.Shared;
using Artemis.WebClient.Workshop;
namespace Artemis.UI.Screens.Workshop.Profile;
public class ProfileListEntryViewModel : ViewModelBase
{
public ProfileListEntryViewModel(IGetEntries_Entries_Nodes entry)
{
Entry = entry;
}
public IGetEntries_Entries_Nodes Entry { get; }
}
@@ -8,14 +8,22 @@
x:DataType="profile:ProfileListViewModel">
<Border Classes="router-container">
<Grid ColumnDefinitions="300,*" Margin="10">
<Border Classes="card-condensed" Grid.Column="0" Margin="0 0 10 0">
<TextBlock>Side panel</TextBlock>
<Border Classes="card-condensed" Grid.Column="0" Margin="0 0 10 0" VerticalAlignment="Top">
<StackPanel>
<TextBlock Classes="h3">Categories</TextBlock>
<ContentControl Content="{CompiledBinding CategoriesViewModel}"></ContentControl>
</StackPanel>
</Border>
<Border Classes="card-condensed" Grid.Column="1">
<TextBlock>
<Run Text="Profile list main panel, page: " /><Run Text="{CompiledBinding Page}"></Run>
</TextBlock>
<ItemsRepeater ItemsSource="{CompiledBinding Entries}">
<ItemsRepeater.ItemTemplate>
<DataTemplate>
<ContentControl Content="{CompiledBinding}" Margin="0 0 0 5"></ContentControl>
</DataTemplate>
</ItemsRepeater.ItemTemplate>
</ItemsRepeater>
</Border>
</Grid>
</Border>
@@ -1,34 +1,70 @@
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive.Disposables;
using System.Threading;
using System.Threading.Tasks;
using Artemis.UI.Screens.Workshop.Categories;
using Artemis.UI.Screens.Workshop.Parameters;
using Artemis.UI.Screens.Workshop.Search;
using Artemis.UI.Shared;
using Artemis.UI.Shared.Routing;
using Artemis.WebClient.Workshop;
using DynamicData;
using ReactiveUI;
using StrawberryShake;
namespace Artemis.UI.Screens.Workshop.Profile;
public class ProfileListViewModel : RoutableScreen<ActivatableViewModelBase, WorkshopListParameters>, IWorkshopViewModel
{
private readonly SourceList<IGetEntries_Entries_Nodes> _entries;
private readonly IWorkshopClient _workshopClient;
private int _page;
/// <inheritdoc />
public ProfileListViewModel()
public ProfileListViewModel(IWorkshopClient workshopClient, CategoriesViewModel categoriesViewModel)
{
_workshopClient = workshopClient;
CategoriesViewModel = categoriesViewModel;
_entries = new SourceList<IGetEntries_Entries_Nodes>();
_entries.Connect()
.Transform(e => new ProfileListEntryViewModel(e))
.Bind(out ReadOnlyObservableCollection<ProfileListEntryViewModel> observableEntries)
.Subscribe();
Entries = observableEntries;
}
public CategoriesViewModel CategoriesViewModel { get; }
public ReadOnlyObservableCollection<ProfileListEntryViewModel> Entries { get; set; }
public int Page
{
get => _page;
set => RaiseAndSetIfChanged(ref _page, value);
}
public override Task OnNavigating(WorkshopListParameters parameters, NavigationArguments args, CancellationToken cancellationToken)
public override async Task OnNavigating(WorkshopListParameters parameters, NavigationArguments args, CancellationToken cancellationToken)
{
Page = Math.Max(1, parameters.Page);
return Task.CompletedTask;
await GetEntries(cancellationToken);
}
private async Task GetEntries(CancellationToken cancellationToken)
{
IOperationResult<IGetEntriesResult> result = await _workshopClient.GetEntries.ExecuteAsync(CreateFilter(), cancellationToken);
if (result.IsErrorResult() || result.Data?.Entries?.Nodes == null)
return;
_entries.Edit(e =>
{
e.Clear();
e.AddRange(result.Data.Entries.Nodes);
});
}
private EntryFilterInput CreateFilter()
{
return new EntryFilterInput {EntryType = new EntryTypeOperationFilterInput {Eq = WebClient.Workshop.EntryType.Profile}};
}
public EntryType? EntryType => null;