diff --git a/src/Artemis.Core/Services/Storage/ProfileService.cs b/src/Artemis.Core/Services/Storage/ProfileService.cs index 103c1c2f1..2ecf653f3 100644 --- a/src/Artemis.Core/Services/Storage/ProfileService.cs +++ b/src/Artemis.Core/Services/Storage/ProfileService.cs @@ -363,14 +363,24 @@ internal class ProfileService : IProfileService _logger.Debug("Updating profile - Saving {Profile}", profile); profile.Save(); if (includeChildren) + { foreach (RenderProfileElement child in profile.GetAllRenderElements()) child.Save(); + } // At this point the user made actual changes, save that profile.IsFreshImport = false; profile.ProfileEntity.IsFreshImport = false; _profileRepository.Save(profile.ProfileEntity); + + // If the provided profile is external (cloned or from the workshop?) but it is loaded locally too, reload the local instance + // A bit dodge but it ensures local instances always represent the latest stored version + ProfileConfiguration? localInstance = ProfileConfigurations.FirstOrDefault(p => p.Profile != null && p.Profile != profile && p.ProfileId == profile.ProfileEntity.Id); + if (localInstance == null) + return; + DeactivateProfile(localInstance); + ActivateProfile(localInstance); } /// diff --git a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj index 15b723fd5..eabfc3924 100644 --- a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj +++ b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj @@ -15,6 +15,7 @@ + diff --git a/src/Artemis.UI/Artemis.UI.csproj b/src/Artemis.UI/Artemis.UI.csproj index 27e75baa2..d69d57955 100644 --- a/src/Artemis.UI/Artemis.UI.csproj +++ b/src/Artemis.UI/Artemis.UI.csproj @@ -23,6 +23,7 @@ + @@ -45,11 +46,4 @@ - - - - ProfileSelectionStepView.axaml - Code - - \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/EntrySpecificationsStepView.axaml b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/EntrySpecificationsStepView.axaml new file mode 100644 index 000000000..b105493c9 --- /dev/null +++ b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/EntrySpecificationsStepView.axaml @@ -0,0 +1,33 @@ + + + + + + + + + + Provide some general information on your submission below. + + + + + + + + A short summary of your submission's description + + + + The main description, Markdown supported. (A better editor planned) + + diff --git a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/EntrySpecificationsStepView.axaml.cs b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/EntrySpecificationsStepView.axaml.cs new file mode 100644 index 000000000..b57435eb7 --- /dev/null +++ b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/EntrySpecificationsStepView.axaml.cs @@ -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 +{ + public EntrySpecificationsStepView() + { + InitializeComponent(); + } + + private void InitializeComponent() + { + AvaloniaXamlLoader.Load(this); + } +} \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/EntrySpecificationsStepViewModel.cs b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/EntrySpecificationsStepViewModel.cs new file mode 100644 index 000000000..9cd5799fe --- /dev/null +++ b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/EntrySpecificationsStepViewModel.cs @@ -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 Continue { get; } + public override ReactiveCommand 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(); + 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; + } +} \ No newline at end of file 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 fd27ecccb..757d6f0c0 100644 --- a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/Profile/ProfileAdaptionHintsStepViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/Profile/ProfileAdaptionHintsStepViewModel.cs @@ -62,5 +62,6 @@ public class ProfileAdaptionHintsStepViewModel : SubmissionViewModel if (Layers.Any(l => l.AdaptionHintCount == 0)) return; + State.ChangeScreen(); } } \ No newline at end of file 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 08f9aafd0..85409e33c 100644 --- a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/Profile/ProfileSelectionStepViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/Profile/ProfileSelectionStepViewModel.cs @@ -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(_profileService.ProfileConfigurations.Select(_profileService.CloneProfileConfiguration)); + foreach (ProfileConfiguration profileConfiguration in Profiles) + _profileService.LoadProfileConfigurationIcon(profileConfiguration); + ProfilePreview = profilePreviewViewModel; GoBack = ReactiveCommand.Create(() => State.ChangeScreen()); diff --git a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/ValidateEmailStepView.axaml b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/ValidateEmailStepView.axaml index 4fc2fe76c..d6a339ccd 100644 --- a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/ValidateEmailStepView.axaml +++ b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/ValidateEmailStepView.axaml @@ -27,12 +27,21 @@ - + + + + + PS: We take this step to avoid the workshop getting spammed with low quality content. diff --git a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/ValidateEmailStepViewModel.cs b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/ValidateEmailStepViewModel.cs index cc90adb22..a6576ee88 100644 --- a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/ValidateEmailStepViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/ValidateEmailStepViewModel.cs @@ -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 GoBack { get; } = null!; public ReactiveCommand Refresh { get; } + public ReactiveCommand Resend { get; } public Claim? Email => _email?.Value; diff --git a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/SubmissionViewModel.cs b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/SubmissionViewModel.cs index d2ba60da1..3cd79cb65 100644 --- a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/SubmissionViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/SubmissionViewModel.cs @@ -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; diff --git a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/SubmissionWizardState.cs b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/SubmissionWizardState.cs index 3525d9ed2..fefb06891 100644 --- a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/SubmissionWizardState.cs +++ b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/SubmissionWizardState.cs @@ -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() where TSubmissionViewModel : SubmissionViewModel { - _wizardViewModel.Screen = _container.Resolve(); + try + { + _wizardViewModel.Screen = _container.Resolve(); + } + catch (Exception e) + { + _windowService.ShowExceptionDialog("Wizard screen failed to activate", e); + } } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/SubmissionWizardView.axaml.cs b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/SubmissionWizardView.axaml.cs index 58dade5ef..cb510d01e 100644 --- a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/SubmissionWizardView.axaml.cs +++ b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/SubmissionWizardView.axaml.cs @@ -25,9 +25,9 @@ public partial class SubmissionWizardView : ReactiveAppWindow Frame.NavigateFromObject(viewModel)); } - catch (Exception) + catch (Exception e) { - // ignored + ViewModel?.WindowService.ShowExceptionDialog("Wizard screen failed to activate", e); } } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/SubmissionWizardViewModel.cs b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/SubmissionWizardViewModel.cs index 0f3c5dc56..f2361b8ed 100644 --- a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/SubmissionWizardViewModel.cs +++ b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/SubmissionWizardViewModel.cs @@ -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 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 diff --git a/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj b/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj index aa97126e1..10b888b33 100644 --- a/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj +++ b/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj @@ -23,12 +23,4 @@ - - - - HotkeyPressNodeCustomView.axaml - Code - - - diff --git a/src/Artemis.WebClient.Workshop/WorkshopConstants.cs b/src/Artemis.WebClient.Workshop/WorkshopConstants.cs index 27ee76421..a500fa970 100644 --- a/src/Artemis.WebClient.Workshop/WorkshopConstants.cs +++ b/src/Artemis.WebClient.Workshop/WorkshopConstants.cs @@ -3,5 +3,5 @@ namespace Artemis.WebClient.Workshop; public static class WorkshopConstants { public const string AUTHORITY_URL = "https://localhost:5001"; - public const string WORKSHOP_URL = "https://workshop.artemis-rgb.com"; + public const string WORKSHOP_URL = "https://localhost:7281"; } \ No newline at end of file