mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-12 11:56:30 +00:00
Workshop Library - Added library pages
UI - Tweaked design to more closely match WinUI 3 gallery examples
This commit is contained in:
1 parent
e545d2f3da
commit
9c6d7329a6
25 files changed
+519
-288
No files matched your search
@@ -2,7 +2,67 @@
|
||||
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.Library.Tabs.LibrarySubmissionsView">
|
||||
Submission management here 😗
|
||||
</UserControl>
|
||||
xmlns:tabs="clr-namespace:Artemis.UI.Screens.Workshop.Library.Tabs"
|
||||
xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||
xmlns:workshop="clr-namespace:Artemis.WebClient.Workshop;assembly=Artemis.WebClient.Workshop"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="650"
|
||||
x:Class="Artemis.UI.Screens.Workshop.Library.Tabs.LibrarySubmissionsView"
|
||||
x:DataType="tabs:LibrarySubmissionsViewModel">
|
||||
<UserControl.Resources>
|
||||
<controls:SymbolIconSource x:Key="GoIcon" Symbol="ChevronRight" />
|
||||
</UserControl.Resources>
|
||||
|
||||
<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>
|
||||
|
||||
<Panel IsVisible="{CompiledBinding !IsLoading}">
|
||||
<StackPanel IsVisible="{CompiledBinding !IsLoggedIn^}" Margin="0 50 0 0" Classes="empty-state">
|
||||
<TextBlock Theme="{StaticResource TitleTextBlockStyle}">You are not logged in</TextBlock>
|
||||
<TextBlock>
|
||||
<Run>In order to manage your submissions you must be logged in.</Run>
|
||||
</TextBlock>
|
||||
<Lottie Path="/Assets/Animations/login-pending.json" RepeatCount="1" Width="350" Height="350"></Lottie>
|
||||
<Button HorizontalAlignment="Center" Command="{CompiledBinding Login}">Log in</Button>
|
||||
</StackPanel>
|
||||
|
||||
<Panel IsVisible="{CompiledBinding IsLoggedIn^}">
|
||||
<StackPanel IsVisible="{CompiledBinding !Entries.Count}" Margin="0 50 0 0" Classes="empty-state">
|
||||
<TextBlock Theme="{StaticResource TitleTextBlockStyle}">Oh boy, it's empty here 🤔</TextBlock>
|
||||
<TextBlock>
|
||||
<Run>Any entries you submit to the workshop you can later manage here</Run>
|
||||
</TextBlock>
|
||||
<Lottie Path="/Assets/Animations/empty.json" RepeatCount="1" Width="350" Height="350"></Lottie>
|
||||
<Button HorizontalAlignment="Center" Command="{CompiledBinding AddSubmission}">Submit new entry</Button>
|
||||
</StackPanel>
|
||||
|
||||
<ItemsRepeater IsVisible="{CompiledBinding Entries.Count}" ItemsSource="{CompiledBinding Entries}">
|
||||
<ItemsRepeater.ItemTemplate>
|
||||
<DataTemplate DataType="workshop:IGetSubmittedEntries_SubmittedEntries">
|
||||
<controls:SettingsExpander
|
||||
Header="{CompiledBinding Name}"
|
||||
Description="{CompiledBinding Summary}"
|
||||
IsClickEnabled="True"
|
||||
ActionIconSource="{StaticResource GoIcon}"
|
||||
Command="{Binding $parent[tabs:LibrarySubmissionsView].DataContext.NavigateToEntry}"
|
||||
CommandParameter="{CompiledBinding}">
|
||||
<controls:SettingsExpander.FooterTemplate>
|
||||
<DataTemplate x:DataType="workshop:IGetSubmittedEntries_SubmittedEntries">
|
||||
<Border Classes="badge" VerticalAlignment="Top" Margin="0 5 0 0">
|
||||
<TextBlock Text="{CompiledBinding EntryType}"></TextBlock>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</controls:SettingsExpander.FooterTemplate>
|
||||
</controls:SettingsExpander>
|
||||
</DataTemplate>
|
||||
</ItemsRepeater.ItemTemplate>
|
||||
</ItemsRepeater>
|
||||
</Panel>
|
||||
</Panel>
|
||||
|
||||
</UserControl>
|
||||
@@ -1,8 +1,108 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Reactive;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Artemis.UI.Extensions;
|
||||
using Artemis.UI.Screens.Workshop.CurrentUser;
|
||||
using Artemis.UI.Screens.Workshop.SubmissionWizard;
|
||||
using Artemis.UI.Shared;
|
||||
using Artemis.UI.Shared.Routing;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using Artemis.WebClient.Workshop;
|
||||
using Artemis.WebClient.Workshop.Services;
|
||||
using DynamicData;
|
||||
using ReactiveUI;
|
||||
using StrawberryShake;
|
||||
|
||||
namespace Artemis.UI.Screens.Workshop.Library.Tabs;
|
||||
|
||||
public class LibrarySubmissionsViewModel : ActivatableViewModelBase
|
||||
public class LibrarySubmissionsViewModel : ActivatableViewModelBase, IWorkshopViewModel
|
||||
{
|
||||
|
||||
private readonly IWorkshopClient _client;
|
||||
private readonly SourceCache<IGetSubmittedEntries_SubmittedEntries, Guid> _entries;
|
||||
private readonly IWindowService _windowService;
|
||||
private bool _isLoading = true;
|
||||
private bool _workshopReachable;
|
||||
|
||||
public LibrarySubmissionsViewModel(IWorkshopClient client, IAuthenticationService authenticationService, IWindowService windowService, IWorkshopService workshopService, IRouter router)
|
||||
{
|
||||
_client = client;
|
||||
_windowService = windowService;
|
||||
_entries = new SourceCache<IGetSubmittedEntries_SubmittedEntries, Guid>(e => e.Id);
|
||||
_entries.Connect().Bind(out ReadOnlyObservableCollection<IGetSubmittedEntries_SubmittedEntries> entries).Subscribe();
|
||||
|
||||
AddSubmission = ReactiveCommand.CreateFromTask(ExecuteAddSubmission, this.WhenAnyValue(vm => vm.WorkshopReachable));
|
||||
Login = ReactiveCommand.CreateFromTask(ExecuteLogin, this.WhenAnyValue(vm => vm.WorkshopReachable));
|
||||
NavigateToEntry = ReactiveCommand.CreateFromTask<IGetSubmittedEntries_SubmittedEntries>(ExecuteNavigateToEntry);
|
||||
|
||||
IsLoggedIn = authenticationService.IsLoggedIn;
|
||||
Entries = entries;
|
||||
|
||||
this.WhenActivatedAsync(async d =>
|
||||
{
|
||||
WorkshopReachable = await workshopService.ValidateWorkshopStatus(d.AsCancellationToken());
|
||||
if (WorkshopReachable)
|
||||
await GetEntries(d.AsCancellationToken());
|
||||
});
|
||||
}
|
||||
|
||||
public ReactiveCommand<Unit, Unit> Login { get; }
|
||||
public ReactiveCommand<Unit, Unit> AddSubmission { get; }
|
||||
public ReactiveCommand<IGetSubmittedEntries_SubmittedEntries, Unit> NavigateToEntry { get; }
|
||||
|
||||
public IObservable<bool> IsLoggedIn { get; }
|
||||
public ReadOnlyObservableCollection<IGetSubmittedEntries_SubmittedEntries> Entries { get; }
|
||||
|
||||
public bool WorkshopReachable
|
||||
{
|
||||
get => _workshopReachable;
|
||||
set => RaiseAndSetIfChanged(ref _workshopReachable, value);
|
||||
}
|
||||
|
||||
public bool IsLoading
|
||||
{
|
||||
get => _isLoading;
|
||||
set => RaiseAndSetIfChanged(ref _isLoading, value);
|
||||
}
|
||||
|
||||
private async Task ExecuteLogin(CancellationToken ct)
|
||||
{
|
||||
await _windowService.CreateContentDialog().WithViewModel(out WorkshopLoginViewModel _).WithTitle("Workshop login").ShowAsync();
|
||||
}
|
||||
|
||||
private async Task ExecuteAddSubmission(CancellationToken arg)
|
||||
{
|
||||
await _windowService.ShowDialogAsync<SubmissionWizardViewModel, bool>();
|
||||
}
|
||||
|
||||
private Task ExecuteNavigateToEntry(IGetSubmittedEntries_SubmittedEntries entry, CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task GetEntries(CancellationToken ct)
|
||||
{
|
||||
IsLoading = true;
|
||||
|
||||
try
|
||||
{
|
||||
IOperationResult<IGetSubmittedEntriesResult> result = await _client.GetSubmittedEntries.ExecuteAsync(null, ct);
|
||||
|
||||
if (result.Data?.SubmittedEntries == null)
|
||||
_entries.Clear();
|
||||
else
|
||||
_entries.Edit(e =>
|
||||
{
|
||||
e.Clear();
|
||||
e.AddOrUpdate(result.Data.SubmittedEntries);
|
||||
});
|
||||
}
|
||||
finally
|
||||
{
|
||||
IsLoading = false;
|
||||
}
|
||||
}
|
||||
|
||||
public EntryType? EntryType => null;
|
||||
}
|
||||
@@ -2,26 +2,25 @@
|
||||
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:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||
xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||
xmlns:library="clr-namespace:Artemis.UI.Screens.Workshop.Library"
|
||||
xmlns:routing="clr-namespace:Artemis.UI.Routing"
|
||||
xmlns:ui1="clr-namespace:Artemis.UI"
|
||||
xmlns:ui="clr-namespace:Artemis.UI"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Artemis.UI.Screens.Workshop.Library.WorkshopLibraryView"
|
||||
x:DataType="library:WorkshopLibraryViewModel">
|
||||
<ui:NavigationView PaneDisplayMode="Top" MenuItemsSource="{CompiledBinding Tabs}" SelectedItem="{CompiledBinding SelectedTab}">
|
||||
<ui:NavigationView.Styles>
|
||||
<controls:NavigationView PaneDisplayMode="Top" MenuItemsSource="{CompiledBinding Tabs}" SelectedItem="{CompiledBinding SelectedTab}">
|
||||
<controls:NavigationView.Styles>
|
||||
<Styles>
|
||||
<Style Selector="ui|NavigationView:topnavminimal /template/ SplitView Border#ContentGridBorder">
|
||||
<Style Selector="controls|NavigationView:topnavminimal /template/ SplitView Border#ContentGridBorder">
|
||||
<Setter Property="CornerRadius" Value="8 0 0 0" />
|
||||
</Style>
|
||||
</Styles>
|
||||
</ui:NavigationView.Styles>
|
||||
</controls:NavigationView.Styles>
|
||||
|
||||
<ui:Frame Name="TabFrame" IsNavigationStackEnabled="False" CacheSize="0">
|
||||
<ui:Frame.NavigationPageFactory>
|
||||
<ui1:PageFactory/>
|
||||
</ui:Frame.NavigationPageFactory>
|
||||
</ui:Frame>
|
||||
</ui:NavigationView>
|
||||
<controls:Frame Name="TabFrame" IsNavigationStackEnabled="False" CacheSize="0" Padding="20">
|
||||
<controls:Frame.NavigationPageFactory>
|
||||
<ui:PageFactory/>
|
||||
</controls:Frame.NavigationPageFactory>
|
||||
</controls:Frame>
|
||||
</controls:NavigationView>
|
||||
</UserControl>
|
||||
@@ -21,17 +21,18 @@ public partial class WorkshopLibraryView : ReactiveUserControl<WorkshopLibraryVi
|
||||
|
||||
private void Navigate(ViewModelBase viewModel)
|
||||
{
|
||||
Dispatcher.UIThread.Invoke(() =>
|
||||
{
|
||||
if (ViewModel == null)
|
||||
return;
|
||||
|
||||
SlideNavigationTransitionInfo transitionInfo = new()
|
||||
{
|
||||
Effect = ViewModel.Tabs.IndexOf(ViewModel.SelectedTab) > _lastIndex ? SlideNavigationTransitionEffect.FromRight : SlideNavigationTransitionEffect.FromLeft
|
||||
};
|
||||
TabFrame.NavigateFromObject(viewModel, new FrameNavigationOptions {TransitionInfoOverride = transitionInfo});
|
||||
_lastIndex = ViewModel.Tabs.IndexOf(ViewModel.SelectedTab);
|
||||
});
|
||||
Dispatcher.UIThread.Invoke(() => TabFrame.NavigateFromObject(viewModel, new FrameNavigationOptions {TransitionInfoOverride = GetTransitionInfo()}));
|
||||
}
|
||||
|
||||
private SlideNavigationTransitionInfo GetTransitionInfo()
|
||||
{
|
||||
if (ViewModel?.SelectedTab == null)
|
||||
return new SlideNavigationTransitionInfo();
|
||||
|
||||
SlideNavigationTransitionEffect effect = ViewModel.Tabs.IndexOf(ViewModel.SelectedTab) > _lastIndex ? SlideNavigationTransitionEffect.FromRight : SlideNavigationTransitionEffect.FromLeft;
|
||||
SlideNavigationTransitionInfo info = new() {Effect = effect};
|
||||
_lastIndex = ViewModel.Tabs.IndexOf(ViewModel.SelectedTab);
|
||||
|
||||
return info;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user