From fcde1d4ecc580c892bf56d085742b21c0574f3db Mon Sep 17 00:00:00 2001 From: Robert Date: Tue, 5 Sep 2023 21:39:43 +0200 Subject: [PATCH] UI - Tweaked monospace font sizing --- .../Styles/Controls/DataModelPicker.axaml | 4 +- .../Tabs/DataModel/DataModelDebugView.axaml | 2 +- .../Debugger/Tabs/Logs/LogsDebugView.axaml | 4 +- .../Tabs/Routing/RoutingDebugView.axaml | 1 + .../Screens/VisualScripting/CableView.axaml | 11 +- .../Entries/EntrySpecificationsView.axaml | 44 +++--- .../Entries/EntrySpecificationsViewModel.cs | 86 ++++++----- .../Library/SubmissionDetailView.axaml | 10 +- .../Library/SubmissionDetailViewModel.cs | 139 +++++++++++++----- .../Steps/EntryTypeStepViewModel.cs | 8 - .../Steps/LoginStepViewModel.cs | 8 - .../ProfileAdaptionHintsLayerViewModel.cs | 11 +- .../ProfileAdaptionHintsStepViewModel.cs | 13 +- .../Profile/ProfileSelectionStepViewModel.cs | 7 - .../Steps/SpecificationsStepView.axaml.cs | 2 - .../Steps/SpecificationsStepViewModel.cs | 60 ++++---- .../Steps/SubmitStepView.axaml.cs | 2 - .../Steps/SubmitStepViewModel.cs | 18 +-- .../Steps/UploadStepView.axaml.cs | 2 - .../Steps/UploadStepViewModel.cs | 7 - .../Steps/ValidateEmailStepViewModel.cs | 8 +- .../Steps/WelcomeStepViewModel.cs | 8 - .../SubmissionWizard/SubmissionViewModel.cs | 17 ++- .../Screens/DisplayValueNodeCustomView.axaml | 2 +- .../Services/IWorkshopService.cs | 21 ++- 25 files changed, 281 insertions(+), 214 deletions(-) diff --git a/src/Artemis.UI.Shared/Styles/Controls/DataModelPicker.axaml b/src/Artemis.UI.Shared/Styles/Controls/DataModelPicker.axaml index d2757ca40..0175ae880 100644 --- a/src/Artemis.UI.Shared/Styles/Controls/DataModelPicker.axaml +++ b/src/Artemis.UI.Shared/Styles/Controls/DataModelPicker.axaml @@ -67,6 +67,7 @@ @@ -81,7 +82,7 @@ IsVisible="{CompiledBinding IsEventPicker, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type dataModelPicker:DataModelPicker}}}"/> - + @@ -91,6 +92,7 @@ diff --git a/src/Artemis.UI/Screens/Debugger/Tabs/DataModel/DataModelDebugView.axaml b/src/Artemis.UI/Screens/Debugger/Tabs/DataModel/DataModelDebugView.axaml index 1ae47d2af..cd12f8f18 100644 --- a/src/Artemis.UI/Screens/Debugger/Tabs/DataModel/DataModelDebugView.axaml +++ b/src/Artemis.UI/Screens/Debugger/Tabs/DataModel/DataModelDebugView.axaml @@ -52,8 +52,8 @@ diff --git a/src/Artemis.UI/Screens/Debugger/Tabs/Logs/LogsDebugView.axaml b/src/Artemis.UI/Screens/Debugger/Tabs/Logs/LogsDebugView.axaml index dd438e85b..06ef67204 100644 --- a/src/Artemis.UI/Screens/Debugger/Tabs/Logs/LogsDebugView.axaml +++ b/src/Artemis.UI/Screens/Debugger/Tabs/Logs/LogsDebugView.axaml @@ -10,8 +10,8 @@ + SelectionBrush="{StaticResource TextControlSelectionHighlightColor}"/> \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Debugger/Tabs/Routing/RoutingDebugView.axaml b/src/Artemis.UI/Screens/Debugger/Tabs/Routing/RoutingDebugView.axaml index 8ea97a606..68230f577 100644 --- a/src/Artemis.UI/Screens/Debugger/Tabs/Routing/RoutingDebugView.axaml +++ b/src/Artemis.UI/Screens/Debugger/Tabs/Routing/RoutingDebugView.axaml @@ -20,6 +20,7 @@ diff --git a/src/Artemis.UI/Screens/VisualScripting/CableView.axaml b/src/Artemis.UI/Screens/VisualScripting/CableView.axaml index 7f9f935a5..31fedf0fa 100644 --- a/src/Artemis.UI/Screens/VisualScripting/CableView.axaml +++ b/src/Artemis.UI/Screens/VisualScripting/CableView.axaml @@ -41,7 +41,8 @@ Text="{CompiledBinding Converter={StaticResource SKColorToStringConverter}, Mode=OneWay}" VerticalAlignment="Center" HorizontalAlignment="Stretch" - FontFamily="{StaticResource RobotoMono}" /> + FontFamily="{StaticResource RobotoMono}" + FontSize="13"/> - + - + - + - + diff --git a/src/Artemis.UI/Screens/Workshop/Entries/EntrySpecificationsView.axaml b/src/Artemis.UI/Screens/Workshop/Entries/EntrySpecificationsView.axaml index 8dbb6539e..94bf49bb5 100644 --- a/src/Artemis.UI/Screens/Workshop/Entries/EntrySpecificationsView.axaml +++ b/src/Artemis.UI/Screens/Workshop/Entries/EntrySpecificationsView.axaml @@ -12,7 +12,7 @@ mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="800" x:Class="Artemis.UI.Screens.Workshop.Entries.EntrySpecificationsView" x:DataType="entries:EntrySpecificationsViewModel"> - + @@ -25,8 +25,8 @@ - - + + + + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Workshop/Library/SubmissionDetailViewModel.cs b/src/Artemis.UI/Screens/Workshop/Library/SubmissionDetailViewModel.cs index 11d35afb1..2b05edc76 100644 --- a/src/Artemis.UI/Screens/Workshop/Library/SubmissionDetailViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/Library/SubmissionDetailViewModel.cs @@ -1,7 +1,9 @@ using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.ComponentModel; using System.IO; using System.Linq; -using System.Net.Http; using System.Reactive; using System.Threading; using System.Threading.Tasks; @@ -10,8 +12,11 @@ using Artemis.UI.Screens.Workshop.Parameters; using Artemis.UI.Screens.Workshop.SubmissionWizard; using Artemis.UI.Shared.Routing; using Artemis.UI.Shared.Services; +using Artemis.UI.Shared.Utilities; using Artemis.WebClient.Workshop; +using Artemis.WebClient.Workshop.Exceptions; using Artemis.WebClient.Workshop.Services; +using Artemis.WebClient.Workshop.UploadHandlers; using Avalonia.Media.Imaging; using ReactiveUI; using StrawberryShake; @@ -21,37 +26,33 @@ namespace Artemis.UI.Screens.Workshop.Library; public class SubmissionDetailViewModel : RoutableScreen { private readonly IWorkshopClient _client; - private readonly IHttpClientFactory _httpClientFactory; - private readonly Func _getEntrySpecificationsViewModel; + private readonly Func _getGetSpecificationsVm; + private readonly IRouter _router; private readonly IWindowService _windowService; private readonly IWorkshopService _workshopService; - private readonly IRouter _router; private IGetSubmittedEntryById_Entry? _entry; private EntrySpecificationsViewModel? _entrySpecificationsViewModel; + private bool _hasChanges; - public SubmissionDetailViewModel(IWorkshopClient client, - IHttpClientFactory httpClientFactory, - IWindowService windowService, - IWorkshopService workshopService, - IRouter router, - Func entrySpecificationsViewModel) - { + public SubmissionDetailViewModel(IWorkshopClient client, IWindowService windowService, IWorkshopService workshopService, IRouter router, Func getSpecificationsVm) { _client = client; - _httpClientFactory = httpClientFactory; _windowService = windowService; _workshopService = workshopService; _router = router; - _getEntrySpecificationsViewModel = entrySpecificationsViewModel; + _getGetSpecificationsVm = getSpecificationsVm; - Save = ReactiveCommand.CreateFromTask(ExecuteSave); CreateRelease = ReactiveCommand.CreateFromTask(ExecuteCreateRelease); DeleteSubmission = ReactiveCommand.CreateFromTask(ExecuteDeleteSubmission); ViewWorkshopPage = ReactiveCommand.CreateFromTask(ExecuteViewWorkshopPage); + DiscardChanges = ReactiveCommand.CreateFromTask(ExecuteDiscardChanges, this.WhenAnyValue(vm => vm.HasChanges)); + SaveChanges = ReactiveCommand.CreateFromTask(ExecuteSaveChanges, this.WhenAnyValue(vm => vm.HasChanges)); } - public ReactiveCommand Save { get; } public ReactiveCommand CreateRelease { get; } public ReactiveCommand DeleteSubmission { get; } + public ReactiveCommand ViewWorkshopPage { get; } + public ReactiveCommand SaveChanges { get; } + public ReactiveCommand DiscardChanges { get; } public EntrySpecificationsViewModel? EntrySpecificationsViewModel { @@ -65,8 +66,12 @@ public class SubmissionDetailViewModel : RoutableScreen RaiseAndSetIfChanged(ref _entry, value); } - public ReactiveCommand ViewWorkshopPage { get; } - + public bool HasChanges + { + get => _hasChanges; + private set => RaiseAndSetIfChanged(ref _hasChanges, value); + } + public override async Task OnNavigating(WorkshopDetailParameters parameters, NavigationArguments args, CancellationToken cancellationToken) { IOperationResult result = await _client.GetSubmittedEntryById.ExecuteAsync(parameters.EntryId, cancellationToken); @@ -77,12 +82,29 @@ public class SubmissionDetailViewModel : RoutableScreen GetEntryIcon(CancellationToken cancellationToken) @@ -102,26 +127,59 @@ public class SubmissionDetailViewModel : RoutableScreen categories = EntrySpecificationsViewModel.Categories.Where(c => c.IsSelected).Select(c => c.Id).OrderBy(c => c).ToList(); + List tags = EntrySpecificationsViewModel.Tags.OrderBy(t => t).ToList(); + + HasChanges = EntrySpecificationsViewModel.Name != Entry.Name || + EntrySpecificationsViewModel.Description != Entry.Description || + EntrySpecificationsViewModel.Summary != Entry.Summary || + EntrySpecificationsViewModel.IconChanged || + !tags.SequenceEqual(Entry.Tags.Select(t => t.Name).OrderBy(t => t)) || + !categories.SequenceEqual(Entry.Categories.Select(c => c.Id).OrderBy(c => c)); + } + + private async Task ExecuteDiscardChanges() + { + await ApplyFromEntry(CancellationToken.None); + } + + private async Task ExecuteSaveChanges(CancellationToken cancellationToken) + { + if (Entry == null || EntrySpecificationsViewModel == null || !EntrySpecificationsViewModel.ValidationContext.GetIsValid()) + return; + + UpdateEntryInput input = new() + { + Id = Entry.Id, + Name = EntrySpecificationsViewModel.Name, + Summary = EntrySpecificationsViewModel.Summary, + Description = EntrySpecificationsViewModel.Description, + Categories = EntrySpecificationsViewModel.SelectedCategories, + Tags = EntrySpecificationsViewModel.Tags + }; + IOperationResult result = await _client.UpdateEntry.ExecuteAsync(input, cancellationToken); result.EnsureNoErrors(); + + if (EntrySpecificationsViewModel.IconChanged && EntrySpecificationsViewModel.IconBitmap != null) + { + using MemoryStream stream = new(); + EntrySpecificationsViewModel.IconBitmap.Save(stream); + ImageUploadResult imageResult = await _workshopService.SetEntryIcon(Entry.Id, new Progress(), stream, cancellationToken); + if (!imageResult.IsSuccess) + throw new ArtemisWorkshopException("Failed to upload image. " + imageResult.Message); + } + + HasChanges = false; } private async Task ExecuteCreateRelease(CancellationToken cancellationToken) @@ -152,4 +210,19 @@ public class SubmissionDetailViewModel : RoutableScreen RaiseAndSetIfChanged(ref _selectedEntryType, value); } - /// - public override ReactiveCommand Continue { get; } - - /// - public override ReactiveCommand GoBack { get; } - private void ExecuteContinue() { if (SelectedEntryType == null) diff --git a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/LoginStepViewModel.cs b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/LoginStepViewModel.cs index 83b7d3ca0..5b6cf680b 100644 --- a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/LoginStepViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/LoginStepViewModel.cs @@ -1,6 +1,4 @@ -using System; using System.Linq; -using System.Reactive; using System.Security.Claims; using System.Threading; using System.Threading.Tasks; @@ -29,12 +27,6 @@ public class LoginStepViewModel : SubmissionViewModel ContinueText = "Log In"; } - /// - public override ReactiveCommand Continue { get; } - - /// - public override ReactiveCommand GoBack { get; } = null!; - private async Task ExecuteLogin(CancellationToken ct) { ContentDialogResult result = await _windowService.CreateContentDialog().WithViewModel(out WorkshopLoginViewModel _).WithTitle("Workshop login").ShowAsync(); diff --git a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/Profile/ProfileAdaptionHintsLayerViewModel.cs b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/Profile/ProfileAdaptionHintsLayerViewModel.cs index ade952508..48b741698 100644 --- a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/Profile/ProfileAdaptionHintsLayerViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/Profile/ProfileAdaptionHintsLayerViewModel.cs @@ -6,31 +6,30 @@ using Artemis.Core.Services; using Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs; using Artemis.UI.Shared; using Artemis.UI.Shared.Services; -using FluentAvalonia.Core; using ReactiveUI; namespace Artemis.UI.Screens.Workshop.SubmissionWizard.Steps.Profile; public class ProfileAdaptionHintsLayerViewModel : ViewModelBase { - private readonly IWindowService _windowService; - private readonly IProfileService _profileService; private readonly ObservableAsPropertyHelper _adaptionHintText; + private readonly IProfileService _profileService; + private readonly IWindowService _windowService; private int _adaptionHintCount; - public Layer Layer { get; } - public ProfileAdaptionHintsLayerViewModel(Layer layer, IWindowService windowService, IProfileService profileService) { _windowService = windowService; _profileService = profileService; _adaptionHintText = this.WhenAnyValue(vm => vm.AdaptionHintCount).Select(c => c == 1 ? "1 adaption hint" : $"{c} adaption hints").ToProperty(this, vm => vm.AdaptionHintText); - + Layer = layer; EditAdaptionHints = ReactiveCommand.CreateFromTask(ExecuteEditAdaptionHints); AdaptionHintCount = layer.Adapter.AdaptionHints.Count; } + public Layer Layer { get; } + public ReactiveCommand EditAdaptionHints { get; } public int AdaptionHintCount diff --git a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/Profile/ProfileAdaptionHintsStepViewModel.cs b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/Profile/ProfileAdaptionHintsStepViewModel.cs index b9ec09c15..fc55b987a 100644 --- a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/Profile/ProfileAdaptionHintsStepViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/Profile/ProfileAdaptionHintsStepViewModel.cs @@ -3,23 +3,22 @@ using System.Collections.ObjectModel; using System.Linq; using System.Reactive; using System.Reactive.Disposables; -using System.Reactive.Linq; using System.Threading.Tasks; using Artemis.Core; using Artemis.Core.Services; using Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs; using Artemis.UI.Shared.Services; using DynamicData; -using ReactiveUI; using DynamicData.Aggregation; +using ReactiveUI; namespace Artemis.UI.Screens.Workshop.SubmissionWizard.Steps.Profile; public class ProfileAdaptionHintsStepViewModel : SubmissionViewModel { - private readonly IWindowService _windowService; - private readonly IProfileService _profileService; private readonly SourceList _layers; + private readonly IProfileService _profileService; + private readonly IWindowService _windowService; public ProfileAdaptionHintsStepViewModel(IWindowService windowService, IProfileService profileService, Func getLayerViewModel) { @@ -36,18 +35,14 @@ public class ProfileAdaptionHintsStepViewModel : SubmissionViewModel this.WhenActivated((CompositeDisposable _) => { if (State.EntrySource is ProfileConfiguration profileConfiguration && profileConfiguration.Profile != null) - { _layers.Edit(l => { l.Clear(); l.AddRange(profileConfiguration.Profile.GetAllLayers().Select(getLayerViewModel)); }); - } }); } - public override ReactiveCommand Continue { get; } - public override ReactiveCommand GoBack { get; } public ReactiveCommand EditAdaptionHints { get; } public ReadOnlyObservableCollection Layers { get; } @@ -61,7 +56,7 @@ public class ProfileAdaptionHintsStepViewModel : SubmissionViewModel { if (Layers.Any(l => l.AdaptionHintCount == 0)) return; - + if (State.EntryId == null) State.ChangeScreen(); else diff --git a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/Profile/ProfileSelectionStepViewModel.cs b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/Profile/ProfileSelectionStepViewModel.cs index 86b49a6d4..adad736d7 100644 --- a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/Profile/ProfileSelectionStepViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/Profile/ProfileSelectionStepViewModel.cs @@ -1,7 +1,6 @@ using System; using System.Collections.ObjectModel; using System.Linq; -using System.Reactive; using System.Reactive.Disposables; using System.Reactive.Linq; using Artemis.Core; @@ -52,12 +51,6 @@ public class ProfileSelectionStepViewModel : SubmissionViewModel set => RaiseAndSetIfChanged(ref _selectedProfile, value); } - /// - public override ReactiveCommand Continue { get; } - - /// - public override ReactiveCommand GoBack { get; } - private void Update(ProfileConfiguration? profileConfiguration) { ProfilePreview.ProfileConfiguration = null; diff --git a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/SpecificationsStepView.axaml.cs b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/SpecificationsStepView.axaml.cs index f7d256121..6d05e97a1 100644 --- a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/SpecificationsStepView.axaml.cs +++ b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/SpecificationsStepView.axaml.cs @@ -1,5 +1,3 @@ -using Avalonia; -using Avalonia.Controls; using Avalonia.Markup.Xaml; using Avalonia.ReactiveUI; diff --git a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/SpecificationsStepViewModel.cs b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/SpecificationsStepViewModel.cs index ebb75cd42..4e8a17c20 100644 --- a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/SpecificationsStepViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/SpecificationsStepViewModel.cs @@ -2,41 +2,38 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Reactive; using System.Reactive.Disposables; using Artemis.UI.Extensions; using Artemis.UI.Screens.Workshop.Entries; using Artemis.UI.Screens.Workshop.SubmissionWizard.Steps.Profile; using Artemis.WebClient.Workshop; -using Avalonia.Threading; using DynamicData; using ReactiveUI; -using ReactiveUI.Validation.Extensions; namespace Artemis.UI.Screens.Workshop.SubmissionWizard.Steps; public class SpecificationsStepViewModel : SubmissionViewModel { - public SpecificationsStepViewModel(EntrySpecificationsViewModel entrySpecificationsViewModel) - { - EntrySpecificationsViewModel = entrySpecificationsViewModel; - GoBack = ReactiveCommand.Create(ExecuteGoBack); - Continue = ReactiveCommand.Create(ExecuteContinue, EntrySpecificationsViewModel.ValidationContext.Valid); + private readonly Func _getEntrySpecificationsViewModel; + private EntrySpecificationsViewModel? _entrySpecificationsViewModel; + public SpecificationsStepViewModel(Func getEntrySpecificationsViewModel) + { + _getEntrySpecificationsViewModel = getEntrySpecificationsViewModel; + + GoBack = ReactiveCommand.Create(ExecuteGoBack); this.WhenActivated((CompositeDisposable d) => { DisplayName = $"{State.EntryType} Information"; - - // Apply the state ApplyFromState(); - - EntrySpecificationsViewModel.ClearValidationRules(); }); } - public EntrySpecificationsViewModel EntrySpecificationsViewModel { get; } - public override ReactiveCommand Continue { get; } - public override ReactiveCommand GoBack { get; } + public EntrySpecificationsViewModel? EntrySpecificationsViewModel + { + get => _entrySpecificationsViewModel; + set => RaiseAndSetIfChanged(ref _entrySpecificationsViewModel, value); + } private void ExecuteGoBack() { @@ -59,46 +56,45 @@ public class SpecificationsStepViewModel : SubmissionViewModel private void ExecuteContinue() { - if (!EntrySpecificationsViewModel.ValidationContext.Validations.Any()) - { - // The ValidationContext seems to update asynchronously, so stop and schedule a retry - EntrySpecificationsViewModel.SetupDataValidation(); - Dispatcher.UIThread.Post(ExecuteContinue); + if (EntrySpecificationsViewModel == null || !EntrySpecificationsViewModel.ValidationContext.GetIsValid()) return; - } ApplyToState(); - - if (!EntrySpecificationsViewModel.ValidationContext.GetIsValid()) - return; - State.ChangeScreen(); } private void ApplyFromState() { + EntrySpecificationsViewModel viewModel = _getEntrySpecificationsViewModel(); + // Basic fields - EntrySpecificationsViewModel.Name = State.Name; - EntrySpecificationsViewModel.Summary = State.Summary; - EntrySpecificationsViewModel.Description = State.Description; + viewModel.Name = State.Name; + viewModel.Summary = State.Summary; + viewModel.Description = State.Description; // Tags - EntrySpecificationsViewModel.Tags.Clear(); - EntrySpecificationsViewModel.Tags.AddRange(State.Tags); + viewModel.Tags.Clear(); + viewModel.Tags.AddRange(State.Tags); // Categories - EntrySpecificationsViewModel.PreselectedCategories = State.Categories; + viewModel.PreselectedCategories = State.Categories; // Icon if (State.Icon != null) { State.Icon.Seek(0, SeekOrigin.Begin); - EntrySpecificationsViewModel.IconBitmap = BitmapExtensions.LoadAndResize(State.Icon, 128); + viewModel.IconBitmap = BitmapExtensions.LoadAndResize(State.Icon, 128); } + + EntrySpecificationsViewModel = viewModel; + Continue = ReactiveCommand.Create(ExecuteContinue, EntrySpecificationsViewModel.ValidationContext.Valid); } private void ApplyToState() { + if (EntrySpecificationsViewModel == null) + return; + // Basic fields State.Name = EntrySpecificationsViewModel.Name; State.Summary = EntrySpecificationsViewModel.Summary; diff --git a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/SubmitStepView.axaml.cs b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/SubmitStepView.axaml.cs index 49f0af7ff..ba64d1d7d 100644 --- a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/SubmitStepView.axaml.cs +++ b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/SubmitStepView.axaml.cs @@ -1,5 +1,3 @@ -using Avalonia; -using Avalonia.Controls; using Avalonia.Markup.Xaml; using Avalonia.ReactiveUI; diff --git a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/SubmitStepViewModel.cs b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/SubmitStepViewModel.cs index 0752ccc0d..8544c30ef 100644 --- a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/SubmitStepViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/SubmitStepViewModel.cs @@ -1,17 +1,16 @@ +using System; using System.Collections.ObjectModel; +using System.IO; using System.Linq; -using System.Reactive; using System.Reactive.Disposables; using System.Reactive.Linq; using Artemis.UI.Screens.Workshop.Categories; using Artemis.WebClient.Workshop; using Artemis.WebClient.Workshop.Services; +using Avalonia.Media.Imaging; using IdentityModel; using ReactiveUI; using StrawberryShake; -using System; -using System.IO; -using Avalonia.Media.Imaging; namespace Artemis.UI.Screens.Workshop.SubmissionWizard.Steps; @@ -26,9 +25,9 @@ public class SubmitStepViewModel : SubmissionViewModel CurrentUser = authenticationService.Claims.FirstOrDefault(c => c.Type == JwtClaimTypes.Name)?.Value; GoBack = ReactiveCommand.Create(() => State.ChangeScreen()); Continue = ReactiveCommand.Create(() => State.ChangeScreen()); - + ContinueText = "Submit"; - + this.WhenActivated(d => { if (State.Icon != null) @@ -37,6 +36,7 @@ public class SubmitStepViewModel : SubmissionViewModel IconBitmap = new Bitmap(State.Icon); IconBitmap.DisposeWith(d); } + Observable.FromAsync(workshopClient.GetCategories.ExecuteAsync).Subscribe(PopulateCategories).DisposeWith(d); }); } @@ -55,19 +55,13 @@ public class SubmitStepViewModel : SubmissionViewModel set => RaiseAndSetIfChanged(ref _categories, value); } - public override ReactiveCommand Continue { get; } - - public override ReactiveCommand GoBack { get; } - private void PopulateCategories(IOperationResult result) { if (result.Data == null) Categories = null; else - { Categories = new ReadOnlyObservableCollection( new ObservableCollection(result.Data.Categories.Where(c => State.Categories.Contains(c.Id)).Select(c => new CategoryViewModel(c))) ); - } } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/UploadStepView.axaml.cs b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/UploadStepView.axaml.cs index 7dc094d0c..21d6bb439 100644 --- a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/UploadStepView.axaml.cs +++ b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/UploadStepView.axaml.cs @@ -1,5 +1,3 @@ -using Avalonia; -using Avalonia.Controls; using Avalonia.Markup.Xaml; using Avalonia.ReactiveUI; diff --git a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/UploadStepViewModel.cs b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/UploadStepViewModel.cs index c98e44efa..7d0413714 100644 --- a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/UploadStepViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/UploadStepViewModel.cs @@ -1,5 +1,4 @@ using System; -using System.Reactive; using System.Reactive.Disposables; using System.Reactive.Linq; using System.Threading; @@ -55,12 +54,6 @@ public class UploadStepViewModel : SubmissionViewModel this.WhenActivated(d => Observable.FromAsync(ExecuteUpload).Subscribe().DisposeWith(d)); } - /// - public override ReactiveCommand Continue { get; } - - /// - public override ReactiveCommand GoBack { get; } = null!; - public int ProgressPercentage => _progressPercentage.Value; public bool ProgressIndeterminate => _progressIndeterminate.Value; diff --git a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/ValidateEmailStepViewModel.cs b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/ValidateEmailStepViewModel.cs index 3778c2673..a2a840421 100644 --- a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/ValidateEmailStepViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/ValidateEmailStepViewModel.cs @@ -27,7 +27,7 @@ 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; @@ -43,12 +43,6 @@ public class ValidateEmailStepViewModel : SubmissionViewModel }); } - /// - public override ReactiveCommand Continue { get; } - - /// - public override ReactiveCommand GoBack { get; } = null!; - public ReactiveCommand Refresh { get; } public ReactiveCommand Resend { get; } diff --git a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/WelcomeStepViewModel.cs b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/WelcomeStepViewModel.cs index 3160fbb1e..87c96fb7d 100644 --- a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/WelcomeStepViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/WelcomeStepViewModel.cs @@ -1,6 +1,4 @@ -using System; using System.Linq; -using System.Reactive; using System.Threading.Tasks; using Artemis.WebClient.Workshop.Services; using IdentityModel; @@ -21,12 +19,6 @@ public class WelcomeStepViewModel : SubmissionViewModel ShowGoBack = false; } - /// - public override ReactiveCommand Continue { get; } - - /// - public override ReactiveCommand GoBack { get; } = null!; - private async Task ExecuteContinue() { bool loggedIn = await _authenticationService.AutoLogin(true); diff --git a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/SubmissionViewModel.cs b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/SubmissionViewModel.cs index fec465981..282b34590 100644 --- a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/SubmissionViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/SubmissionViewModel.cs @@ -6,15 +6,26 @@ namespace Artemis.UI.Screens.Workshop.SubmissionWizard; public abstract class SubmissionViewModel : ValidatableViewModelBase { + private ReactiveCommand? _continue; + private ReactiveCommand? _goBack; private string _continueText = "Continue"; private bool _showFinish; private bool _showGoBack = true; private bool _showHeader = true; public SubmissionWizardState State { get; set; } = null!; - - public abstract ReactiveCommand Continue { get; } - public abstract ReactiveCommand GoBack { get; } + + public ReactiveCommand? Continue + { + get => _continue; + set => RaiseAndSetIfChanged(ref _continue, value); + } + + public ReactiveCommand? GoBack + { + get => _goBack; + set => RaiseAndSetIfChanged(ref _goBack, value); + } public bool ShowHeader { diff --git a/src/Artemis.VisualScripting/Nodes/Static/Screens/DisplayValueNodeCustomView.axaml b/src/Artemis.VisualScripting/Nodes/Static/Screens/DisplayValueNodeCustomView.axaml index 014b2bdb5..8831dd1e9 100644 --- a/src/Artemis.VisualScripting/Nodes/Static/Screens/DisplayValueNodeCustomView.axaml +++ b/src/Artemis.VisualScripting/Nodes/Static/Screens/DisplayValueNodeCustomView.axaml @@ -46,7 +46,7 @@ - + diff --git a/src/Artemis.WebClient.Workshop/Services/IWorkshopService.cs b/src/Artemis.WebClient.Workshop/Services/IWorkshopService.cs index 5c7dbd35f..d1e0fb287 100644 --- a/src/Artemis.WebClient.Workshop/Services/IWorkshopService.cs +++ b/src/Artemis.WebClient.Workshop/Services/IWorkshopService.cs @@ -16,6 +16,22 @@ public class WorkshopService : IWorkshopService _router = router; } + public async Task GetEntryIcon(Guid entryId, CancellationToken cancellationToken) + { + HttpClient client = _httpClientFactory.CreateClient(WorkshopConstants.WORKSHOP_CLIENT_NAME); + try + { + HttpResponseMessage response = await client.GetAsync($"entries/{entryId}/icon", cancellationToken); + response.EnsureSuccessStatusCode(); + return await response.Content.ReadAsStreamAsync(cancellationToken); + } + catch (HttpRequestException) + { + // ignored + return null; + } + } + public async Task SetEntryIcon(Guid entryId, Progress progress, Stream icon, CancellationToken cancellationToken) { icon.Seek(0, SeekOrigin.Begin); @@ -55,7 +71,7 @@ public class WorkshopService : IWorkshopService return new IWorkshopService.WorkshopStatus(false, e.Message); } } - + /// public async Task ValidateWorkshopStatus(CancellationToken cancellationToken) { @@ -86,10 +102,11 @@ public class WorkshopService : IWorkshopService public interface IWorkshopService { + Task GetEntryIcon(Guid entryId, CancellationToken cancellationToken); Task SetEntryIcon(Guid entryId, Progress progress, Stream icon, CancellationToken cancellationToken); Task GetWorkshopStatus(CancellationToken cancellationToken); Task ValidateWorkshopStatus(CancellationToken cancellationToken); Task NavigateToEntry(Guid entryId, EntryType entryType); - + public record WorkshopStatus(bool IsReachable, string Message); } \ No newline at end of file