1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-12 13:28:33 +00:00

Meta - Fixed a bunch of build warnings

This commit is contained in:
Robert 2023-10-18 23:13:57 +02:00
parent 6921561317
commit 1bd4efbbc5
27 changed files with 199 additions and 149 deletions

View File

@ -151,8 +151,7 @@ public static class Constants
public static ReadOnlyCollection<string> StartupArguments { get; set; } = null!;
/// <summary>
/// Gets the graphics context to be used for rendering by SkiaSharp. Can be set via
/// <see cref="IRgbService.UpdateGraphicsContext" />.
/// Gets the graphics context to be used for rendering by SkiaSharp.
/// </summary>
public static IManagedGraphicsContext? ManagedGraphicsContext { get; internal set; }
}

View File

@ -23,7 +23,6 @@ public class ProfileConfiguration : BreakableModel, IStorageModel, IDisposable
private bool _disposed;
private Hotkey? _enableHotkey;
private ProfileConfigurationHotkeyMode _hotkeyMode;
private bool _isBeingEdited;
private bool _isMissingModule;
private bool _isSuspended;
private bool _fadeInAndOut;

View File

@ -5,6 +5,7 @@ using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using Artemis.Core.DeviceProviders;
using Artemis.Core.Services;
using Artemis.Storage.Entities.Surface;
using RGB.NET.Core;
using SkiaSharp;
@ -266,7 +267,7 @@ public class ArtemisDevice : CorePropertyChanged
/// <summary>
/// Gets a boolean indicating whether this devices is enabled or not
/// <para>Note: To enable/disable a device use the methods provided by <see cref="IRgbService" /></para>
/// <para>Note: To enable/disable a device use the methods provided by <see cref="IDeviceService" /></para>
/// </summary>
public bool IsEnabled
{
@ -320,7 +321,7 @@ public class ArtemisDevice : CorePropertyChanged
}
/// <summary>
/// Gets or sets the path of the custom layout to load when calling <see cref="IRgbService.ApplyBestDeviceLayout" />
/// Gets or sets the path of the custom layout to load when calling <see cref="GetBestDeviceLayout" />
/// for this device
/// </summary>
public string? CustomLayoutPath

View File

@ -31,7 +31,7 @@ internal class PluginManagementService : IPluginManagementService
private readonly IPluginRepository _pluginRepository;
private readonly List<Plugin> _plugins;
private readonly IQueuedActionRepository _queuedActionRepository;
private FileSystemWatcher _hotReloadWatcher;
private FileSystemWatcher? _hotReloadWatcher;
private bool _disposed;
private bool _isElevated;

View File

@ -1,24 +1,49 @@
namespace Artemis.Core.Services;
/// <summary>
/// This readonly struct provides information about a process.
/// </summary>
public readonly struct ProcessInfo
{
#region Properties & Fields
/// <summary>
/// Gets the Identifier for the process.
/// </summary>
public readonly int ProcessId;
/// <summary>
/// Gets the name of the process.
/// </summary>
public readonly string ProcessName;
public readonly string ImageName; //TODO DarthAffe 01.09.2023: Do we need this if we can't get it through Process.GetProcesses()?
/// <summary>
/// Gets the Image Name of the Process.
/// </summary>
public readonly string ImageName; // TODO DarthAffe 01.09.2023: Do we need this if we can't get it through Process.GetProcesses()?
/// <summary>
/// Gets the Executable associated with the Process.
/// </summary>
public readonly string Executable;
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="ProcessInfo"/> struct.
/// </summary>
/// <param name="processId">The identifier for the process.</param>
/// <param name="processName">The name of the process.</param>
/// <param name="imageName">The Image Name of the process.</param>
/// <param name="executable">The executable associated with the process.</param>
public ProcessInfo(int processId, string processName, string imageName, string executable)
{
this.ProcessId = processId;
this.ProcessName = processName;
this.ImageName = imageName;
this.Executable = executable;
ProcessId = processId;
ProcessName = processName;
ImageName = imageName;
Executable = executable;
}
#endregion

View File

@ -15,7 +15,7 @@ public class LostFocusTextBoxBindingBehavior : Behavior<TextBox>
/// <summary>
/// Gets or sets the value of the binding.
/// </summary>
public static readonly StyledProperty<string> TextProperty = AvaloniaProperty.Register<LostFocusTextBoxBindingBehavior, string>(
public static readonly StyledProperty<string?> TextProperty = AvaloniaProperty.Register<LostFocusTextBoxBindingBehavior, string?>(
"Text", defaultBindingMode: BindingMode.TwoWay);
static LostFocusTextBoxBindingBehavior()
@ -26,7 +26,7 @@ public class LostFocusTextBoxBindingBehavior : Behavior<TextBox>
/// <summary>
/// Gets or sets the value of the binding.
/// </summary>
public string Text
public string? Text
{
get => GetValue(TextProperty);
set => SetValue(TextProperty, value);

View File

@ -305,7 +305,7 @@ public class DeviceVisualizer : Control
{
_deviceImage = await Task.Run(() => GetDeviceImage(device));
}
catch (Exception e)
catch (Exception)
{
// ignored
}

View File

@ -19,32 +19,32 @@ namespace Artemis.UI.Shared.Pagination;
[TemplatePart("PART_PagesView", typeof(StackPanel))]
public partial class Pagination : TemplatedControl
{
private Button? _previousButton;
private Button? _nextButton;
private StackPanel? _pagesView;
/// <inheritdoc />
public Pagination()
{
PropertyChanged += OnPropertyChanged;
}
public Button? PreviousButton { get; set; }
public Button? NextButton { get; set; }
public StackPanel? PagesView { get; set; }
/// <inheritdoc />
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
if (PreviousButton != null)
PreviousButton.Click -= PreviousButtonOnClick;
if (NextButton != null)
NextButton.Click -= NextButtonOnClick;
if (_previousButton != null)
_previousButton.Click -= PreviousButtonOnClick;
if (_nextButton != null)
_nextButton.Click -= NextButtonOnClick;
PreviousButton = e.NameScope.Find<Button>("PART_PreviousButton");
NextButton = e.NameScope.Find<Button>("PART_NextButton");
PagesView = e.NameScope.Find<StackPanel>("PART_PagesView");
_previousButton = e.NameScope.Find<Button>("PART_PreviousButton");
_nextButton = e.NameScope.Find<Button>("PART_NextButton");
_pagesView = e.NameScope.Find<StackPanel>("PART_PagesView");
if (PreviousButton != null)
PreviousButton.Click += PreviousButtonOnClick;
if (NextButton != null)
NextButton.Click += NextButtonOnClick;
if (_previousButton != null)
_previousButton.Click += PreviousButtonOnClick;
if (_nextButton != null)
_nextButton.Click += NextButtonOnClick;
Update();
}
@ -69,40 +69,40 @@ public partial class Pagination : TemplatedControl
private void Update()
{
if (PagesView == null)
if (_pagesView == null)
return;
List<int> pages = GetPages(Value, Maximum);
// Remove extra children
while (PagesView.Children.Count > pages.Count)
while (_pagesView.Children.Count > pages.Count)
{
PagesView.Children.RemoveAt(PagesView.Children.Count - 1);
_pagesView.Children.RemoveAt(_pagesView.Children.Count - 1);
}
if (PagesView.Children.Count > pages.Count)
PagesView.Children.RemoveRange(0, PagesView.Children.Count - pages.Count);
if (_pagesView.Children.Count > pages.Count)
_pagesView.Children.RemoveRange(0, _pagesView.Children.Count - pages.Count);
// Add/modify children
for (int i = 0; i < pages.Count; i++)
{
int page = pages[i];
// -1 indicates an ellipsis (...)
if (page == -1)
{
if (PagesView.Children.ElementAtOrDefault(i) is not PaginationEllipsis)
if (_pagesView.Children.ElementAtOrDefault(i) is not PaginationEllipsis)
{
if (PagesView.Children.Count - 1 >= i)
PagesView.Children[i] = new PaginationEllipsis();
if (_pagesView.Children.Count - 1 >= i)
_pagesView.Children[i] = new PaginationEllipsis();
else
PagesView.Children.Add(new PaginationEllipsis());
_pagesView.Children.Add(new PaginationEllipsis());
}
}
// Anything else indicates a regular page
else
{
if (PagesView.Children.ElementAtOrDefault(i) is PaginationPage paginationPage)
if (_pagesView.Children.ElementAtOrDefault(i) is PaginationPage paginationPage)
{
paginationPage.Page = page;
paginationPage.Command = ReactiveCommand.Create(() => Value = page);
@ -110,14 +110,14 @@ public partial class Pagination : TemplatedControl
}
paginationPage = new PaginationPage {Page = page, Command = ReactiveCommand.Create(() => Value = page)};
if (PagesView.Children.Count - 1 >= i)
PagesView.Children[i] = paginationPage;
if (_pagesView.Children.Count - 1 >= i)
_pagesView.Children[i] = paginationPage;
else
PagesView.Children.Add(paginationPage);
_pagesView.Children.Add(paginationPage);
}
}
foreach (Control child in PagesView.Children)
foreach (Control child in _pagesView.Children)
{
if (child is PaginationPage paginationPage)
((IPseudoClasses) paginationPage.Classes).Set(":selected", paginationPage.Page == Value);

View File

@ -8,10 +8,17 @@ using ReactiveUI;
namespace Artemis.UI.Shared.TagsInput;
/// <summary>
/// Represents an input for tags.
/// </summary>
[TemplatePart("PART_TagInputBox", typeof(TextBox))]
public partial class TagsInput : TemplatedControl
{
public TextBox? TagInputBox { get; set; }
private TextBox? _tagInputBox;
/// <summary>
/// Gets the command that is to be called when removing a tag
/// </summary>
public ICommand RemoveTag { get; }
/// <inheritdoc />
@ -23,18 +30,18 @@ public partial class TagsInput : TemplatedControl
/// <inheritdoc />
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
if (TagInputBox != null)
if (_tagInputBox != null)
{
TagInputBox.KeyDown -= TagInputBoxOnKeyDown;
TagInputBox.TextChanging -= TagInputBoxOnTextChanging;
_tagInputBox.KeyDown -= TagInputBoxOnKeyDown;
_tagInputBox.TextChanging -= TagInputBoxOnTextChanging;
}
TagInputBox = e.NameScope.Find<TextBox>("PART_TagInputBox");
_tagInputBox = e.NameScope.Find<TextBox>("PART_TagInputBox");
if (TagInputBox != null)
if (_tagInputBox != null)
{
TagInputBox.KeyDown += TagInputBoxOnKeyDown;
TagInputBox.TextChanging += TagInputBoxOnTextChanging;
_tagInputBox.KeyDown += TagInputBoxOnKeyDown;
_tagInputBox.TextChanging += TagInputBoxOnTextChanging;
}
}
@ -42,21 +49,21 @@ public partial class TagsInput : TemplatedControl
{
Tags.Remove(t);
if (TagInputBox != null)
TagInputBox.IsEnabled = Tags.Count < MaxLength;
if (_tagInputBox != null)
_tagInputBox.IsEnabled = Tags.Count < MaxLength;
}
private void TagInputBoxOnTextChanging(object? sender, TextChangingEventArgs e)
{
if (TagInputBox?.Text == null)
if (_tagInputBox?.Text == null)
return;
TagInputBox.Text = CleanTagRegex().Replace(TagInputBox.Text.ToLower(), "");
_tagInputBox.Text = CleanTagRegex().Replace(_tagInputBox.Text.ToLower(), "");
}
private void TagInputBoxOnKeyDown(object? sender, KeyEventArgs e)
{
if (TagInputBox == null)
if (_tagInputBox == null)
return;
if (e.Key == Key.Space)
@ -64,13 +71,13 @@ public partial class TagsInput : TemplatedControl
if (e.Key != Key.Enter)
return;
if (string.IsNullOrWhiteSpace(TagInputBox.Text) || Tags.Contains(TagInputBox.Text) || Tags.Count >= MaxLength)
if (string.IsNullOrWhiteSpace(_tagInputBox.Text) || Tags.Contains(_tagInputBox.Text) || Tags.Count >= MaxLength)
return;
Tags.Add(CleanTagRegex().Replace(TagInputBox.Text.ToLower(), ""));
Tags.Add(CleanTagRegex().Replace(_tagInputBox.Text.ToLower(), ""));
TagInputBox.Text = "";
TagInputBox.IsEnabled = Tags.Count < MaxLength;
_tagInputBox.Text = "";
_tagInputBox.IsEnabled = Tags.Count < MaxLength;
}
[GeneratedRegex("[\\s\\-]+")]

View File

@ -2,6 +2,9 @@ using System;
namespace Artemis.UI.Shared;
/// <summary>
/// Represents errors that occur within the Artemis router.
/// </summary>
public class ArtemisRoutingException : Exception
{
/// <inheritdoc />

View File

@ -5,50 +5,60 @@ using System.Threading;
using System.Threading.Tasks;
using Artemis.UI.Shared.Utilities;
namespace Artemis.UI.Shared.Extensions
namespace Artemis.UI.Shared.Extensions;
/// <summary>
/// Provides extension methods for the <see cref="HttpClient" /> type.
/// </summary>
public static class HttpClientProgressExtensions
{
public static class HttpClientProgressExtensions
/// <summary>
/// Send a GET request to the specified Uri with an HTTP completion option and a cancellation token as an asynchronous operation.
/// </summary>
/// <param name="client">The HTTP client to use.</param>
/// <param name="requestUrl">The Uri the request is sent to.</param>
/// <param name="destination">The destination stream.</param>
/// <param name="progress">The progress instance to use for progress indication.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
public static async Task DownloadDataAsync(this HttpClient client, string requestUrl, Stream destination, IProgress<StreamProgress>? progress, CancellationToken cancellationToken)
{
public static async Task DownloadDataAsync(this HttpClient client, string requestUrl, Stream destination, IProgress<StreamProgress>? progress, CancellationToken cancellationToken)
using HttpResponseMessage response = await client.GetAsync(requestUrl, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
response.EnsureSuccessStatusCode();
long? contentLength = response.Content.Headers.ContentLength;
await using Stream download = await response.Content.ReadAsStreamAsync(cancellationToken);
// no progress... no contentLength... very sad
if (progress is null || !contentLength.HasValue)
{
using HttpResponseMessage response = await client.GetAsync(requestUrl, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
response.EnsureSuccessStatusCode();
long? contentLength = response.Content.Headers.ContentLength;
await using Stream download = await response.Content.ReadAsStreamAsync(cancellationToken);
// no progress... no contentLength... very sad
if (progress is null || !contentLength.HasValue)
{
await download.CopyToAsync(destination, cancellationToken);
return;
}
// Such progress and contentLength much reporting Wow!
await download.CopyToAsync(destination, 81920, progress, contentLength, cancellationToken);
await download.CopyToAsync(destination, cancellationToken);
return;
}
static async Task CopyToAsync(this Stream source, Stream destination, int bufferSize, IProgress<StreamProgress> progress, long? contentLength, CancellationToken cancellationToken)
{
if (bufferSize < 0)
throw new ArgumentOutOfRangeException(nameof(bufferSize));
if (source is null)
throw new ArgumentNullException(nameof(source));
if (!source.CanRead)
throw new InvalidOperationException($"'{nameof(source)}' is not readable.");
if (destination == null)
throw new ArgumentNullException(nameof(destination));
if (!destination.CanWrite)
throw new InvalidOperationException($"'{nameof(destination)}' is not writable.");
// Such progress and contentLength much reporting Wow!
await download.CopyToAsync(destination, 81920, progress, contentLength, cancellationToken);
}
byte[] buffer = new byte[bufferSize];
long totalBytesRead = 0;
int bytesRead;
while ((bytesRead = await source.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false)) != 0)
{
await destination.WriteAsync(buffer, 0, bytesRead, cancellationToken).ConfigureAwait(false);
totalBytesRead += bytesRead;
progress?.Report(new StreamProgress(totalBytesRead, contentLength ?? totalBytesRead));
}
private static async Task CopyToAsync(this Stream source, Stream destination, int bufferSize, IProgress<StreamProgress> progress, long? contentLength, CancellationToken cancellationToken)
{
if (bufferSize < 0)
throw new ArgumentOutOfRangeException(nameof(bufferSize));
if (source is null)
throw new ArgumentNullException(nameof(source));
if (!source.CanRead)
throw new InvalidOperationException($"'{nameof(source)}' is not readable.");
if (destination == null)
throw new ArgumentNullException(nameof(destination));
if (!destination.CanWrite)
throw new InvalidOperationException($"'{nameof(destination)}' is not writable.");
byte[] buffer = new byte[bufferSize];
long totalBytesRead = 0;
int bytesRead;
while ((bytesRead = await source.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false)) != 0)
{
await destination.WriteAsync(buffer, 0, bytesRead, cancellationToken).ConfigureAwait(false);
totalBytesRead += bytesRead;
progress?.Report(new StreamProgress(totalBytesRead, contentLength ?? totalBytesRead));
}
}
}

View File

@ -61,7 +61,10 @@ internal class WindowService : IWindowService
public async Task ShowDialogAsync(object viewModel)
{
Window? parent = GetCurrentWindow();
if (parent == null)
throw new ArtemisSharedUIException("Failed to get the current window.");
string name = viewModel.GetType().FullName!.Split('`')[0].Replace("ViewModel", "View");
Type? type = viewModel.GetType().Assembly.GetType(name);
@ -100,6 +103,9 @@ internal class WindowService : IWindowService
public async Task<TResult> ShowDialogAsync<TResult>(DialogViewModelBase<TResult> viewModel)
{
Window? parent = GetCurrentWindow();
if (parent == null)
throw new ArtemisSharedUIException("Failed to get the current window.");
string name = viewModel.GetType().FullName!.Split('`')[0].Replace("ViewModel", "View");
Type? type = viewModel.GetType().Assembly.GetType(name);

View File

@ -18,6 +18,9 @@ public static class UI
{
private static readonly BehaviorSubject<bool> MicaEnabledSubject = new(false);
/// <summary>
/// Gets the background event loop scheduler.
/// </summary>
public static EventLoopScheduler BackgroundScheduler = new(ts => new Thread(ts));
static UI()

View File

@ -33,9 +33,9 @@ public static class ArtemisBootstrapper
{
if (_application != null || _container != null)
throw new ArtemisUIException("UI already bootstrapped");
Utilities.PrepareFirstLaunch();
application.RequestedThemeVariant = ThemeVariant.Dark;
_application = application;
_container = new Container(rules => rules
@ -52,7 +52,7 @@ public static class ArtemisBootstrapper
configureServices?.Invoke(_container);
_container.UseDryIocDependencyResolver();
Logger.Sink = _container.Resolve<SerilogAvaloniaSink>();
return _container;
}
@ -64,7 +64,7 @@ public static class ArtemisBootstrapper
if (_application.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop)
return;
Constants.StartupArguments = new ReadOnlyCollection<string>(new List<string>(desktop.Args));
Constants.StartupArguments = new ReadOnlyCollection<string>(desktop.Args != null ? new List<string>(desktop.Args) : new List<string>());
// Don't shut down when the last window closes, we might still be active in the tray
desktop.ShutdownMode = ShutdownMode.OnExplicitShutdown;

View File

@ -1,15 +1,10 @@
using Artemis.UI.Shared;
using Artemis.UI.Shared;
using System;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reactive.Disposables;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Artemis.Core;
using Artemis.Core.Services;
using Artemis.UI.Shared;
using Artemis.UI.Shared.Services;
using ReactiveUI;
using RGB.NET.Core;
@ -50,10 +45,10 @@ public class DeviceGeneralTabViewModel : ActivatableViewModelBase
Device = device;
DisplayName = "General";
X = (int)Device.X;
Y = (int)Device.Y;
X = (int) Device.X;
Y = (int) Device.Y;
Scale = Device.Scale;
Rotation = (int)Device.Rotation;
Rotation = (int) Device.Rotation;
RedScale = Device.RedScale * 100f;
GreenScale = Device.GreenScale * 100f;
BlueScale = Device.BlueScale * 100f;
@ -234,7 +229,7 @@ public class DeviceGeneralTabViewModel : ActivatableViewModelBase
if (!DisplayOnDevices)
return;
using SKPaint overlayPaint = new() { Color = CurrentColor };
using SKPaint overlayPaint = new() {Color = CurrentColor};
e.Canvas.DrawRect(0, 0, e.Canvas.LocalClipBounds.Width, e.Canvas.LocalClipBounds.Height, overlayPaint);
}
}

View File

@ -1,8 +1,5 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using Avalonia.ReactiveUI;
namespace Artemis.UI.Screens.Device;
@ -18,17 +15,17 @@ public partial class DeviceLayoutTabView : ReactiveUserControl<DeviceLayoutTabVi
{
if (ViewModel?.DefaultLayoutPath is null)
return;
TopLevel.GetTopLevel(this).Clipboard.SetTextAsync(ViewModel.DefaultLayoutPath);
TopLevel.GetTopLevel(this)?.Clipboard?.SetTextAsync(ViewModel.DefaultLayoutPath);
ViewModel.ShowCopiedNotification();
}
private void ImagePathButton_OnClick(object? sender, RoutedEventArgs e)
{
if (ViewModel?.Device?.Layout?.Image?.LocalPath is null)
if (ViewModel?.Device.Layout?.Image?.LocalPath is null)
return;
TopLevel.GetTopLevel(this).Clipboard.SetTextAsync(ViewModel.Device.Layout.Image.LocalPath);
TopLevel.GetTopLevel(this)?.Clipboard?.SetTextAsync(ViewModel.Device.Layout.Image.LocalPath);
ViewModel.ShowCopiedNotification();
}
}

View File

@ -25,8 +25,10 @@ public partial class DeviceLogicalLayoutDialogView : ReactiveUserControl<DeviceL
RegionsAutoCompleteBox.PopulateComplete();
}
private bool SearchRegions(string search, object item)
private bool SearchRegions(string? search, object? item)
{
if (search == null)
return true;
if (item is not RegionInfo regionInfo)
return false;

View File

@ -11,7 +11,7 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.Dialogs.AdaptionHints;
public partial class SingleLedAdaptionHintViewModel : AdaptionHintViewModelBase
{
[Notify] private List<AdaptionLed> _adaptionLeds;
[Notify] private List<AdaptionLed> _adaptionLeds = new();
[Notify] private AdaptionLed? _selectedLed;
public SingleLedAdaptionHintViewModel(Layer layer, SingleLedAdaptionHint adaptionHint) : base(layer, adaptionHint)

View File

@ -5,7 +5,6 @@ using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Layout;
using Avalonia.LogicalTree;
using Avalonia.Markup.Xaml;
using Avalonia.Media;
using Avalonia.Media.Imaging;
using Avalonia.ReactiveUI;
@ -40,7 +39,8 @@ public partial class ProfileTreeView : ReactiveUserControl<ProfileTreeViewModel>
private void CreateDragAdorner(DragEventArgs e)
{
if (_dragAdorner != null)
Window? window = this.FindAncestorOfType<Window>();
if (window == null || _dragAdorner != null)
return;
if (e.Source is not Control c)
@ -55,7 +55,7 @@ public partial class ProfileTreeView : ReactiveUserControl<ProfileTreeViewModel>
ITransform? originalTransform = container.RenderTransform;
try
{
_dragStartPosition = e.GetPosition(this.FindAncestorOfType<Window>());
_dragStartPosition = e.GetPosition(window);
_elementDragOffset = e.GetPosition(container);
RenderTargetBitmap renderTarget = new(new PixelSize((int) container.Bounds.Width, (int) container.Bounds.Height));
@ -106,10 +106,11 @@ public partial class ProfileTreeView : ReactiveUserControl<ProfileTreeViewModel>
private void UpdateDragAdorner(DragEventArgs e)
{
if (_dragAdorner == null)
Window? window = this.FindAncestorOfType<Window>();
if (window == null || _dragAdorner == null)
return;
Point position = e.GetPosition(this.FindAncestorOfType<Window>());
Point position = e.GetPosition(window);
_dragAdorner.RenderTransform = new TranslateTransform(_dragStartPosition.X - _elementDragOffset.X, position.Y - _elementDragOffset.Y);
}

View File

@ -15,7 +15,7 @@ public partial class RootView : ReactiveUserControl<RootViewModel>
this.WhenActivated(d => ViewModel.WhenAnyValue(vm => vm.Screen).Subscribe(Navigate).DisposeWith(d));
}
private void Navigate(RoutableScreen viewModel)
private void Navigate(RoutableScreen? viewModel)
{
try
{

View File

@ -23,7 +23,7 @@ public partial class ReleasesTabView : ReactiveUserControl<ReleasesTabViewModel>
{
ReleaseFrame.NavigateFromObject(viewModel);
}
catch (Exception e)
catch (Exception)
{
// ignored
}

View File

@ -202,14 +202,17 @@ public class ProfileConfigurationEditViewModel : DialogViewModelBase<ProfileConf
{
// Preselect the icon based on streams if needed
if (_profileConfiguration.Icon.IconType == ProfileConfigurationIconType.BitmapImage)
{
try
{
SelectedBitmapSource = new Bitmap(_profileConfiguration.Icon.GetIconStream());
Stream? iconStream = _profileConfiguration.Icon.GetIconStream();
SelectedBitmapSource = iconStream != null ? new Bitmap(iconStream) : null;
}
catch (Exception e)
{
_windowService.ShowConfirmContentDialog("Failed to load profile icon", e.Message, "Meh", null);
}
}
// Prepare the contents of the dropdown box, it should be virtualized so no need to wait with this
ObservableCollection<ProfileIconViewModel> icons = new(Enum.GetValues<MaterialIconKind>()

View File

@ -49,7 +49,8 @@ public partial class SidebarCategoryView : ReactiveUserControl<SidebarCategoryVi
private void CreateDragAdorner(DragEventArgs e)
{
if (_dragAdorner != null)
Window? window = this.FindAncestorOfType<Window>();
if (window == null || _dragAdorner != null)
return;
if (e.Source is not Control c)
@ -64,7 +65,7 @@ public partial class SidebarCategoryView : ReactiveUserControl<SidebarCategoryVi
ITransform? originalTransform = container.RenderTransform;
try
{
_dragStartPosition = e.GetPosition(this.FindAncestorOfType<Window>());
_dragStartPosition = e.GetPosition(window);
_elementDragOffset = e.GetPosition(container);
RenderTargetBitmap renderTarget = new(new PixelSize((int) container.Bounds.Width, (int) container.Bounds.Height));
@ -88,7 +89,9 @@ public partial class SidebarCategoryView : ReactiveUserControl<SidebarCategoryVi
private void HandleDragOver(object? sender, DragEventArgs e)
{
UpdateDragAdorner(e.GetPosition(this.FindAncestorOfType<Window>()));
Window? window = this.FindAncestorOfType<Window>();
if (window != null)
UpdateDragAdorner(e.GetPosition(window));
}
private void HandleLeaveEvent(object? sender, RoutedEventArgs e)

View File

@ -1,10 +1,8 @@
using System;
using System.Reactive;
using System.Threading;
using System.Threading.Tasks;
using Artemis.UI.Shared;
using Artemis.UI.Shared.Routing;
using Artemis.WebClient.Workshop;
using Artemis.WebClient.Workshop.Services;
using ReactiveUI;
@ -14,7 +12,7 @@ public class WorkshopOfflineViewModel : RoutableScreen<WorkshopOfflineParameters
{
private readonly IRouter _router;
private readonly IWorkshopService _workshopService;
private string _message;
private string _message = string.Empty;
/// <inheritdoc />
public WorkshopOfflineViewModel(IWorkshopService workshopService, IRouter router)
@ -51,5 +49,5 @@ public class WorkshopOfflineViewModel : RoutableScreen<WorkshopOfflineParameters
public class WorkshopOfflineParameters
{
public string Message { get; set; }
public string Message { get; set; } = string.Empty;
}

View File

@ -11,7 +11,7 @@ namespace Artemis.VisualScripting.Converters;
public class JsonConverter : IValueConverter
{
/// <inheritdoc />
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
return JsonConvert.SerializeObject(value, Formatting.Indented);
}
@ -19,8 +19,7 @@ public class JsonConverter : IValueConverter
/// <inheritdoc />
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value == null)
return null;
return JsonConvert.DeserializeObject(value.ToString(), targetType);
string? json = value?.ToString();
return json == null ? null : JsonConvert.DeserializeObject(json, targetType);
}
}

View File

@ -44,7 +44,7 @@ public class EnumEqualsNodeCustomViewModel : CustomNodeViewModel
public ObservableCollection<EnumValueItem> EnumValues { get; } = new();
public EnumValueItem CurrentValue
public EnumValueItem? CurrentValue
{
get => EnumValues.FirstOrDefault(v => v.Value == _node.Storage);
set

View File

@ -2,6 +2,5 @@ namespace Artemis.WebClient.Workshop.Entities;
public class RefreshTokenEntity
{
public string RefreshToken { get; set; }
public string RefreshToken { get; set; } = string.Empty;
}