Submission wizard - Added logging in and email verification check

This commit is contained in:
Robert committed 2023-08-07 20:25:00 +02:00
1 parent eeaf3999cf
commit 661242ebf9
6 files changed
+152 -20

No files matched your search

@@ -34,8 +34,11 @@ public class CurrentUserViewModel : ActivatableViewModelBase
_windowService = windowService;
Login = ReactiveCommand.CreateFromTask(ExecuteLogin);
this.WhenActivated(d => ReactiveCommand.CreateFromTask(ExecuteAutoLogin).Execute().Subscribe().DisposeWith(d));
this.WhenActivated(d => _authenticationService.IsLoggedIn.Subscribe(_ => LoadCurrentUser().DisposeWith(d)));
this.WhenActivated(d =>
{
Task.Run(AutoLogin);
_authenticationService.IsLoggedIn.Subscribe(_ => Task.Run(LoadCurrentUser)).DisposeWith(d);
});
}
public bool Loading
@@ -86,7 +89,7 @@ public class CurrentUserViewModel : ActivatableViewModelBase
await LoadCurrentUser();
}
private async Task ExecuteAutoLogin(CancellationToken cancellationToken)
private async Task AutoLogin()
{
try
{
@@ -2,10 +2,51 @@
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="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.Workshop.SubmissionWizard.Steps.WelcomeStepView">
x:Class="Artemis.UI.Screens.Workshop.SubmissionWizard.Steps.WelcomeStepView"
x:DataType="steps:WelcomeStepViewModel">
<StackPanel>
<TextBlock>Welcome to the Workshop Submission Wizard 🧙</TextBlock>
<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 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>
</StackPanel>
</UserControl>
</UserControl>
@@ -1,11 +1,51 @@
using System;
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
{
#region Overrides of 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)
{
_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);
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 />
public override ReactiveCommand<Unit, Unit> Continue { get; }
@@ -13,10 +53,43 @@ public class WelcomeStepViewModel : SubmissionViewModel
/// <inheritdoc />
public override ReactiveCommand<Unit, Unit> GoBack { get; } = null!;
public WelcomeStepViewModel()
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()
{
ShowGoBack = false;
if (EmailVerified?.Value == "true")
return;
try
{
// Use the refresh token to login again, updating claims
await _authenticationService.AutoLogin(true);
}
catch (Exception)
{
// ignored, meh
}
}
#endregion
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);
}
}
@@ -10,9 +10,9 @@ public class SubmissionWizardViewModel : DialogViewModelBase<bool>
{
private SubmissionViewModel _screen;
public SubmissionWizardViewModel(CurrentUserViewModel currentUserViewModel)
public SubmissionWizardViewModel(CurrentUserViewModel currentUserViewModel, WelcomeStepViewModel welcomeStepViewModel)
{
_screen = new WelcomeStepViewModel();
_screen = welcomeStepViewModel;
CurrentUserViewModel = currentUserViewModel;
}