diff --git a/src/Artemis.UI.Shared/Controls/ProfileConfigurationIcon.axaml.cs b/src/Artemis.UI.Shared/Controls/ProfileConfigurationIcon.axaml.cs
index 6b7fd2a02..c6e491438 100644
--- a/src/Artemis.UI.Shared/Controls/ProfileConfigurationIcon.axaml.cs
+++ b/src/Artemis.UI.Shared/Controls/ProfileConfigurationIcon.axaml.cs
@@ -6,7 +6,6 @@ using Avalonia.Controls;
using Avalonia.Controls.Documents;
using Avalonia.Layout;
using Avalonia.LogicalTree;
-using Avalonia.Markup.Xaml;
using Avalonia.Media;
using Avalonia.Media.Imaging;
using Avalonia.Threading;
@@ -43,7 +42,7 @@ public partial class ProfileConfigurationIcon : UserControl, IDisposable
if (ConfigurationIcon.IconType == ProfileConfigurationIconType.MaterialIcon)
{
Content = Enum.TryParse(ConfigurationIcon.IconName, true, out MaterialIconKind parsedIcon)
- ? new MaterialIcon {Kind = parsedIcon!}
+ ? new MaterialIcon {Kind = parsedIcon}
: new MaterialIcon {Kind = MaterialIconKind.QuestionMark};
}
else if (ConfigurationIcon.IconBytes != null)
@@ -65,19 +64,28 @@ public partial class ProfileConfigurationIcon : UserControl, IDisposable
return;
_stream = new MemoryStream(ConfigurationIcon.IconBytes);
- if (!ConfigurationIcon.Fill)
+ Border border = new()
{
- Content = new Image {Source = new Bitmap(_stream)};
- return;
+ CornerRadius = CornerRadius,
+ ClipToBounds = true,
+ VerticalAlignment = VerticalAlignment.Stretch,
+ HorizontalAlignment = HorizontalAlignment.Stretch
+
+ };
+
+ if (ConfigurationIcon.Fill)
+ {
+ // Fill mode: use Foreground as Background and the bitmap as opacity mask
+ border.Background = TextElement.GetForeground(this);
+ border.OpacityMask = new ImageBrush(new Bitmap(_stream));
+ }
+ else
+ {
+ // Non-fill mode: place the image inside the rounded border
+ border.Child = new Image { Source = new Bitmap(_stream) };
}
- Content = new Border
- {
- Background = TextElement.GetForeground(this),
- VerticalAlignment = VerticalAlignment.Stretch,
- HorizontalAlignment = HorizontalAlignment.Stretch,
- OpacityMask = new ImageBrush(new Bitmap(_stream))
- };
+ Content = border;
}
catch (Exception)
{
diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/VisualEditorView.axaml b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/VisualEditorView.axaml
index 361ca360d..6708c965b 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/VisualEditorView.axaml
+++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/VisualEditorView.axaml
@@ -89,7 +89,7 @@
Background="{DynamicResource ControlFillColorDefaultBrush}"
IsVisible="{CompiledBinding ProfileConfiguration, Converter={x:Static ObjectConverters.IsNotNull}}">
-
+
diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/VisualEditorView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/VisualEditorView.axaml.cs
index f7e4491a5..648c815ab 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/VisualEditorView.axaml.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/VisualEditor/VisualEditorView.axaml.cs
@@ -27,8 +27,9 @@ public partial class VisualEditorView : ReactiveUserControl
{
- ViewModel!.AutoFitRequested += ViewModelOnAutoFitRequested;
- Disposable.Create(() => ViewModel.AutoFitRequested -= ViewModelOnAutoFitRequested).DisposeWith(d);
+ VisualEditorViewModel? viewModel = ViewModel;
+ viewModel!.AutoFitRequested += ViewModelOnAutoFitRequested;
+ Disposable.Create(() => viewModel.AutoFitRequested -= ViewModelOnAutoFitRequested).DisposeWith(d);
});
this.WhenAnyValue(v => v.Bounds).Where(_ => !_movedByUser).Subscribe(_ => AutoFit(true));
diff --git a/src/Artemis.UI/Screens/Sidebar/SidebarProfileConfigurationView.axaml b/src/Artemis.UI/Screens/Sidebar/SidebarProfileConfigurationView.axaml
index cd4223392..5e7884967 100644
--- a/src/Artemis.UI/Screens/Sidebar/SidebarProfileConfigurationView.axaml
+++ b/src/Artemis.UI/Screens/Sidebar/SidebarProfileConfigurationView.axaml
@@ -72,15 +72,20 @@
Background="Transparent"
ContextFlyout="{StaticResource ProfileMenuFlyout}"
Classes.flyout-open="{CompiledBinding IsOpen, Source={StaticResource ProfileMenuFlyout}}">
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
c.ProfileConfigurations).FirstOrDefault(c => c.ProfileId == profileId);
if (profile == null)
return;
-
+
ProfileCategory category = _profileService.ProfileCategories.FirstOrDefault(c => c.Name == "General") ?? _profileService.CreateProfileCategory("General", true);
if (category.ProfileConfigurations.Contains(profile))
return;
-
+
+
+ // Add the profile to the category
category.AddProfileConfiguration(profile, null);
+
+ // Suspend all but the first profile in the category
+ profile.IsSuspended = category.ProfileConfigurations.Count > 1;
+
_profileService.SaveProfileCategory(category);
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/Profile/ProfileSelectionStepView.axaml b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/Profile/ProfileSelectionStepView.axaml
index 8fd0eb216..7f5aee8f8 100644
--- a/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/Profile/ProfileSelectionStepView.axaml
+++ b/src/Artemis.UI/Screens/Workshop/SubmissionWizard/Steps/Profile/ProfileSelectionStepView.axaml
@@ -38,6 +38,7 @@
Grid.Column="0"
ConfigurationIcon="{CompiledBinding Icon}"
VerticalAlignment="Center"
+ CornerRadius="4"
Width="22"
Height="22"
Margin="0 0 10 0" />
diff --git a/src/Artemis.WebClient.Workshop/Services/AuthenticationService.cs b/src/Artemis.WebClient.Workshop/Services/AuthenticationService.cs
index 7e7e76f47..3f7e65735 100644
--- a/src/Artemis.WebClient.Workshop/Services/AuthenticationService.cs
+++ b/src/Artemis.WebClient.Workshop/Services/AuthenticationService.cs
@@ -180,13 +180,15 @@ internal class AuthenticationService : CorePropertyChanged, IAuthenticationServi
{
await _authLock.WaitAsync(cancellationToken);
+ // Start a HTTP listener, this port could be in use but chances are very slim
+ // IdentityServer only accepts these two redirect URLs
+ string redirectUri = Constants.StartupArguments.Contains("--alt-login-callback") ? "http://localhost:56789" : "http://localhost:57461";
+
try
{
if (_isLoggedInSubject.Value)
return;
-
- // Start a HTTP listener, this port could be in use but chances are very slim
- string redirectUri = "http://localhost:57461";
+
using HttpListener listener = new();
listener.Prefixes.Add(redirectUri + "/");
listener.Start();
@@ -249,7 +251,11 @@ internal class AuthenticationService : CorePropertyChanged, IAuthenticationServi
}
catch (HttpListenerException e)
{
- throw new ArtemisWebClientException($"HTTP listener for login callback failed with error code {e.ErrorCode}", e);
+ // I've seen the Nvidia app do this after a login. What are the odds...
+ if (e.ErrorCode == 32)
+ throw new ArtemisWebClientException($"HTTP listener for login callback failed because another application is already listening on '{redirectUri}', please close that application and try again", e);
+ else
+ throw new ArtemisWebClientException($"HTTP listener for login callback failed with error code {e.ErrorCode}", e);
}
finally
{