Workshop - Simplify upload to a busy indicator, show images in profiles

This commit is contained in:
RobertBeekman committed 2023-12-10 22:44:03 +01:00
1 parent e33ae8a066
commit e304d67035
22 files changed
+125 -242

No files matched your search

@@ -9,6 +9,7 @@ using Artemis.UI.Screens.Workshop.Image;
using Artemis.UI.Shared.Services;
using Artemis.WebClient.Workshop.Handlers.UploadHandlers;
using DynamicData;
using FluentAvalonia.UI.Controls;
using ReactiveUI;
namespace Artemis.UI.Screens.Workshop.SubmissionWizard.Steps;
@@ -49,7 +50,7 @@ public class ImagesStepViewModel : SubmissionViewModel
private ImageSubmissionViewModel CreateImageSubmissionViewModel(ImageUploadRequest image)
{
ImageSubmissionViewModel viewModel = _getImageSubmissionViewModel(image);
viewModel.Remove = ReactiveCommand.Create(() => _stateImages.Remove(image));
viewModel.Remove = ReactiveCommand.Create(() => RemoveImage(image));
return viewModel;
}
@@ -73,8 +74,23 @@ public class ImagesStepViewModel : SubmissionViewModel
}
ImageUploadRequest request = new(stream, Path.GetFileName(path), string.Empty);
_stateImages.Add(request);
State.Images.Add(request);
AddImage(request);
// Show the dialog to give the image a name and description
if (await Images.Last().Edit() != ContentDialogResult.Primary)
RemoveImage(request); // user did not click confirm, remove again
}
}
private void AddImage(ImageUploadRequest image)
{
_stateImages.Add(image);
State.Images.Add(image);
}
private void RemoveImage(ImageUploadRequest image)
{
_stateImages.Remove(image);
State.Images.Remove(image);
}
}
@@ -16,17 +16,11 @@
</Styles>
</StackPanel.Styles>
<TextBlock IsVisible="{CompiledBinding !Finished}" Theme="{StaticResource TitleTextBlockStyle}" TextAlignment="Center" TextWrapping="Wrap">
Uploading your submission...
</TextBlock>
<ProgressBar IsVisible="{CompiledBinding !Finished}"
Margin="0 15 0 0"
Width="380"
IsIndeterminate="{CompiledBinding ProgressIndeterminate}"
Value="{CompiledBinding ProgressPercentage}">
</ProgressBar>
<StackPanel IsVisible="{CompiledBinding !Finished}">
<Lottie Path="/Assets/Animations/busy.json" Width="250" Height="250" Margin="0 100" ></Lottie>
<TextBlock Theme="{StaticResource TitleTextBlockStyle}">Uploading your submission...</TextBlock>
</StackPanel>
<StackPanel IsVisible="{CompiledBinding Succeeded}">
<Lottie Path="/Assets/Animations/success.json" RepeatCount="1" Width="250" Height="250" Margin="0 100"></Lottie>
<TextBlock Theme="{StaticResource TitleTextBlockStyle}">All done! Hit finish to view your submission.</TextBlock>
@@ -23,9 +23,6 @@ public partial class UploadStepViewModel : SubmissionViewModel
{
private readonly ILogger _logger;
private readonly EntryUploadHandlerFactory _entryUploadHandlerFactory;
private readonly Progress<StreamProgress> _progress = new();
private readonly ObservableAsPropertyHelper<bool> _progressIndeterminate;
private readonly ObservableAsPropertyHelper<int> _progressPercentage;
private readonly IRouter _router;
private readonly IWindowService _windowService;
private readonly IWorkshopClient _workshopClient;
@@ -40,7 +37,7 @@ public partial class UploadStepViewModel : SubmissionViewModel
IWorkshopClient workshopClient,
IWorkshopService workshopService,
EntryUploadHandlerFactory entryUploadHandlerFactory,
IWindowService windowService,
IWindowService windowService,
IRouter router)
{
_logger = logger;
@@ -54,19 +51,9 @@ public partial class UploadStepViewModel : SubmissionViewModel
ContinueText = "Finish";
Continue = ReactiveCommand.CreateFromTask(ExecuteContinue, this.WhenAnyValue(vm => vm.Finished));
_progressPercentage = Observable.FromEventPattern<StreamProgress>(x => _progress.ProgressChanged += x, x => _progress.ProgressChanged -= x)
.Select(e => e.EventArgs.ProgressPercentage)
.ToProperty(this, vm => vm.ProgressPercentage);
_progressIndeterminate = Observable.FromEventPattern<StreamProgress>(x => _progress.ProgressChanged += x, x => _progress.ProgressChanged -= x)
.Select(e => e.EventArgs.ProgressPercentage == 0)
.ToProperty(this, vm => vm.ProgressIndeterminate);
this.WhenActivated(d => Observable.FromAsync(ExecuteUpload).Subscribe().DisposeWith(d));
}
public int ProgressPercentage => _progressPercentage.Value;
public bool ProgressIndeterminate => _progressIndeterminate.Value;
private async Task ExecuteUpload(CancellationToken cancellationToken)
{
// Use the existing entry or create a new one
@@ -79,7 +66,7 @@ public partial class UploadStepViewModel : SubmissionViewModel
try
{
IEntryUploadHandler uploadHandler = _entryUploadHandlerFactory.CreateHandler(State.EntryType);
EntryUploadResult uploadResult = await uploadHandler.CreateReleaseAsync(_entryId.Value, State.EntrySource!, _progress, cancellationToken);
EntryUploadResult uploadResult = await uploadHandler.CreateReleaseAsync(_entryId.Value, State.EntrySource!, cancellationToken);
if (!uploadResult.IsSuccess)
{
string? message = uploadResult.Message;
@@ -96,7 +83,7 @@ public partial class UploadStepViewModel : SubmissionViewModel
catch (Exception e)
{
_logger.Error(e, "Failed to upload submission for entry {EntryId}", _entryId);
// Something went wrong when creating a release :c
// We'll keep the workshop entry so that the user can make changes and try again
Failed = true;
@@ -109,6 +96,8 @@ public partial class UploadStepViewModel : SubmissionViewModel
private async Task<long?> CreateEntry(CancellationToken cancellationToken)
{
await Task.Delay(2000);
IOperationResult<IAddEntryResult> result = await _workshopClient.AddEntry.ExecuteAsync(new CreateEntryInput
{
EntryType = State.EntryType,
@@ -122,57 +111,40 @@ public partial class UploadStepViewModel : SubmissionViewModel
long? entryId = result.Data?.AddEntry?.Id;
if (result.IsErrorResult() || entryId == null)
{
await _windowService.ShowConfirmContentDialog("Failed to create workshop entry", string.Join("\r\n", result.Errors.Select(e => e.Message)), "Close", null);
State.ChangeScreen<SubmitStepViewModel>();
return null;
}
if (cancellationToken.IsCancellationRequested)
{
await _windowService.ShowConfirmContentDialog("Failed to create workshop entry", string.Join("\r\n", result.Errors.Select(e => e.Message)), "Close", null);
State.ChangeScreen<SubmitStepViewModel>();
return null;
}
cancellationToken.ThrowIfCancellationRequested();
foreach (ImageUploadRequest image in State.Images.ToList())
{
// Upload image
try
{
ImageUploadResult imageUploadResult = await _workshopService.UploadEntryImage(entryId.Value, image, _progress, cancellationToken);
if (!imageUploadResult.IsSuccess)
throw new ArtemisWorkshopException(imageUploadResult.Message);
State.Images.Remove(image);
}
catch (Exception e)
{
// It's not critical if this fails
await _windowService.ShowConfirmContentDialog("Failed to upload image", "Your submission will continue, you can try upload a new image afterwards\r\n" + e.Message, "Continue", null);
}
if (cancellationToken.IsCancellationRequested)
{
State.ChangeScreen<SubmitStepViewModel>();
return null;
}
await TryImageUpload(async () => await _workshopService.UploadEntryImage(entryId.Value, image, cancellationToken));
cancellationToken.ThrowIfCancellationRequested();
}
if (State.Icon == null)
return entryId;
// Upload icon
await TryImageUpload(async () => await _workshopService.SetEntryIcon(entryId.Value, State.Icon, cancellationToken));
return entryId;
}
private async Task TryImageUpload(Func<Task<ImageUploadResult>> action)
{
try
{
ImageUploadResult imageUploadResult = await _workshopService.SetEntryIcon(entryId.Value, _progress, State.Icon, cancellationToken);
if (!imageUploadResult.IsSuccess)
throw new ArtemisWorkshopException(imageUploadResult.Message);
ImageUploadResult result = await action();
if (!result.IsSuccess)
throw new ArtemisWorkshopException(result.Message);
}
catch (Exception e)
{
// It's not critical if this fails
await _windowService.ShowConfirmContentDialog("Failed to upload icon", "Your submission will continue, you can try upload a new image afterwards\r\n" + e.Message, "Continue", null);
await _windowService.ShowConfirmContentDialog("Failed to upload", "Your submission will continue, you can try upload a new image afterwards\r\n" + e.Message, "Continue", null);
}
return entryId;
}
private async Task ExecuteContinue()