mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-12 13:28:33 +00:00
Workshop - Add --alt-login-callback startup argument
UI - Rounded corners on profile icons
This commit is contained in:
parent
06c5294e88
commit
5609065974
@ -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)
|
||||
{
|
||||
|
||||
@ -89,7 +89,7 @@
|
||||
Background="{DynamicResource ControlFillColorDefaultBrush}"
|
||||
IsVisible="{CompiledBinding ProfileConfiguration, Converter={x:Static ObjectConverters.IsNotNull}}">
|
||||
<StackPanel Orientation="Horizontal" Margin="8">
|
||||
<shared:ProfileConfigurationIcon ConfigurationIcon="{CompiledBinding ProfileConfiguration.Icon}" Width="18" Height="18" Margin="0 0 5 0" />
|
||||
<shared:ProfileConfigurationIcon ConfigurationIcon="{CompiledBinding ProfileConfiguration.Icon}" Width="18" Height="18" CornerRadius="3" Margin="0 0 5 0" />
|
||||
<TextBlock Text="{CompiledBinding ProfileConfiguration.Name}" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
@ -27,8 +27,9 @@ public partial class VisualEditorView : ReactiveUserControl<VisualEditorViewMode
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
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));
|
||||
|
||||
@ -72,15 +72,20 @@
|
||||
Background="Transparent"
|
||||
ContextFlyout="{StaticResource ProfileMenuFlyout}"
|
||||
Classes.flyout-open="{CompiledBinding IsOpen, Source={StaticResource ProfileMenuFlyout}}">
|
||||
<Border CornerRadius="4" ClipToBounds="True" Grid.Column="0" Width="22" Height="22" Margin="0 0 5 0" VerticalAlignment="Center">
|
||||
<shared:ProfileConfigurationIcon x:Name="ProfileIcon" ConfigurationIcon="{CompiledBinding ProfileConfiguration.Icon}">
|
||||
<shared:ProfileConfigurationIcon Grid.Column="0"
|
||||
x:Name="ProfileIcon"
|
||||
VerticalAlignment="Center"
|
||||
ConfigurationIcon="{CompiledBinding ProfileConfiguration.Icon}"
|
||||
Width="22"
|
||||
Height="22"
|
||||
CornerRadius="4"
|
||||
Margin="0 0 5 0">
|
||||
<shared:ProfileConfigurationIcon.Transitions>
|
||||
<Transitions>
|
||||
<DoubleTransition Property="Opacity" Duration="0:0:0.2" />
|
||||
</Transitions>
|
||||
</shared:ProfileConfigurationIcon.Transitions>
|
||||
</shared:ProfileConfigurationIcon>
|
||||
</Border>
|
||||
|
||||
<Panel Grid.Column="1" HorizontalAlignment="Left">
|
||||
<TextBlock Classes="fadable"
|
||||
|
||||
@ -80,7 +80,7 @@ public partial class DefaultEntryItemViewModel : ActivatableViewModelBase
|
||||
await EnablePluginAndFeatures(result.Entry);
|
||||
// If the entry is a profile, move it to the General profile category
|
||||
else if (result.Entry?.EntryType == EntryType.Profile)
|
||||
MoveProfileToGeneral(result.Entry);
|
||||
PrepareProfile(result.Entry);
|
||||
|
||||
return result.IsSuccess;
|
||||
}
|
||||
@ -124,7 +124,7 @@ public partial class DefaultEntryItemViewModel : ActivatableViewModelBase
|
||||
}
|
||||
}
|
||||
|
||||
private void MoveProfileToGeneral(InstalledEntry entry)
|
||||
private void PrepareProfile(InstalledEntry entry)
|
||||
{
|
||||
if (!entry.TryGetMetadata("ProfileId", out Guid profileId))
|
||||
return;
|
||||
@ -137,7 +137,13 @@ public partial class DefaultEntryItemViewModel : ActivatableViewModelBase
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -38,6 +38,7 @@
|
||||
Grid.Column="0"
|
||||
ConfigurationIcon="{CompiledBinding Icon}"
|
||||
VerticalAlignment="Center"
|
||||
CornerRadius="4"
|
||||
Width="22"
|
||||
Height="22"
|
||||
Margin="0 0 10 0" />
|
||||
|
||||
@ -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,6 +251,10 @@ internal class AuthenticationService : CorePropertyChanged, IAuthenticationServi
|
||||
}
|
||||
catch (HttpListenerException 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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user