Submission wizard - Added adaption hint and entry details steps

This commit is contained in:
Robert committed 2023-08-11 14:43:35 +02:00
1 parent d2b8123a30
commit e1f0ccbcc1
16 files changed
+195 -30

No files matched your search

@@ -0,0 +1,33 @@
<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:steps="clr-namespace:Artemis.UI.Screens.Workshop.SubmissionWizard.Steps"
mc:Ignorable="d" d:DesignWidth="970" d:DesignHeight="625"
x:Class="Artemis.UI.Screens.Workshop.SubmissionWizard.Steps.EntrySpecificationsStepView"
x:DataType="steps:EntrySpecificationsStepViewModel">
<StackPanel>
<StackPanel.Styles>
<Styles>
<Style Selector="TextBlock">
<Setter Property="TextWrapping" Value="Wrap"></Setter>
</Style>
</Styles>
</StackPanel.Styles>
<TextBlock Theme="{StaticResource TitleTextBlockStyle}" TextWrapping="Wrap" Text="{CompiledBinding DisplayName, FallbackValue=Information}"/>
<TextBlock TextWrapping="Wrap">
Provide some general information on your submission below.
</TextBlock>
<Label Target="Name" Margin="0 15 0 0">Name</Label>
<TextBox Name="Name" Text="{CompiledBinding Name}"></TextBox>
<Label Target="Summary" Margin="0 5 0 0">Summary</Label>
<TextBox Name="Summary" Text="{CompiledBinding Summary}"></TextBox>
<TextBlock Theme="{StaticResource CaptionTextBlockStyle}">A short summary of your submission's description</TextBlock>
<Label Target="Description" Margin="0 5 0 0">Description</Label>
<TextBox AcceptsReturn="True" Name="Description" Text="{CompiledBinding Description}" Height="250"></TextBox>
<TextBlock Theme="{StaticResource CaptionTextBlockStyle}">The main description, Markdown supported. (A better editor planned)</TextBlock>
</StackPanel>
</UserControl>
@@ -0,0 +1,19 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
namespace Artemis.UI.Screens.Workshop.SubmissionWizard.Steps;
public partial class EntrySpecificationsStepView : ReactiveUserControl<EntrySpecificationsStepViewModel>
{
public EntrySpecificationsStepView()
{
InitializeComponent();
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
}
@@ -0,0 +1,83 @@
using System;
using System.Reactive;
using System.Reactive.Disposables;
using Artemis.UI.Screens.Workshop.SubmissionWizard.Steps.Profile;
using Artemis.WebClient.Workshop;
using ReactiveUI;
using ReactiveUI.Validation.Extensions;
namespace Artemis.UI.Screens.Workshop.SubmissionWizard.Steps;
public class EntrySpecificationsStepViewModel : SubmissionViewModel
{
private string _name = string.Empty;
private string _summary = string.Empty;
private string _description = string.Empty;
public EntrySpecificationsStepViewModel()
{
GoBack = ReactiveCommand.Create(ExecuteGoBack);
Continue = ReactiveCommand.Create(ExecuteContinue, ValidationContext.Valid);
this.WhenActivated((CompositeDisposable _) =>
{
this.ClearValidationRules();
DisplayName = $"{State.EntryType} Information";
Name = State.Name;
Summary = State.Summary;
Description = State.Description;
});
}
public override ReactiveCommand<Unit, Unit> Continue { get; }
public override ReactiveCommand<Unit, Unit> GoBack { get; }
public string Name
{
get => _name;
set => RaiseAndSetIfChanged(ref _name, value);
}
public string Summary
{
get => _summary;
set => RaiseAndSetIfChanged(ref _summary, value);
}
public string Description
{
get => _description;
set => RaiseAndSetIfChanged(ref _description, value);
}
private void ExecuteGoBack()
{
switch (State.EntryType)
{
case EntryType.Layout:
break;
case EntryType.Plugin:
break;
case EntryType.Profile:
State.ChangeScreen<ProfileAdaptionHintsStepViewModel>();
break;
default:
throw new ArgumentOutOfRangeException();
}
}
private void ExecuteContinue()
{
this.ValidationRule(vm => vm.Name, s => !string.IsNullOrWhiteSpace(s), "Name cannot be empty.");
this.ValidationRule(vm => vm.Summary, s => !string.IsNullOrWhiteSpace(s), "Summary cannot be empty.");
this.ValidationRule(vm => vm.Description, s => !string.IsNullOrWhiteSpace(s), "Description cannot be empty.");
if (!ValidationContext.IsValid)
return;
State.Name = Name;
State.Summary = Summary;
State.Description = Description;
}
}
@@ -62,5 +62,6 @@ public class ProfileAdaptionHintsStepViewModel : SubmissionViewModel
if (Layers.Any(l => l.AdaptionHintCount == 0))
return;
State.ChangeScreen<EntrySpecificationsStepViewModel>();
}
}
@@ -26,6 +26,9 @@ public class ProfileSelectionStepViewModel : SubmissionViewModel
// Use copies of the profiles, the originals are used by the core and could be disposed
Profiles = new ObservableCollection<ProfileConfiguration>(_profileService.ProfileConfigurations.Select(_profileService.CloneProfileConfiguration));
foreach (ProfileConfiguration profileConfiguration in Profiles)
_profileService.LoadProfileConfigurationIcon(profileConfiguration);
ProfilePreview = profilePreviewViewModel;
GoBack = ReactiveCommand.Create(() => State.ChangeScreen<EntryTypeViewModel>());
@@ -27,12 +27,21 @@
<Lottie Path="/Assets/Animations/email.json" RepeatCount="-1" Width="200" Height="200"></Lottie>
<Button Margin="0 0 0 15" HorizontalAlignment="Center" Command="{CompiledBinding Refresh}">
<StackPanel Orientation="Horizontal" Spacing="5">
<avalonia:MaterialIcon Kind="Refresh" />
<TextBlock>Refresh</TextBlock>
</StackPanel>
</Button>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Spacing="5">
<Button Margin="0 0 0 15" HorizontalAlignment="Center" Command="{CompiledBinding Refresh}">
<StackPanel Orientation="Horizontal" Spacing="5">
<avalonia:MaterialIcon Kind="Refresh" />
<TextBlock>Refresh</TextBlock>
</StackPanel>
</Button>
<Button Margin="0 0 0 15" HorizontalAlignment="Center" Command="{CompiledBinding Resend}">
<StackPanel Orientation="Horizontal" Spacing="5">
<avalonia:MaterialIcon Kind="Mail" />
<TextBlock>Resend confirmation mail</TextBlock>
</StackPanel>
</Button>
</StackPanel>
<TextBlock Theme="{StaticResource CaptionTextBlockStyle}">
PS: We take this step to avoid the workshop getting spammed with low quality content.
@@ -1,10 +1,13 @@
using System;
using System.Diagnostics;
using System.Linq;
using System.Reactive;
using System.Reactive.Disposables;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
using Artemis.Core;
using Artemis.WebClient.Workshop;
using Artemis.WebClient.Workshop.Services;
using IdentityModel;
using ReactiveUI;
@@ -23,6 +26,8 @@ public class ValidateEmailStepViewModel : SubmissionViewModel
Continue = ReactiveCommand.Create(ExecuteContinue);
Refresh = ReactiveCommand.CreateFromTask(ExecuteRefresh);
Resend = ReactiveCommand.Create(() => Utilities.OpenUrl(WorkshopConstants.AUTHORITY_URL + "/account/confirm/resend"));
ShowGoBack = false;
ShowHeader = false;
@@ -45,6 +50,7 @@ public class ValidateEmailStepViewModel : SubmissionViewModel
public override ReactiveCommand<Unit, Unit> GoBack { get; } = null!;
public ReactiveCommand<Unit, Unit> Refresh { get; }
public ReactiveCommand<Unit, Process?> Resend { get; }
public Claim? Email => _email?.Value;
@@ -4,7 +4,7 @@ using ReactiveUI;
namespace Artemis.UI.Screens.Workshop.SubmissionWizard;
public abstract class SubmissionViewModel : ActivatableViewModelBase
public abstract class SubmissionViewModel : ValidatableViewModelBase
{
private string _continueText = "Continue";
private bool _showFinish;
@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using Artemis.UI.Shared.Services;
using Artemis.WebClient.Workshop;
using DryIoc;
@@ -8,12 +10,14 @@ namespace Artemis.UI.Screens.Workshop.SubmissionWizard;
public class SubmissionWizardState
{
private readonly IContainer _container;
private readonly IWindowService _windowService;
private readonly SubmissionWizardViewModel _wizardViewModel;
public SubmissionWizardState(SubmissionWizardViewModel wizardViewModel, IContainer container)
public SubmissionWizardState(SubmissionWizardViewModel wizardViewModel, IContainer container, IWindowService windowService)
{
_wizardViewModel = wizardViewModel;
_container = container;
_windowService = windowService;
}
public EntryType EntryType { get; set; }
@@ -31,6 +35,13 @@ public class SubmissionWizardState
public void ChangeScreen<TSubmissionViewModel>() where TSubmissionViewModel : SubmissionViewModel
{
_wizardViewModel.Screen = _container.Resolve<TSubmissionViewModel>();
try
{
_wizardViewModel.Screen = _container.Resolve<TSubmissionViewModel>();
}
catch (Exception e)
{
_windowService.ShowExceptionDialog("Wizard screen failed to activate", e);
}
}
}
@@ -25,9 +25,9 @@ public partial class SubmissionWizardView : ReactiveAppWindow<SubmissionWizardVi
{
Dispatcher.UIThread.Invoke(() => Frame.NavigateFromObject(viewModel));
}
catch (Exception)
catch (Exception e)
{
// ignored
ViewModel?.WindowService.ShowExceptionDialog("Wizard screen failed to activate", e);
}
}
}
@@ -1,6 +1,7 @@
using Artemis.UI.Screens.Workshop.CurrentUser;
using Artemis.UI.Screens.Workshop.SubmissionWizard.Steps;
using Artemis.UI.Shared;
using Artemis.UI.Shared.Services;
using DryIoc;
namespace Artemis.UI.Screens.Workshop.SubmissionWizard;
@@ -10,17 +11,19 @@ public class SubmissionWizardViewModel : DialogViewModelBase<bool>
private readonly SubmissionWizardState _state;
private SubmissionViewModel _screen;
public SubmissionWizardViewModel(IContainer container, CurrentUserViewModel currentUserViewModel, WelcomeStepViewModel welcomeStepViewModel)
public SubmissionWizardViewModel(IContainer container, IWindowService windowService, CurrentUserViewModel currentUserViewModel, WelcomeStepViewModel welcomeStepViewModel)
{
_state = new SubmissionWizardState(this, container);
_state = new SubmissionWizardState(this, container, windowService);
_screen = welcomeStepViewModel;
_screen.WizardViewModel = this;
_screen.State = _state;
WindowService = windowService;
CurrentUserViewModel = currentUserViewModel;
CurrentUserViewModel.AllowLogout = false;
}
public IWindowService WindowService { get; }
public CurrentUserViewModel CurrentUserViewModel { get; }
public SubmissionViewModel Screen