Images WIP

This commit is contained in:
RobertBeekman committed 2023-11-05 21:27:41 +01:00
1 parent 6b4e84c95a
commit 0667d58ed8
56 files changed
+783 -454

No files matched your search

@@ -0,0 +1,24 @@
<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:asyncImageLoader="clr-namespace:AsyncImageLoader;assembly=AsyncImageLoader.Avalonia"
xmlns:details="clr-namespace:Artemis.UI.Screens.Workshop.Entries.Details"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.Workshop.Entries.Details.EntryImageView"
x:DataType="details:EntryImageViewModel">
<Border Classes="card" Padding="0" Width="300" ClipToBounds="True" Margin="0 5 0 0">
<Grid RowDefinitions="230,*">
<Rectangle Grid.Row="0" Fill="{DynamicResource CheckerboardBrush}" />
<Image Grid.Row="0"
VerticalAlignment="Center"
HorizontalAlignment="Center"
RenderOptions.BitmapInterpolationMode="HighQuality"
asyncImageLoader:ImageLoader.Source="{CompiledBinding ThumbnailUrl, Mode=OneWay}" />
<StackPanel Grid.Row="1" Margin="12">
<TextBlock Text="{CompiledBinding Image.Name}" TextTrimming="CharacterEllipsis" />
<TextBlock Classes="subtitle" Text="{CompiledBinding Image.Description}" TextWrapping="Wrap" />
</StackPanel>
</Grid>
</Border>
</UserControl>
@@ -0,0 +1,13 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace Artemis.UI.Screens.Workshop.Entries.Details;
public partial class EntryImageView : UserControl
{
public EntryImageView()
{
InitializeComponent();
}
}
@@ -0,0 +1,17 @@
using Artemis.WebClient.Workshop;
namespace Artemis.UI.Screens.Workshop.Entries.Details;
public class EntryImageViewModel
{
public EntryImageViewModel(IImage image)
{
Image = image;
Url = $"{WorkshopConstants.WORKSHOP_URL}/images/{image.Id}.png";
ThumbnailUrl = $"{WorkshopConstants.WORKSHOP_URL}/images/{image.Id}-thumb.png";
}
public IImage Image { get; }
public string Url { get; }
public string ThumbnailUrl { get; }
}
@@ -0,0 +1,28 @@
<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:system="clr-namespace:System;assembly=System.Runtime"
xmlns:asyncImageLoader="clr-namespace:AsyncImageLoader;assembly=AsyncImageLoader.Avalonia"
xmlns:details="clr-namespace:Artemis.UI.Screens.Workshop.Entries.Details"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.Workshop.Entries.Details.EntryImagesView"
x:DataType="details:EntryImagesViewModel">
<ItemsControl ItemsSource="{CompiledBinding Images}" Margin="0 -16 0 0">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.DataTemplates>
<DataTemplate x:DataType="details:EntryImageViewModel">
<Border CornerRadius="6"
Margin="0 16 0 0"
MaxWidth="300"
ClipToBounds="True">
<Image Stretch="UniformToFill" asyncImageLoader:ImageLoader.Source="{CompiledBinding ThumbnailUrl, Mode=OneWay}" />
</Border>
</DataTemplate>
</ItemsControl.DataTemplates>
</ItemsControl>
</UserControl>
@@ -0,0 +1,13 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace Artemis.UI.Screens.Workshop.Entries.Details;
public partial class EntryImagesView : UserControl
{
public EntryImagesView()
{
InitializeComponent();
}
}
@@ -0,0 +1,16 @@
using System.Collections.ObjectModel;
using System.Linq;
using Artemis.UI.Shared;
using Artemis.WebClient.Workshop;
namespace Artemis.UI.Screens.Workshop.Entries.Details;
public class EntryImagesViewModel : ViewModelBase
{
public ObservableCollection<EntryImageViewModel> Images { get; }
public EntryImagesViewModel(IEntryDetails entryDetails)
{
Images = new ObservableCollection<EntryImageViewModel>(entryDetails.Images.Select(i => new EntryImageViewModel(i)));
}
}
@@ -0,0 +1,83 @@
<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:details="clr-namespace:Artemis.UI.Screens.Workshop.Entries.Details"
xmlns:il="clr-namespace:AsyncImageLoader;assembly=AsyncImageLoader.Avalonia"
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.Workshop.Entries.Details.EntryInfoView"
x:DataType="details:EntryInfoViewModel">
<UserControl.Resources>
<converters:EntryIconUriConverter x:Key="EntryIconUriConverter" />
<converters:DateTimeConverter x:Key="DateTimeConverter" />
</UserControl.Resources>
<StackPanel>
<Panel>
<Border CornerRadius="6"
HorizontalAlignment="Left"
Margin="0 0 10 0"
Width="80"
Height="80"
ClipToBounds="True">
<Image Stretch="UniformToFill" il:ImageLoader.Source="{CompiledBinding Entry.Id, Converter={StaticResource EntryIconUriConverter}, Mode=OneWay}" />
</Border>
<Button Classes="icon-button"
VerticalAlignment="Top"
HorizontalAlignment="Right"
Command="{CompiledBinding CopyShareLink}"
ToolTip.Tip="Copy share link">
<avalonia:MaterialIcon Kind="ShareVariant" />
</Button>
</Panel>
<TextBlock Theme="{StaticResource TitleTextBlockStyle}"
MaxLines="3"
TextTrimming="CharacterEllipsis"
Text="{CompiledBinding Entry.Name, FallbackValue=Title }" />
<TextBlock Classes="subtitle" TextTrimming="CharacterEllipsis" Text="{CompiledBinding Entry.Author, FallbackValue=Author}" />
<TextBlock Margin="0 8" TextWrapping="Wrap" Text="{CompiledBinding Entry.Summary, FallbackValue=Summary}" />
<!-- Categories -->
<ItemsControl ItemsSource="{CompiledBinding Entry.Categories}" Margin="0 0 -8 0">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"></WrapPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="0 0 8 0">
<avalonia:MaterialIcon Kind="{CompiledBinding Icon}" Margin="0 0 3 0"></avalonia:MaterialIcon>
<TextBlock Text="{CompiledBinding Name}" TextTrimming="CharacterEllipsis" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Border Classes="card-separator"></Border>
<TextBlock Margin="0 0 0 8">
<avalonia:MaterialIcon Kind="Downloads" />
<Run Classes="h5" Text="{CompiledBinding Entry.Downloads, FallbackValue=0}" />
<Run>downloads</Run>
</TextBlock>
<TextBlock Classes="subtitle"
ToolTip.Tip="{CompiledBinding Entry.CreatedAt, Converter={StaticResource DateTimeConverter}}">
<avalonia:MaterialIcon Kind="Calendar" />
<Run>Created</Run>
<Run Text="{CompiledBinding Entry.CreatedAt, Converter={StaticResource DateTimeConverter}, ConverterParameter='humanize'}"></Run>
</TextBlock>
<TextBlock Classes="subtitle"
ToolTip.Tip="{CompiledBinding UpdatedAt, Converter={StaticResource DateTimeConverter}}">
<avalonia:MaterialIcon Kind="Update" />
<Run>Updated</Run>
<Run Text="{CompiledBinding UpdatedAt, Converter={StaticResource DateTimeConverter}, ConverterParameter='humanize'}"></Run>
</TextBlock>
</StackPanel>
</UserControl>
@@ -0,0 +1,13 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace Artemis.UI.Screens.Workshop.Entries.Details;
public partial class EntryInfoView : UserControl
{
public EntryInfoView()
{
InitializeComponent();
}
}
@@ -0,0 +1,28 @@
using System;
using System.Threading.Tasks;
using Artemis.Core;
using Artemis.UI.Shared;
using Artemis.UI.Shared.Services;
using Artemis.WebClient.Workshop;
namespace Artemis.UI.Screens.Workshop.Entries.Details;
public class EntryInfoViewModel : ViewModelBase
{
private readonly INotificationService _notificationService;
public IGetEntryById_Entry Entry { get; }
public DateTimeOffset? UpdatedAt { get; }
public EntryInfoViewModel(IGetEntryById_Entry entry, INotificationService notificationService)
{
_notificationService = notificationService;
Entry = entry;
UpdatedAt = Entry.LatestRelease?.CreatedAt ?? Entry.CreatedAt;
}
public async Task CopyShareLink()
{
await Shared.UI.Clipboard.SetTextAsync($"{WorkshopConstants.WORKSHOP_URL}/entries/{Entry.Id}/{StringUtilities.UrlFriendly(Entry.Name)}");
_notificationService.CreateNotification().WithTitle("Copied share link to clipboard.").Show();
}
}
@@ -0,0 +1,52 @@
<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:details="clr-namespace:Artemis.UI.Screens.Workshop.Entries.Details"
xmlns:converters="clr-namespace:Artemis.UI.Converters"
xmlns:sharedConverters="clr-namespace:Artemis.UI.Shared.Converters;assembly=Artemis.UI.Shared"
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.Workshop.Entries.Details.EntryReleasesView"
x:DataType="details:EntryReleasesViewModel">
<UserControl.Resources>
<converters:DateTimeConverter x:Key="DateTimeConverter" />
<sharedConverters:BytesToStringConverter x:Key="BytesToStringConverter" />
</UserControl.Resources>
<StackPanel>
<TextBlock Theme="{StaticResource SubtitleTextBlockStyle}">Latest release</TextBlock>
<Border Classes="card-separator" />
<Button HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
Command="{CompiledBinding DownloadLatestRelease}">
<Grid ColumnDefinitions="Auto,*">
<!-- Icon -->
<Border Grid.Column="0"
CornerRadius="4"
Background="{StaticResource SystemAccentColor}"
VerticalAlignment="Center"
Margin="0 6"
Width="50"
Height="50"
ClipToBounds="True">
<avalonia:MaterialIcon Kind="Download"></avalonia:MaterialIcon>
</Border>
<!-- Body -->
<StackPanel Grid.Column="1" Margin="10 0" VerticalAlignment="Center">
<TextBlock Text="{CompiledBinding Entry.LatestRelease.Version, FallbackValue=Version}"></TextBlock>
<TextBlock Classes="subtitle">
<avalonia:MaterialIcon Kind="BoxOutline" />
<Run Text="{CompiledBinding Entry.LatestRelease.DownloadSize, Converter={StaticResource BytesToStringConverter}, Mode=OneWay}"></Run>
</TextBlock>
<TextBlock Classes="subtitle"
ToolTip.Tip="{CompiledBinding Entry.LatestRelease.CreatedAt, Converter={StaticResource DateTimeConverter}}">
<avalonia:MaterialIcon Kind="Calendar" />
<Run>Created</Run>
<Run Text="{CompiledBinding Entry.LatestRelease.CreatedAt, Converter={StaticResource DateTimeConverter}, ConverterParameter='humanize'}"></Run>
</TextBlock>
</StackPanel>
</Grid>
</Button>
</StackPanel>
</UserControl>
@@ -0,0 +1,13 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace Artemis.UI.Screens.Workshop.Entries.Details;
public partial class EntryReleasesView : UserControl
{
public EntryReleasesView()
{
InitializeComponent();
}
}
@@ -0,0 +1,59 @@
using System;
using System.Reactive;
using System.Threading;
using System.Threading.Tasks;
using Artemis.UI.Shared;
using Artemis.UI.Shared.Services;
using Artemis.UI.Shared.Services.Builders;
using Artemis.UI.Shared.Utilities;
using Artemis.WebClient.Workshop;
using Artemis.WebClient.Workshop.Handlers.InstallationHandlers;
using Humanizer;
using ReactiveUI;
namespace Artemis.UI.Screens.Workshop.Entries.Details;
public class EntryReleasesViewModel : ViewModelBase
{
private readonly EntryInstallationHandlerFactory _factory;
private readonly IWindowService _windowService;
private readonly INotificationService _notificationService;
public EntryReleasesViewModel(IGetEntryById_Entry entry, EntryInstallationHandlerFactory factory, IWindowService windowService, INotificationService notificationService)
{
_factory = factory;
_windowService = windowService;
_notificationService = notificationService;
Entry = entry;
DownloadLatestRelease = ReactiveCommand.CreateFromTask(ExecuteDownloadLatestRelease);
}
public IGetEntryById_Entry Entry { get; }
public ReactiveCommand<Unit, Unit> DownloadLatestRelease { get; }
private async Task ExecuteDownloadLatestRelease(CancellationToken cancellationToken)
{
if (Entry.LatestRelease == null)
return;
bool confirm = await _windowService.ShowConfirmContentDialog(
"Install latest release",
$"Are you sure you want to download and install version {Entry.LatestRelease.Version} of {Entry.Name}?"
);
if (!confirm)
return;
IEntryInstallationHandler installationHandler = _factory.CreateHandler(Entry.EntryType);
EntryInstallResult result = await installationHandler.InstallAsync(Entry, Entry.LatestRelease.Id, new Progress<StreamProgress>(), cancellationToken);
if (result.IsSuccess)
_notificationService.CreateNotification().WithTitle($"{Entry.EntryType.Humanize(LetterCasing.Sentence)} installed").WithSeverity(NotificationSeverity.Success).Show();
else
{
_notificationService.CreateNotification()
.WithTitle($"Failed to install {Entry.EntryType.Humanize(LetterCasing.LowerCase)}")
.WithMessage(result.Message)
.WithSeverity(NotificationSeverity.Error).Show();
}
}
}
@@ -9,9 +9,10 @@
xmlns:avaloniaEdit="https://github.com/avaloniaui/avaloniaedit"
xmlns:mdxaml="https://github.com/whistyun/Markdown.Avalonia.Tight"
xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:details="clr-namespace:Artemis.UI.Screens.Workshop.Entries.Details"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="800"
x:Class="Artemis.UI.Screens.Workshop.Entries.EntrySpecificationsView"
x:DataType="entries:EntrySpecificationsViewModel">
x:Class="Artemis.UI.Screens.Workshop.Entries.Details.EntrySpecificationsView"
x:DataType="details:EntrySpecificationsViewModel">
<Grid RowDefinitions="Auto,Auto,*,Auto">
<StackPanel>
<StackPanel.Styles>
@@ -1,5 +1,4 @@
using System.Linq;
using Artemis.UI.Shared.Extensions;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Media;
@@ -8,8 +7,9 @@ using Avalonia.ReactiveUI;
using AvaloniaEdit.TextMate;
using ReactiveUI;
using TextMateSharp.Grammars;
using VisualExtensions = Artemis.UI.Shared.Extensions.VisualExtensions;
namespace Artemis.UI.Screens.Workshop.Entries;
namespace Artemis.UI.Screens.Workshop.Entries.Details;
public partial class EntrySpecificationsView : ReactiveUserControl<EntrySpecificationsViewModel>
{
@@ -23,7 +23,7 @@ public partial class EntrySpecificationsView : ReactiveUserControl<EntrySpecific
DescriptionEditor.Options.AllowScrollBelowDocument = false;
RegistryOptions options = new(ThemeName.Dark);
TextMate.Installation? install = DescriptionEditor.InstallTextMate(options);
TextMate.Installation? install = TextMate.InstallTextMate(DescriptionEditor, options);
install.SetGrammar(options.GetScopeByExtension(".md"));
@@ -45,8 +45,8 @@ public partial class EntrySpecificationsView : ReactiveUserControl<EntrySpecific
if (_previewScrollViewer != null)
_previewScrollViewer.PropertyChanged -= PreviewScrollViewerOnPropertyChanged;
_editorScrollViewer = DescriptionEditor.GetVisualChildrenOfType<ScrollViewer>().FirstOrDefault();
_previewScrollViewer = DescriptionPreview.GetVisualChildrenOfType<ScrollViewer>().FirstOrDefault();
_editorScrollViewer = VisualExtensions.GetVisualChildrenOfType<ScrollViewer>(DescriptionEditor).FirstOrDefault();
_previewScrollViewer = VisualExtensions.GetVisualChildrenOfType<ScrollViewer>(DescriptionPreview).FirstOrDefault();
if (_editorScrollViewer != null)
_editorScrollViewer.PropertyChanged += EditorScrollViewerOnPropertyChanged;
@@ -22,7 +22,7 @@ using ReactiveUI.Validation.Extensions;
using ReactiveUI.Validation.Helpers;
using StrawberryShake;
namespace Artemis.UI.Screens.Workshop.Entries;
namespace Artemis.UI.Screens.Workshop.Entries.Details;
public partial class EntrySpecificationsViewModel : ValidatableViewModelBase
{
@@ -52,12 +52,12 @@ public partial class EntrySpecificationsViewModel : ValidatableViewModelBase
.Subscribe();
SelectedCategories = selectedCategories;
this.ValidationRule(vm => vm.Name, s => !string.IsNullOrWhiteSpace(s), "Name is required");
this.ValidationRule(vm => vm.Summary, s => !string.IsNullOrWhiteSpace(s), "Summary is required");
ValidationHelper descriptionRule = this.ValidationRule(vm => vm.Description, s => !string.IsNullOrWhiteSpace(s), "Description is required");
this.ValidationRule<EntrySpecificationsViewModel, string>(vm => vm.Name, s => !string.IsNullOrWhiteSpace(s), "Name is required");
this.ValidationRule<EntrySpecificationsViewModel, string>(vm => vm.Summary, s => !string.IsNullOrWhiteSpace(s), "Summary is required");
ValidationHelper descriptionRule = this.ValidationRule<EntrySpecificationsViewModel, string>(vm => vm.Description, s => !string.IsNullOrWhiteSpace(s), "Description is required");
// These don't use inputs that support validation messages, do so manually
ValidationHelper iconRule = this.ValidationRule(vm => vm.IconBitmap, s => s != null, "Icon required");
ValidationHelper iconRule = this.ValidationRule<EntrySpecificationsViewModel, Bitmap>(vm => vm.IconBitmap, s => s != null, "Icon required");
ValidationHelper categoriesRule = this.ValidationRule(vm => vm.Categories, Categories.ToObservableChangeSet().AutoRefresh(c => c.IsSelected).Filter(c => c.IsSelected).IsNotEmpty(),
"At least one category must be selected"
);
@@ -1,8 +0,0 @@
<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"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.Workshop.Entries.EntryInstallationDialogView">
Welcome to Avalonia!
</UserControl>
@@ -1,13 +0,0 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace Artemis.UI.Screens.Workshop.Entries;
public partial class EntryInstallationDialogView : UserControl
{
public EntryInstallationDialogView()
{
InitializeComponent();
}
}
@@ -1,8 +0,0 @@
using Artemis.UI.Shared;
namespace Artemis.UI.Screens.Workshop.Entries;
public class EntryInstallationDialogViewModel : ContentDialogViewModelBase
{
}
@@ -4,9 +4,10 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:entries="clr-namespace:Artemis.UI.Screens.Workshop.Entries"
xmlns:system="clr-namespace:System;assembly=System.Runtime"
xmlns:list="clr-namespace:Artemis.UI.Screens.Workshop.Entries.List"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.Workshop.Entries.EntryListInputView"
x:DataType="entries:EntryListInputViewModel">
x:Class="Artemis.UI.Screens.Workshop.Entries.List.EntryListInputView"
x:DataType="list:EntryListInputViewModel">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" MaxWidth="500" />
@@ -1,8 +1,6 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace Artemis.UI.Screens.Workshop.Entries;
namespace Artemis.UI.Screens.Workshop.Entries.List;
public partial class EntryListInputView : UserControl
{
@@ -4,7 +4,7 @@ using Artemis.UI.Shared;
using PropertyChanged.SourceGenerator;
using ReactiveUI;
namespace Artemis.UI.Screens.Workshop.Entries;
namespace Artemis.UI.Screens.Workshop.Entries.List;
public partial class EntryListInputViewModel : ViewModelBase
{
@@ -6,9 +6,10 @@
xmlns:entries1="clr-namespace:Artemis.UI.Screens.Workshop.Entries"
xmlns:il="clr-namespace:AsyncImageLoader;assembly=AsyncImageLoader.Avalonia"
xmlns:converters="clr-namespace:Artemis.UI.Converters"
xmlns:list="clr-namespace:Artemis.UI.Screens.Workshop.Entries.List"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="110"
x:Class="Artemis.UI.Screens.Workshop.Entries.EntryListItemView"
x:DataType="entries1:EntryListItemViewModel">
x:Class="Artemis.UI.Screens.Workshop.Entries.List.EntryListItemView"
x:DataType="list:EntryListItemViewModel">
<UserControl.Resources>
<converters:EntryIconUriConverter x:Key="EntryIconUriConverter" />
<converters:DateTimeConverter x:Key="DateTimeConverter" />
@@ -1,6 +1,6 @@
using Avalonia.ReactiveUI;
namespace Artemis.UI.Screens.Workshop.Entries;
namespace Artemis.UI.Screens.Workshop.Entries.List;
public partial class EntryListItemView : ReactiveUserControl<EntryListItemViewModel>
{
@@ -1,17 +1,12 @@
using System;
using System.Reactive;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Threading;
using System.Threading.Tasks;
using Artemis.UI.Shared;
using Artemis.UI.Shared.Routing;
using Artemis.WebClient.Workshop;
using Artemis.WebClient.Workshop.Services;
using Avalonia.Media.Imaging;
using ReactiveUI;
namespace Artemis.UI.Screens.Workshop.Entries;
namespace Artemis.UI.Screens.Workshop.Entries.List;
public class EntryListItemViewModel : ActivatableViewModelBase
{
@@ -17,7 +17,7 @@ using PropertyChanged.SourceGenerator;
using ReactiveUI;
using StrawberryShake;
namespace Artemis.UI.Screens.Workshop.Entries;
namespace Artemis.UI.Screens.Workshop.Entries.List;
public abstract partial class EntryListViewModel : RoutableScreen<WorkshopListParameters>
{
@@ -42,8 +42,8 @@ public abstract partial class EntryListViewModel : RoutableScreen<WorkshopListPa
_route = route;
_workshopClient = workshopClient;
_notificationService = notificationService;
_showPagination = this.WhenAnyValue(vm => vm.TotalPages).Select(t => t > 1).ToProperty(this, vm => vm.ShowPagination);
_isLoading = this.WhenAnyValue(vm => vm.Page, vm => vm.LoadedPage, (p, c) => p != c).ToProperty(this, vm => vm.IsLoading);
_showPagination = this.WhenAnyValue<EntryListViewModel, int>(vm => vm.TotalPages).Select(t => t > 1).ToProperty(this, vm => vm.ShowPagination);
_isLoading = this.WhenAnyValue<EntryListViewModel, bool, int, int>(vm => vm.Page, vm => vm.LoadedPage, (p, c) => p != c).ToProperty(this, vm => vm.IsLoading);
CategoriesViewModel = categoriesViewModel;
InputViewModel = entryListInputViewModel;
@@ -56,7 +56,7 @@ public abstract partial class EntryListViewModel : RoutableScreen<WorkshopListPa
Entries = entries;
// Respond to page changes
this.WhenAnyValue(vm => vm.Page).Skip(1).Subscribe(p => Task.Run(() => router.Navigate($"{_route}/{p}")));
this.WhenAnyValue<EntryListViewModel, int>(vm => vm.Page).Skip(1).Subscribe(p => Task.Run(() => router.Navigate($"{_route}/{p}")));
this.WhenActivated(d =>
{
@@ -1,17 +1,18 @@
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 LayoutListViewModel : EntryListViewModel
public class LayoutListViewModel : List.EntryListViewModel
{
public LayoutListViewModel(IWorkshopClient workshopClient,
IRouter router,
CategoriesViewModel categoriesViewModel,
EntryListInputViewModel entryListInputViewModel,
List.EntryListInputViewModel entryListInputViewModel,
INotificationService notificationService,
Func<IGetEntries_Entries_Items, EntryListItemViewModel> getEntryListViewModel)
: base("workshop/entries/layout", workshopClient, router, categoriesViewModel, entryListInputViewModel, notificationService, getEntryListViewModel)
@@ -1,17 +1,18 @@
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 ProfileListViewModel : EntryListViewModel
public class ProfileListViewModel : List.EntryListViewModel
{
public ProfileListViewModel(IWorkshopClient workshopClient,
IRouter router,
CategoriesViewModel categoriesViewModel,
EntryListInputViewModel entryListInputViewModel,
List.EntryListInputViewModel entryListInputViewModel,
INotificationService notificationService,
Func<IGetEntries_Entries_Items, EntryListItemViewModel> getEntryListViewModel)
: base("workshop/entries/profiles", workshopClient, router, categoriesViewModel, entryListInputViewModel, notificationService, getEntryListViewModel)