Submission wizard - Added Lottie animations and the first few steps

This commit is contained in:
Robert committed 2023-08-09 11:54:35 +02:00
1 parent 661242ebf9
commit 78cb95aabc
29 files changed
+534 -153

No files matched your search

@@ -0,0 +1,48 @@
<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"
xmlns:workshop="clr-namespace:Artemis.WebClient.Workshop;assembly=Artemis.WebClient.Workshop"
xmlns:converters="clr-namespace:Artemis.UI.Shared.Converters;assembly=Artemis.UI.Shared"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.Workshop.SubmissionWizard.Steps.EntryTypeView"
x:DataType="steps:EntryTypeViewModel">
<UserControl.Resources>
<converters:EnumToBooleanConverter x:Key="EnumBoolConverter" />
</UserControl.Resources>
<StackPanel>
<StackPanel.Styles>
<Styles>
<Style Selector="TextBlock">
<Setter Property="TextWrapping" Value="Wrap"></Setter>
</Style>
</Styles>
</StackPanel.Styles>
<TextBlock Theme="{StaticResource TitleTextBlockStyle}" TextWrapping="Wrap">
Submission type
</TextBlock>
<TextBlock TextWrapping="Wrap">
Please select the type of content you want to submit to the workshop.
</TextBlock>
<RadioButton GroupName="EntryType"
Margin="0 15 0 0"
IsChecked="{CompiledBinding SelectedEntryType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static workshop:EntryType.Profile}}" >
<RadioButton.Content>
<StackPanel>
<TextBlock>Profile</TextBlock>
<TextBlock Classes="subtitle" TextWrapping="Wrap">A profile which others can install to enjoy new lighting and interactions.</TextBlock>
</StackPanel>
</RadioButton.Content>
</RadioButton>
<RadioButton GroupName="EntryType"
IsChecked="{CompiledBinding SelectedEntryType, Converter={StaticResource EnumBoolConverter}, ConverterParameter={x:Static workshop:EntryType.Layout}}">
<RadioButton.Content>
<StackPanel>
<TextBlock>Layout</TextBlock>
<TextBlock Classes="subtitle" TextWrapping="Wrap">A layout providing users with a visual representation of a device.</TextBlock>
</StackPanel>
</RadioButton.Content>
</RadioButton>
</StackPanel>
</UserControl>
@@ -0,0 +1,17 @@
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
namespace Artemis.UI.Screens.Workshop.SubmissionWizard.Steps;
public partial class EntryTypeView : ReactiveUserControl<EntryTypeViewModel>
{
public EntryTypeView()
{
InitializeComponent();
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
}
@@ -0,0 +1,41 @@
using System;
using System.Reactive;
using System.Reactive.Linq;
using Artemis.WebClient.Workshop;
using ReactiveUI;
namespace Artemis.UI.Screens.Workshop.SubmissionWizard.Steps;
public class EntryTypeViewModel : SubmissionViewModel
{
private EntryType? _selectedEntryType;
/// <inheritdoc />
public EntryTypeViewModel()
{
GoBack = ReactiveCommand.Create(() => State.ChangeScreen<WelcomeStepViewModel>());
Continue = ReactiveCommand.Create(ExecuteContinue, this.WhenAnyValue(vm => vm.SelectedEntryType).Select(e => e != null));
}
public EntryType? SelectedEntryType
{
get => _selectedEntryType;
set => RaiseAndSetIfChanged(ref _selectedEntryType, value);
}
/// <inheritdoc />
public override ReactiveCommand<Unit, Unit> Continue { get; }
/// <inheritdoc />
public override ReactiveCommand<Unit, Unit> GoBack { get; }
private void ExecuteContinue()
{
if (SelectedEntryType == null)
return;
State.EntryType = SelectedEntryType.Value;
if (State.EntryType == EntryType.Profile)
State.ChangeScreen<ProfileSelectionStepViewModel>();
}
}
@@ -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.LoginStepView"
x:DataType="steps:LoginStepViewModel">
<StackPanel>
<StackPanel.Styles>
<Styles>
<Style Selector="TextBlock">
<Setter Property="TextAlignment" Value="Center"></Setter>
<Setter Property="TextWrapping" Value="Wrap"></Setter>
</Style>
</Styles>
</StackPanel.Styles>
<TextBlock Theme="{StaticResource TitleTextBlockStyle}">First things first</TextBlock>
<TextBlock>
<Run>In order to submit anything to the workshop you must be logged in.</Run>
<LineBreak />
<Run>Creating an account is free and we'll not bother you with a newsletter or crap like that.</Run>
</TextBlock>
<Lottie Path="/Assets/Animations/login-pending.json" RepeatCount="-1" Width="250" Height="250"></Lottie>
<TextBlock>
<Run>Click continue to (create an account) and log in.</Run>
<LineBreak/>
<Run>You'll also be able to log in with Google or Discord.</Run>
</TextBlock>
</StackPanel>
</UserControl>
@@ -0,0 +1,17 @@
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
namespace Artemis.UI.Screens.Workshop.SubmissionWizard.Steps;
public partial class LoginStepView : ReactiveUserControl<LoginStepView>
{
public LoginStepView()
{
InitializeComponent();
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
}
@@ -0,0 +1,50 @@
using System;
using System.Linq;
using System.Reactive;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
using Artemis.UI.Screens.Workshop.CurrentUser;
using Artemis.UI.Shared.Services;
using Artemis.WebClient.Workshop.Services;
using FluentAvalonia.UI.Controls;
using IdentityModel;
using ReactiveUI;
namespace Artemis.UI.Screens.Workshop.SubmissionWizard.Steps;
public class LoginStepViewModel : SubmissionViewModel
{
private readonly IAuthenticationService _authenticationService;
private readonly IWindowService _windowService;
public LoginStepViewModel(IAuthenticationService authenticationService, IWindowService windowService)
{
_authenticationService = authenticationService;
_windowService = windowService;
Continue = ReactiveCommand.CreateFromTask(ExecuteLogin);
ShowGoBack = false;
ShowHeader = false;
ContinueText = "Log In";
}
/// <inheritdoc />
public override ReactiveCommand<Unit, Unit> Continue { get; }
/// <inheritdoc />
public override ReactiveCommand<Unit, Unit> GoBack { get; } = null!;
private async Task ExecuteLogin(CancellationToken ct)
{
ContentDialogResult result = await _windowService.CreateContentDialog().WithViewModel(out WorkshopLoginViewModel _).WithTitle("Workshop login").ShowAsync();
if (result != ContentDialogResult.Primary)
return;
Claim? emailVerified = _authenticationService.Claims.FirstOrDefault(c => c.Type == JwtClaimTypes.EmailVerified);
if (emailVerified?.Value == "true")
State.ChangeScreen<EntryTypeViewModel>();
else
State.ChangeScreen<ValidateEmailStepViewModel>();
}
}
@@ -0,0 +1,10 @@
<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="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.Workshop.SubmissionWizard.Steps.ProfileSelectionStepView"
x:DataType="steps:ProfileSelectionStepViewModel">
Welcome to Avalonia!
</UserControl>
@@ -0,0 +1,18 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace Artemis.UI.Screens.Workshop.SubmissionWizard.Steps;
public partial class ProfileSelectionStepView : UserControl
{
public ProfileSelectionStepView()
{
InitializeComponent();
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
}
@@ -0,0 +1,13 @@
using System.Reactive;
using ReactiveUI;
namespace Artemis.UI.Screens.Workshop.SubmissionWizard.Steps;
public class ProfileSelectionStepViewModel : SubmissionViewModel
{
/// <inheritdoc />
public override ReactiveCommand<Unit, Unit> Continue { get; }
/// <inheritdoc />
public override ReactiveCommand<Unit, Unit> GoBack { get; }
}
@@ -0,0 +1,41 @@
<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"
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
mc:Ignorable="d" d:DesignWidth="970" d:DesignHeight="625"
x:Class="Artemis.UI.Screens.Workshop.SubmissionWizard.Steps.ValidateEmailStepView"
x:DataType="steps:ValidateEmailStepViewModel">
<StackPanel >
<StackPanel.Styles>
<Styles>
<Style Selector="TextBlock">
<Setter Property="TextAlignment" Value="Center"></Setter>
</Style>
</Styles>
</StackPanel.Styles>
<TextBlock Theme="{StaticResource TitleTextBlockStyle}" TextWrapping="Wrap">Confirm email address</TextBlock>
<TextBlock TextWrapping="Wrap">
<Run>Before you can continue, please confirm your email address.</Run> (<Run Text="{CompiledBinding Email.Value}"></Run>)
<LineBreak />
<Run>You'll find the confirmation mail in your inbox.</Run>
<LineBreak />
<LineBreak />
<TextBlock>Don't see an email? Check your spam box!</TextBlock>
</TextBlock>
<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>
<TextBlock Theme="{StaticResource CaptionTextBlockStyle}">
PS: We take this step to avoid the workshop getting spammed with low quality content.
</TextBlock>
</StackPanel>
</UserControl>
@@ -0,0 +1,17 @@
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
namespace Artemis.UI.Screens.Workshop.SubmissionWizard.Steps;
public partial class ValidateEmailStepView : ReactiveUserControl<ValidateEmailStepViewModel>
{
public ValidateEmailStepView()
{
InitializeComponent();
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
}
@@ -0,0 +1,78 @@
using System;
using System.Linq;
using System.Reactive;
using System.Reactive.Disposables;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
using Artemis.WebClient.Workshop.Services;
using IdentityModel;
using ReactiveUI;
using Timer = System.Timers.Timer;
namespace Artemis.UI.Screens.Workshop.SubmissionWizard.Steps;
public class ValidateEmailStepViewModel : SubmissionViewModel
{
private readonly IAuthenticationService _authenticationService;
private ObservableAsPropertyHelper<Claim?>? _email;
public ValidateEmailStepViewModel(IAuthenticationService authenticationService)
{
_authenticationService = authenticationService;
Continue = ReactiveCommand.Create(ExecuteContinue);
Refresh = ReactiveCommand.CreateFromTask(ExecuteRefresh);
ShowGoBack = false;
ShowHeader = false;
this.WhenActivated(d =>
{
_email = authenticationService.GetClaim(JwtClaimTypes.Email).ToProperty(this, vm => vm.Email).DisposeWith(d);
Timer updateTimer = new(TimeSpan.FromSeconds(15));
updateTimer.Elapsed += (_, _) => Task.Run(Update);
updateTimer.Start();
updateTimer.DisposeWith(d);
});
}
/// <inheritdoc />
public override ReactiveCommand<Unit, Unit> Continue { get; }
/// <inheritdoc />
public override ReactiveCommand<Unit, Unit> GoBack { get; } = null!;
public ReactiveCommand<Unit, Unit> Refresh { get; }
public Claim? Email => _email?.Value;
private async Task Update()
{
try
{
// Use the refresh token to login again, updating claims
await _authenticationService.AutoLogin(true);
Claim? emailVerified = _authenticationService.Claims.FirstOrDefault(c => c.Type == JwtClaimTypes.EmailVerified);
if (emailVerified?.Value == "true")
ExecuteContinue();
}
catch (Exception)
{
// ignored, meh
}
}
private void ExecuteContinue()
{
State.ChangeScreen<EntryTypeViewModel>();
}
private async Task ExecuteRefresh(CancellationToken ct)
{
await Update();
await Task.Delay(1000, ct);
}
}
@@ -3,50 +3,17 @@
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"
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
mc:Ignorable="d" d:DesignWidth="970" d:DesignHeight="625"
x:Class="Artemis.UI.Screens.Workshop.SubmissionWizard.Steps.WelcomeStepView"
x:DataType="steps:WelcomeStepViewModel">
<StackPanel>
<TextBlock Theme="{StaticResource TitleTextBlockStyle}">Welcome to the Workshop Submission Wizard 🧙</TextBlock>
<TextBlock>Here we'll take you, step by step, through the process of uploading your submission to the workshop.</TextBlock>
<StackPanel Margin="0 50 0 0" >
<TextBlock Theme="{StaticResource TitleTextBlockStyle}" TextAlignment="Center" TextWrapping="Wrap">
Welcome to the Workshop Submission Wizard 🧙
</TextBlock>
<TextBlock TextAlignment="Center" TextWrapping="Wrap">
Here we'll take you, step by step, through the process of uploading your submission to the workshop.
</TextBlock>
<StackPanel IsVisible="{CompiledBinding !IsLoggedIn}" Margin="0 35 0 0">
<TextBlock Theme="{StaticResource SubtitleTextBlockStyle}" TextWrapping="Wrap">First things first</TextBlock>
<TextBlock TextWrapping="Wrap">
<Run>In order to submit anything to the workshop you must be logged in.</Run>
<LineBreak />
<LineBreak />
<Run>Creating an account is free and we'll not bother you with a newsletter or crap like that. You can also log in with Google or Discord.</Run>
</TextBlock>
<Button Margin="0 15 0 0" Command="{CompiledBinding Login}">
<StackPanel Orientation="Horizontal" Spacing="5">
<avalonia:MaterialIcon Kind="ExternalLink" />
<TextBlock>Create account or log in</TextBlock>
</StackPanel>
</Button>
</StackPanel>
<StackPanel IsVisible="{CompiledBinding ShowMissingVerification}" Margin="0 35 0 0">
<TextBlock Theme="{StaticResource SubtitleTextBlockStyle}" TextWrapping="Wrap">Confirm email address</TextBlock>
<TextBlock TextWrapping="Wrap">
<Run>Before you can continue, please confirm your email address.</Run> (<Run Text="{CompiledBinding Email.Value}"></Run>)
<LineBreak />
<Run>You'll find the confirmation mail in your inbox.</Run>
<LineBreak />
<LineBreak />
<TextBlock>Don't see an email? Check your spam box!</TextBlock>
</TextBlock>
<Button Margin="0 15 0 5" Command="{CompiledBinding Refresh}">
<StackPanel Orientation="Horizontal" Spacing="5">
<avalonia:MaterialIcon Kind="Refresh" />
<TextBlock>Refresh</TextBlock>
</StackPanel>
</Button>
<TextBlock Theme="{StaticResource CaptionTextBlockStyle}">PS: We take this step to avoid the workshop getting flooded with bogus content.</TextBlock>
</StackPanel>
<Lottie Path="/Assets/Animations/workshop-wizard.json" RepeatCount="1" Width="300" Height="400"></Lottie>
</StackPanel>
</UserControl>
@@ -1,50 +1,24 @@
using System;
using System.Linq;
using System.Reactive;
using System.Reactive.Disposables;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
using Artemis.UI.Screens.Workshop.CurrentUser;
using Artemis.UI.Shared.Services;
using Artemis.WebClient.Workshop.Services;
using IdentityModel;
using ReactiveUI;
using Timer = System.Timers.Timer;
namespace Artemis.UI.Screens.Workshop.SubmissionWizard.Steps;
public class WelcomeStepViewModel : SubmissionViewModel
{
private readonly IAuthenticationService _authenticationService;
private readonly ObservableAsPropertyHelper<bool> _showMissingVerification;
private readonly IWindowService _windowService;
private ObservableAsPropertyHelper<Claim?>? _email;
private ObservableAsPropertyHelper<Claim?>? _emailVerified;
private ObservableAsPropertyHelper<bool>? _isLoggedIn;
public WelcomeStepViewModel(IAuthenticationService authenticationService, IWindowService windowService)
public WelcomeStepViewModel(IAuthenticationService authenticationService)
{
_authenticationService = authenticationService;
_windowService = windowService;
_showMissingVerification = this.WhenAnyValue(vm => vm.IsLoggedIn, vm => vm.EmailVerified, (l, v) => l && (v == null || v.Value == "false")).ToProperty(this, vm => vm.ShowMissingVerification);
Continue = ReactiveCommand.CreateFromTask(ExecuteContinue);
ShowHeader = false;
ShowGoBack = false;
Continue = ReactiveCommand.Create(ExecuteContinue);
Login = ReactiveCommand.CreateFromTask(ExecuteLogin);
Refresh = ReactiveCommand.CreateFromTask(ExecuteRefresh);
this.WhenActivated(d =>
{
_isLoggedIn = authenticationService.IsLoggedIn.ToProperty(this, vm => vm.IsLoggedIn).DisposeWith(d);
_emailVerified = authenticationService.GetClaim(JwtClaimTypes.EmailVerified).ToProperty(this, vm => vm.EmailVerified).DisposeWith(d);
_email = authenticationService.GetClaim(JwtClaimTypes.Email).ToProperty(this, vm => vm.Email).DisposeWith(d);
Timer updateTimer = new(TimeSpan.FromSeconds(15));
updateTimer.Elapsed += (_, _) => Task.Run(Update);
updateTimer.Start();
updateTimer.DisposeWith(d);
});
}
/// <inheritdoc />
@@ -53,43 +27,20 @@ public class WelcomeStepViewModel : SubmissionViewModel
/// <inheritdoc />
public override ReactiveCommand<Unit, Unit> GoBack { get; } = null!;
public ReactiveCommand<Unit, Unit> Login { get; }
public ReactiveCommand<Unit, Unit> Refresh { get; }
public bool ShowMissingVerification => _showMissingVerification.Value;
public bool IsLoggedIn => _isLoggedIn?.Value ?? false;
public Claim? EmailVerified => _emailVerified?.Value;
public Claim? Email => _email?.Value;
private async Task Update()
private async Task ExecuteContinue()
{
if (EmailVerified?.Value == "true")
return;
bool loggedIn = await _authenticationService.AutoLogin(true);
try
if (!loggedIn)
{
// Use the refresh token to login again, updating claims
await _authenticationService.AutoLogin(true);
State.ChangeScreen<LoginStepViewModel>();
}
catch (Exception)
else
{
// ignored, meh
if (_authenticationService.Claims.Any(c => c.Type == JwtClaimTypes.EmailVerified && c.Value == "true"))
State.ChangeScreen<EntryTypeViewModel>();
else
State.ChangeScreen<ValidateEmailStepViewModel>();
}
}
private void ExecuteContinue()
{
throw new NotImplementedException();
}
private async Task ExecuteLogin(CancellationToken ct)
{
await _windowService.CreateContentDialog().WithViewModel(out WorkshopLoginViewModel _).WithTitle("Workshop login").ShowAsync();
}
private async Task ExecuteRefresh(CancellationToken ct)
{
await Update();
await Task.Delay(1000, ct);
}
}
@@ -0,0 +1,43 @@
using System.Reactive;
using Artemis.UI.Shared;
using ReactiveUI;
namespace Artemis.UI.Screens.Workshop.SubmissionWizard;
public abstract class SubmissionViewModel : ActivatableViewModelBase
{
private string _continueText = "Continue";
private bool _showFinish;
private bool _showGoBack = true;
private bool _showHeader = true;
public SubmissionWizardViewModel WizardViewModel { get; set; } = null!;
public SubmissionWizardState State { get; set; } = null!;
public abstract ReactiveCommand<Unit, Unit> Continue { get; }
public abstract ReactiveCommand<Unit, Unit> GoBack { get; }
public bool ShowHeader
{
get => _showHeader;
set => RaiseAndSetIfChanged(ref _showHeader, value);
}
public bool ShowGoBack
{
get => _showGoBack;
set => RaiseAndSetIfChanged(ref _showGoBack, value);
}
public bool ShowFinish
{
get => _showFinish;
set => RaiseAndSetIfChanged(ref _showFinish, value);
}
public string ContinueText
{
get => _continueText;
set => RaiseAndSetIfChanged(ref _continueText, value);
}
}
@@ -0,0 +1,34 @@
using System.Collections.Generic;
using System.IO;
using Artemis.WebClient.Workshop;
using DryIoc;
namespace Artemis.UI.Screens.Workshop.SubmissionWizard;
public class SubmissionWizardState
{
private readonly SubmissionWizardViewModel _wizardViewModel;
private readonly IContainer _container;
public SubmissionWizardState(SubmissionWizardViewModel wizardViewModel, IContainer container)
{
_wizardViewModel = wizardViewModel;
_container = container;
}
public EntryType EntryType { get; set; }
public string Name { get; set; } = string.Empty;
public Stream? Icon { get; set; }
public string Summary { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public List<int> Categories { get; set; } = new();
public List<int> Tags { get; set; } = new();
public List<Stream> Images { get; set; } = new();
public void ChangeScreen<TSubmissionViewModel>() where TSubmissionViewModel : SubmissionViewModel
{
_wizardViewModel.Screen = _container.Resolve<TSubmissionViewModel>();
}
}
@@ -17,7 +17,8 @@
<Grid Margin="15" RowDefinitions="Auto,*,Auto">
<Grid RowDefinitions="*,*" ColumnDefinitions="Auto,*,Auto" Margin="0 0 0 15">
<ContentControl Grid.Column="0" Grid.RowSpan="2" Width="65" Height="65" VerticalAlignment="Center" Margin="0 0 20 0" Content="{CompiledBinding CurrentUserViewModel}"/>
<TextBlock Grid.Row="0" Grid.Column="1" FontSize="36" VerticalAlignment="Bottom" Text="{CompiledBinding CurrentUserViewModel.Name, FallbackValue=Not logged in}"/>
<TextBlock Grid.Row="0" Grid.Column="1" FontSize="36" VerticalAlignment="Bottom" Text="{CompiledBinding CurrentUserViewModel.Name}" IsVisible="{CompiledBinding !CurrentUserViewModel.IsAnonymous}"/>
<TextBlock Grid.Row="0" Grid.Column="1" FontSize="36" VerticalAlignment="Bottom" Text="Anon 🕵️" IsVisible="{CompiledBinding CurrentUserViewModel.IsAnonymous}"/>
<StackPanel Grid.Row="0" Grid.Column="2" HorizontalAlignment="Right" VerticalAlignment="Bottom" Orientation="Horizontal">
<controls:HyperlinkButton Classes="icon-button" ToolTip.Tip="View Wiki" NavigateUri="https://wiki.artemis-rgb.com?mtm_campaign=artemis&amp;mtm_kwd=workshop-wizard">
@@ -44,9 +45,7 @@
<Button Command="{CompiledBinding Screen.GoBack}" IsVisible="{CompiledBinding Screen.ShowGoBack}">
Back
</Button>
<Button Command="{CompiledBinding Screen.Continue}" IsVisible="{CompiledBinding !Screen.ShowFinish}" Width="80">
Continue
</Button>
<Button Command="{CompiledBinding Screen.Continue}" IsVisible="{CompiledBinding !Screen.ShowFinish}" Width="80" Content="{CompiledBinding Screen.ContinueText}"/>
<Button Command="{CompiledBinding Screen.Continue}" IsVisible="{CompiledBinding Screen.ShowFinish}" Width="80">
Finish
</Button>
@@ -1,19 +1,24 @@
using System.Reactive;
using Artemis.UI.Screens.Workshop.CurrentUser;
using Artemis.UI.Screens.Workshop.CurrentUser;
using Artemis.UI.Screens.Workshop.SubmissionWizard.Steps;
using Artemis.UI.Shared;
using ReactiveUI;
using DryIoc;
namespace Artemis.UI.Screens.Workshop.SubmissionWizard;
public class SubmissionWizardViewModel : DialogViewModelBase<bool>
{
private readonly SubmissionWizardState _state;
private SubmissionViewModel _screen;
public SubmissionWizardViewModel(CurrentUserViewModel currentUserViewModel, WelcomeStepViewModel welcomeStepViewModel)
public SubmissionWizardViewModel(IContainer container, CurrentUserViewModel currentUserViewModel, WelcomeStepViewModel welcomeStepViewModel)
{
_state = new SubmissionWizardState(this, container);
_screen = welcomeStepViewModel;
_screen.WizardViewModel = this;
_screen.State = _state;
CurrentUserViewModel = currentUserViewModel;
CurrentUserViewModel.AllowLogout = false;
}
public CurrentUserViewModel CurrentUserViewModel { get; }
@@ -21,27 +26,11 @@ public class SubmissionWizardViewModel : DialogViewModelBase<bool>
public SubmissionViewModel Screen
{
get => _screen;
set => RaiseAndSetIfChanged(ref _screen, value);
}
}
public abstract class SubmissionViewModel : ActivatableViewModelBase
{
private bool _showFinish;
private bool _showGoBack = true;
public abstract ReactiveCommand<Unit, Unit> Continue { get; }
public abstract ReactiveCommand<Unit, Unit> GoBack { get; }
public bool ShowGoBack
{
get => _showGoBack;
set => RaiseAndSetIfChanged(ref _showGoBack, value);
}
public bool ShowFinish
{
get => _showFinish;
set => RaiseAndSetIfChanged(ref _showFinish, value);
set
{
value.WizardViewModel = this;
value.State = _state;
RaiseAndSetIfChanged(ref _screen, value);
}
}
}