From fe933f60e8f7290fb400dcddef754c2f901f9416 Mon Sep 17 00:00:00 2001 From: Robert Date: Thu, 10 Jun 2021 17:41:54 +0200 Subject: [PATCH] Update service - Removed option to install updates without asking Modules - Decrease CPU usage for activation requirements check by using a centralized service Devices - Reload provider when unloading a layout --- .../Models/Surface/ArtemisDevice.cs | 5 -- .../ProcessActivationRequirement.cs | 23 ++++-- .../Plugins/TimedUpdateRegistration.cs | 4 ++ src/Artemis.Core/Services/CoreService.cs | 4 +- src/Artemis.Core/Services/RgbService.cs | 23 +++++- .../LayerPropertiesViewModel.cs | 15 ++-- .../ProfileTree/ProfileTreeView.xaml | 16 ++++- .../ProfileTree/ProfileTreeViewModel.cs | 29 ++++++-- .../Settings/Device/DeviceDialogViewModel.cs | 55 +++++++++++--- .../Device/Tabs/DevicePropertiesTabView.xaml | 6 +- .../Tabs/DevicePropertiesTabViewModel.cs | 16 ++--- .../Devices/DeviceSettingsTabViewModel.cs | 71 ++++++++++++------- .../Tabs/General/GeneralSettingsTabView.xaml | 21 ------ .../General/GeneralSettingsTabViewModel.cs | 14 ---- .../Screens/Sidebar/SidebarView.xaml | 12 ++-- .../Screens/Sidebar/SidebarViewModel.cs | 2 +- src/Artemis.UI/Services/UpdateService.cs | 14 ---- 17 files changed, 195 insertions(+), 135 deletions(-) diff --git a/src/Artemis.Core/Models/Surface/ArtemisDevice.cs b/src/Artemis.Core/Models/Surface/ArtemisDevice.cs index 9dec7f4bc..b8034ca26 100644 --- a/src/Artemis.Core/Models/Surface/ArtemisDevice.cs +++ b/src/Artemis.Core/Models/Surface/ArtemisDevice.cs @@ -549,11 +549,6 @@ namespace Artemis.Core else LogicalLayout = DeviceEntity.LogicalLayout; } - - public void ClearLayout() - { - // TODO - } } /// diff --git a/src/Artemis.Core/Plugins/Modules/ActivationRequirements/ProcessActivationRequirement.cs b/src/Artemis.Core/Plugins/Modules/ActivationRequirements/ProcessActivationRequirement.cs index cd43a0c9a..a773160df 100644 --- a/src/Artemis.Core/Plugins/Modules/ActivationRequirements/ProcessActivationRequirement.cs +++ b/src/Artemis.Core/Plugins/Modules/ActivationRequirements/ProcessActivationRequirement.cs @@ -3,6 +3,8 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; +using Artemis.Core.Services; +using Ninject; namespace Artemis.Core.Modules { @@ -11,6 +13,8 @@ namespace Artemis.Core.Modules /// public class ProcessActivationRequirement : IModuleActivationRequirement { + private readonly IProcessMonitorService _processMonitorService; + /// /// Creates a new instance of the class /// @@ -18,6 +22,14 @@ namespace Artemis.Core.Modules /// The location of where the process must be running from (optional) public ProcessActivationRequirement(string? processName, string? location = null) { + if (string.IsNullOrWhiteSpace(ProcessName) && string.IsNullOrWhiteSpace(Location)) + throw new ArgumentNullException($"Atleast one {nameof(processName)} and {nameof(location)} must not be null"); + + // Let's not make a habit out of this :P + if (CoreService.Kernel == null) + throw new ArtemisCoreException("Cannot create a ProcessActivationRequirement before initializing the Core"); + _processMonitorService = CoreService.Kernel.Get(); + ProcessName = processName; Location = location; } @@ -38,10 +50,13 @@ namespace Artemis.Core.Modules if (ProcessName == null && Location == null) return false; - IEnumerable processes = ProcessName != null ? Process.GetProcessesByName(ProcessName).Where(p => !p.HasExited) : Process.GetProcesses().Where(p => !p.HasExited); - return Location != null - ? processes.Any(p => string.Equals(Path.GetDirectoryName(p.GetProcessFilename()), Location, StringComparison.CurrentCultureIgnoreCase)) - : processes.Any(); + IEnumerable processes = _processMonitorService.GetRunningProcesses().Where(p => !p.HasExited); + if (ProcessName != null) + processes = processes.Where(p => string.Equals(p.ProcessName, ProcessName, StringComparison.InvariantCultureIgnoreCase)); + if (Location != null) + processes = processes.Where(p => string.Equals(Path.GetDirectoryName(p.GetProcessFilename()), Location, StringComparison.InvariantCultureIgnoreCase)); + + return processes.Any(); } /// diff --git a/src/Artemis.Core/Plugins/TimedUpdateRegistration.cs b/src/Artemis.Core/Plugins/TimedUpdateRegistration.cs index 39d5ad8cb..a2a189745 100644 --- a/src/Artemis.Core/Plugins/TimedUpdateRegistration.cs +++ b/src/Artemis.Core/Plugins/TimedUpdateRegistration.cs @@ -22,6 +22,8 @@ namespace Artemis.Core internal TimedUpdateRegistration(PluginFeature feature, TimeSpan interval, Action action, string? name) { + if (CoreService.Kernel == null) + throw new ArtemisCoreException("Cannot create a TimedUpdateRegistration before initializing the Core"); _logger = CoreService.Kernel.Get(); Feature = feature; @@ -37,6 +39,8 @@ namespace Artemis.Core internal TimedUpdateRegistration(PluginFeature feature, TimeSpan interval, Func asyncAction, string? name) { + if (CoreService.Kernel == null) + throw new ArtemisCoreException("Cannot create a TimedUpdateRegistration before initializing the Core"); _logger = CoreService.Kernel.Get(); Feature = feature; diff --git a/src/Artemis.Core/Services/CoreService.cs b/src/Artemis.Core/Services/CoreService.cs index b07ba5861..f9e64e00f 100644 --- a/src/Artemis.Core/Services/CoreService.cs +++ b/src/Artemis.Core/Services/CoreService.cs @@ -22,7 +22,7 @@ namespace Artemis.Core.Services /// internal class CoreService : ICoreService { - internal static IKernel Kernel = null!; + internal static IKernel? Kernel; private readonly Stopwatch _frameStopWatch; private readonly ILogger _logger; @@ -201,7 +201,7 @@ namespace Artemis.Core.Services Version? hidSharpVersion = Assembly.GetAssembly(typeof(HidDevice))!.GetName().Version; _logger.Debug("Forcing plugins to use HidSharp {hidSharpVersion}", hidSharpVersion); - DeserializationLogger.Initialize(Kernel); + DeserializationLogger.Initialize(Kernel!); // Initialize the services _pluginManagementService.CopyBuiltInPlugins(); diff --git a/src/Artemis.Core/Services/RgbService.cs b/src/Artemis.Core/Services/RgbService.cs index e65b74b4b..22d7b1c66 100644 --- a/src/Artemis.Core/Services/RgbService.cs +++ b/src/Artemis.Core/Services/RgbService.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; using System.Linq; +using System.Threading; using Artemis.Core.DeviceProviders; using Artemis.Core.Services.Models; using Artemis.Core.SkiaSharp; @@ -345,6 +346,13 @@ namespace Artemis.Core.Services return layout; } + if (device.DisableDefaultLayout) + { + layout = null; + ApplyDeviceLayout(device, layout); + return null; + } + // Look for a layout provided by the plugin layout = device.DeviceProvider.LoadLayout(device); if (layout.IsValid) @@ -354,8 +362,7 @@ namespace Artemis.Core.Services } // Finally fall back to a default layout - if (!device.DisableDefaultLayout) - layout = ArtemisLayout.GetDefaultLayout(device); + layout = ArtemisLayout.GetDefaultLayout(device); ApplyDeviceLayout(device, layout); return layout; } @@ -365,7 +372,7 @@ namespace Artemis.Core.Services if (layout == null) { if (device.Layout != null) - device.ClearLayout(); + ReloadDevice(device); return; } @@ -377,6 +384,16 @@ namespace Artemis.Core.Services UpdateLedGroup(); } + private void ReloadDevice(ArtemisDevice device) + { + DeviceProvider deviceProvider = device.DeviceProvider; + + // Feels bad but need to in order to get the initial LEDs back + _pluginManagementService.DisablePluginFeature(deviceProvider, false); + Thread.Sleep(500); + _pluginManagementService.EnablePluginFeature(deviceProvider, false); + } + public ArtemisDevice? GetDevice(IRGBDevice rgbDevice) { return _devices.FirstOrDefault(d => d.RgbDevice == rgbDevice); diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertiesViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertiesViewModel.cs index f566bf8d2..5aa6a6515 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertiesViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerPropertiesViewModel.cs @@ -9,6 +9,7 @@ using System.Windows.Media; using Artemis.Core; using Artemis.Core.LayerEffects; using Artemis.Core.Services; +using Artemis.UI.Extensions; using Artemis.UI.Ninject.Factories; using Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings; using Artemis.UI.Screens.ProfileEditor.LayerProperties.LayerEffects; @@ -220,7 +221,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties private void SelectedProfileEditorServiceOnSelectedProfileElementChanged(object sender, RenderProfileElementEventArgs e) { - PopulateProperties(e.RenderProfileElement); + Execute.PostToUIThread(() => PopulateProperties(e.RenderProfileElement)); } private void ProfileEditorServiceOnCurrentTimeChanged(object sender, EventArgs e) @@ -347,7 +348,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties .ToList(); // Order the effects List effectProperties = Items - .Where(l => l.TreeGroupViewModel.GroupType == LayerEffectRoot) + .Where(l => l.TreeGroupViewModel.GroupType == LayerEffectRoot && l.LayerPropertyGroup.LayerEffect != null) .OrderBy(l => l.LayerPropertyGroup.LayerEffect.Order) .ToList(); @@ -355,14 +356,16 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties for (int index = 0; index < nonEffectProperties.Count; index++) { LayerPropertyGroupViewModel layerPropertyGroupViewModel = nonEffectProperties[index]; - ((BindableCollection) Items).Move(Items.IndexOf(layerPropertyGroupViewModel), index); + if (Items.IndexOf(layerPropertyGroupViewModel) != index) + ((BindableCollection) Items).Move(Items.IndexOf(layerPropertyGroupViewModel), index); } // Put the effect properties after, sorted by their order for (int index = 0; index < effectProperties.Count; index++) { LayerPropertyGroupViewModel layerPropertyGroupViewModel = effectProperties[index]; - ((BindableCollection) Items).Move(Items.IndexOf(layerPropertyGroupViewModel), index + nonEffectProperties.Count); + if (Items.IndexOf(layerPropertyGroupViewModel) != index + nonEffectProperties.Count) + ((BindableCollection) Items).Move(Items.IndexOf(layerPropertyGroupViewModel), index + nonEffectProperties.Count); } } @@ -527,7 +530,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties Repeating = false; } } - + private TimeSpan GetCurrentSegmentStart() { TimeSpan current = ProfileEditorService.CurrentTime; @@ -637,7 +640,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties public void TimelineJump(object sender, MouseButtonEventArgs e) { // Get the parent grid, need that for our position - IInputElement parent = (IInputElement)VisualTreeHelper.GetParent((DependencyObject)sender); + IInputElement parent = (IInputElement) VisualTreeHelper.GetParent((DependencyObject) sender); double x = Math.Max(0, e.GetPosition(parent).X); TimeSpan newTime = TimeSpan.FromSeconds(x / ProfileEditorService.PixelsPerSecond); diff --git a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeView.xaml b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeView.xaml index a949eee63..ce49b864f 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeView.xaml +++ b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeView.xaml @@ -15,6 +15,15 @@ d:DataContext="{d:DesignInstance {x:Type profileTree1:ProfileTreeViewModel}}"> + + + + + + + @@ -33,7 +42,10 @@ dd:DragDrop.IsDragSource="True" dd:DragDrop.IsDropTarget="True" dd:DragDrop.DropHandler="{Binding}" - ContextMenuOpening="{s:Action ContextMenuOpening}"> + dd:DragDrop.DragAdornerTemplate="{StaticResource ElementDragTemplate}" + ContextMenuOpening="{s:Action ContextMenuOpening}" + PreviewMouseDown="{s:Action TreeViewPreviewMouseDown}" + PreviewMouseUp="{s:Action TreeViewPreviewMouseUp}"> @@ -83,7 +95,7 @@ - + diff --git a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeViewModel.cs index ea167ba29..39cd410a8 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeViewModel.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Windows; +using System.Windows.Input; using Artemis.Core; using Artemis.UI.Ninject.Factories; using Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem; @@ -15,6 +16,7 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree { private readonly IProfileEditorService _profileEditorService; private readonly IProfileTreeVmFactory _profileTreeVmFactory; + private bool _draggingTreeView; private TreeItemViewModel _selectedTreeItem; private bool _updatingTree; @@ -33,16 +35,25 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree { if (_updatingTree) return; if (!SetAndNotify(ref _selectedTreeItem, value)) return; + if (_draggingTreeView) return; - if (value != null && value.ProfileElement is RenderProfileElement renderElement) - _profileEditorService.ChangeSelectedProfileElement(renderElement); - else - _profileEditorService.ChangeSelectedProfileElement(null); + ApplySelectedTreeItem(); } } public bool CanPasteElement => _profileEditorService.GetCanPasteProfileElement(); + public void TreeViewPreviewMouseDown(object sender, MouseButtonEventArgs e) + { + _draggingTreeView = true; + } + + public void TreeViewPreviewMouseUp(object sender, MouseButtonEventArgs e) + { + _draggingTreeView = false; + ApplySelectedTreeItem(); + } + protected override void OnInitialActivate() { Subscribe(); @@ -55,6 +66,14 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree base.OnClose(); } + private void ApplySelectedTreeItem() + { + if (_selectedTreeItem != null && _selectedTreeItem.ProfileElement is RenderProfileElement renderElement) + _profileEditorService.ChangeSelectedProfileElement(renderElement); + else + _profileEditorService.ChangeSelectedProfileElement(null); + } + private void CreateRootFolderViewModel() { _updatingTree = true; @@ -64,7 +83,7 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree ActivateItem(null); return; } - + ActiveItem = _profileTreeVmFactory.FolderViewModel(folder); _updatingTree = false; } diff --git a/src/Artemis.UI/Screens/Settings/Device/DeviceDialogViewModel.cs b/src/Artemis.UI/Screens/Settings/Device/DeviceDialogViewModel.cs index 0cd156be7..97f47d8c7 100644 --- a/src/Artemis.UI/Screens/Settings/Device/DeviceDialogViewModel.cs +++ b/src/Artemis.UI/Screens/Settings/Device/DeviceDialogViewModel.cs @@ -25,9 +25,11 @@ namespace Artemis.UI.Screens.Settings.Device private readonly ICoreService _coreService; private readonly IDeviceService _deviceService; private readonly IDialogService _dialogService; + private readonly IDeviceDebugVmFactory _factory; private readonly IRgbService _rgbService; private SnackbarMessageQueue _deviceMessageQueue; private BindableCollection _selectedLeds; + private ArtemisDevice _device; public DeviceDialogViewModel(ArtemisDevice device, ICoreService coreService, @@ -40,22 +42,46 @@ namespace Artemis.UI.Screens.Settings.Device _deviceService = deviceService; _rgbService = rgbService; _dialogService = dialogService; + _factory = factory; - Device = device; PanZoomViewModel = new PanZoomViewModel(); SelectedLeds = new BindableCollection(); - Items.Add(factory.DevicePropertiesTabViewModel(device)); - if (device.DeviceType == RGBDeviceType.Keyboard) - Items.Add(factory.InputMappingsTabViewModel(device)); - Items.Add(factory.DeviceInfoTabViewModel(device)); - Items.Add(factory.DeviceLedsTabViewModel(device)); - - ActiveItem = Items.First(); - DisplayName = $"{device.RgbDevice.DeviceInfo.Model} | Artemis"; + Initialize(device); + } + + private void Initialize(ArtemisDevice device) + { + if (SelectedLeds.Any()) + SelectedLeds.Clear(); + + if (Device != null) + Device.DeviceUpdated -= DeviceOnDeviceUpdated; + Device = device; + Device.DeviceUpdated += DeviceOnDeviceUpdated; + + int activeTabIndex = 0; + if (Items.Any()) + { + activeTabIndex = Items.IndexOf(ActiveItem); + Items.Clear(); + } + Items.Add(_factory.DevicePropertiesTabViewModel(Device)); + if (Device.DeviceType == RGBDeviceType.Keyboard) + Items.Add(_factory.InputMappingsTabViewModel(Device)); + Items.Add(_factory.DeviceInfoTabViewModel(Device)); + Items.Add(_factory.DeviceLedsTabViewModel(Device)); + + ActiveItem = Items[activeTabIndex]; + DisplayName = $"{Device.RgbDevice.DeviceInfo.Model} | Artemis"; + } + + public ArtemisDevice Device + { + get => _device; + set => SetAndNotify(ref _device, value); } - public ArtemisDevice Device { get; } public PanZoomViewModel PanZoomViewModel { get; } public SnackbarMessageQueue DeviceMessageQueue @@ -84,14 +110,21 @@ namespace Artemis.UI.Screens.Settings.Device protected override void OnInitialActivate() { _coreService.FrameRendering += CoreServiceOnFrameRendering; + _rgbService.DeviceAdded += RgbServiceOnDeviceAdded; DeviceMessageQueue = new SnackbarMessageQueue(TimeSpan.FromSeconds(5)); - Device.DeviceUpdated += DeviceOnDeviceUpdated; base.OnInitialActivate(); } + private void RgbServiceOnDeviceAdded(object sender, DeviceEventArgs e) + { + if (e.Device != Device && e.Device.Identifier == Device.Identifier) + Execute.OnUIThread(() => Initialize(e.Device)); + } + protected override void OnClose() { _coreService.FrameRendering -= CoreServiceOnFrameRendering; + _rgbService.DeviceAdded -= RgbServiceOnDeviceAdded; Device.DeviceUpdated -= DeviceOnDeviceUpdated; base.OnClose(); } diff --git a/src/Artemis.UI/Screens/Settings/Device/Tabs/DevicePropertiesTabView.xaml b/src/Artemis.UI/Screens/Settings/Device/Tabs/DevicePropertiesTabView.xaml index 344e87fee..f1ff314ac 100644 --- a/src/Artemis.UI/Screens/Settings/Device/Tabs/DevicePropertiesTabView.xaml +++ b/src/Artemis.UI/Screens/Settings/Device/Tabs/DevicePropertiesTabView.xaml @@ -202,12 +202,12 @@ The device layout is used to determine the position of LEDs and to create the visual representation of the device you see on the left side of this window. - + - Use default layout if needed + Don't load default layout + ToolTip="With this enabled Artemis will not load a layout for this device unless you specifically provide one." /> diff --git a/src/Artemis.UI/Screens/Settings/Device/Tabs/DevicePropertiesTabViewModel.cs b/src/Artemis.UI/Screens/Settings/Device/Tabs/DevicePropertiesTabViewModel.cs index af4f44aa4..244b7e448 100644 --- a/src/Artemis.UI/Screens/Settings/Device/Tabs/DevicePropertiesTabViewModel.cs +++ b/src/Artemis.UI/Screens/Settings/Device/Tabs/DevicePropertiesTabViewModel.cs @@ -101,7 +101,7 @@ namespace Artemis.UI.Screens.Settings.Device.Tabs get => _displayOnDevices; set => SetAndNotify(ref _displayOnDevices, value); } - + // This solution won't scale well but I don't expect there to be many more categories. // If for some reason there will be, dynamically creating a view model per category may be more appropriate public bool HasDeskCategory @@ -134,16 +134,6 @@ namespace Artemis.UI.Screens.Settings.Device.Tabs set => SetCategory(DeviceCategory.Peripherals, value); } - public bool UseDefaultLayout - { - get => !Device.DisableDefaultLayout; - set - { - Device.DisableDefaultLayout = !value; - NotifyOfPropertyChange(nameof(UseDefaultLayout)); - } - } - public void ApplyScaling() { Device.RedScale = RedScale / 100f; @@ -266,7 +256,9 @@ namespace Artemis.UI.Screens.Settings.Device.Tabs private void DeviceOnPropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == nameof(Device.CustomLayoutPath) || e.PropertyName == nameof(Device.DisableDefaultLayout)) - _rgbService.ApplyBestDeviceLayout(Device); + { + Task.Run(() => _rgbService.ApplyBestDeviceLayout(Device)); + } } private void OnFrameRendering(object sender, FrameRenderingEventArgs e) diff --git a/src/Artemis.UI/Screens/Settings/Tabs/Devices/DeviceSettingsTabViewModel.cs b/src/Artemis.UI/Screens/Settings/Tabs/Devices/DeviceSettingsTabViewModel.cs index ee9c2f793..e775065a3 100644 --- a/src/Artemis.UI/Screens/Settings/Tabs/Devices/DeviceSettingsTabViewModel.cs +++ b/src/Artemis.UI/Screens/Settings/Tabs/Devices/DeviceSettingsTabViewModel.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Artemis.Core; using Artemis.Core.Services; using Artemis.UI.Ninject.Factories; using Artemis.UI.Shared.Services; @@ -10,9 +11,9 @@ namespace Artemis.UI.Screens.Settings.Tabs.Devices { public class DeviceSettingsTabViewModel : Conductor.Collection.AllActive { - private readonly ISettingsVmFactory _settingsVmFactory; - private readonly IRgbService _rgbService; private readonly IDialogService _dialogService; + private readonly IRgbService _rgbService; + private readonly ISettingsVmFactory _settingsVmFactory; private bool _confirmedDisable; public DeviceSettingsTabViewModel(IRgbService rgbService, IDialogService dialogService, ISettingsVmFactory settingsVmFactory) @@ -24,28 +25,6 @@ namespace Artemis.UI.Screens.Settings.Tabs.Devices _settingsVmFactory = settingsVmFactory; } - #region Overrides of AllActive - - /// - protected override void OnActivate() - { - // Take it off the UI thread to avoid freezing on tab change - Task.Run(async () => - { - if (Items.Any()) - Items.Clear(); - - await Task.Delay(200); - - List instances = _rgbService.Devices.Select(d => _settingsVmFactory.CreateDeviceSettingsViewModel(d)).ToList(); - foreach (DeviceSettingsViewModel deviceSettingsViewModel in instances) - Items.Add(deviceSettingsViewModel); - }); - base.OnActivate(); - } - - #endregion - public async Task ShowDeviceDisableDialog() { if (_confirmedDisable) @@ -61,5 +40,49 @@ namespace Artemis.UI.Screens.Settings.Tabs.Devices return confirmed; } + + private void RgbServiceOnDeviceRemoved(object sender, DeviceEventArgs e) + { + DeviceSettingsViewModel viewModel = Items.FirstOrDefault(i => i.Device == e.Device); + if (viewModel != null) + Items.Remove(viewModel); + } + + private void RgbServiceOnDeviceAdded(object sender, DeviceEventArgs e) + { + Items.Add(_settingsVmFactory.CreateDeviceSettingsViewModel(e.Device)); + } + + #region Overrides of AllActive + + /// + protected override void OnActivate() + { + _rgbService.DeviceAdded += RgbServiceOnDeviceAdded; + _rgbService.DeviceRemoved += RgbServiceOnDeviceRemoved; + // Take it off the UI thread to avoid freezing on tab change + Task.Run(async () => + { + if (Items.Any()) + Items.Clear(); + + await Task.Delay(200); + + List instances = _rgbService.Devices.Select(d => _settingsVmFactory.CreateDeviceSettingsViewModel(d)).ToList(); + foreach (DeviceSettingsViewModel deviceSettingsViewModel in instances) + Items.Add(deviceSettingsViewModel); + }); + base.OnActivate(); + } + + /// + protected override void OnClose() + { + _rgbService.DeviceAdded -= RgbServiceOnDeviceAdded; + _rgbService.DeviceRemoved -= RgbServiceOnDeviceRemoved; + base.OnClose(); + } + + #endregion } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Settings/Tabs/General/GeneralSettingsTabView.xaml b/src/Artemis.UI/Screens/Settings/Tabs/General/GeneralSettingsTabView.xaml index 7153e747c..504f87002 100644 --- a/src/Artemis.UI/Screens/Settings/Tabs/General/GeneralSettingsTabView.xaml +++ b/src/Artemis.UI/Screens/Settings/Tabs/General/GeneralSettingsTabView.xaml @@ -218,27 +218,6 @@ - - - - - - - - - - - Automatically install updates - - If enabled updates are installed automatically without asking first. - - - - - - - - diff --git a/src/Artemis.UI/Screens/Settings/Tabs/General/GeneralSettingsTabViewModel.cs b/src/Artemis.UI/Screens/Settings/Tabs/General/GeneralSettingsTabViewModel.cs index 2f8978ef4..895d903a0 100644 --- a/src/Artemis.UI/Screens/Settings/Tabs/General/GeneralSettingsTabViewModel.cs +++ b/src/Artemis.UI/Screens/Settings/Tabs/General/GeneralSettingsTabViewModel.cs @@ -158,20 +158,6 @@ namespace Artemis.UI.Screens.Settings.Tabs.General _settingsService.GetSetting("UI.CheckForUpdates", true).Value = value; _settingsService.GetSetting("UI.CheckForUpdates", true).Save(); NotifyOfPropertyChange(nameof(CheckForUpdates)); - - if (!value) - AutoInstallUpdates = false; - } - } - - public bool AutoInstallUpdates - { - get => _settingsService.GetSetting("UI.AutoInstallUpdates", false).Value; - set - { - _settingsService.GetSetting("UI.AutoInstallUpdates", false).Value = value; - _settingsService.GetSetting("UI.AutoInstallUpdates", false).Save(); - NotifyOfPropertyChange(nameof(AutoInstallUpdates)); } } diff --git a/src/Artemis.UI/Screens/Sidebar/SidebarView.xaml b/src/Artemis.UI/Screens/Sidebar/SidebarView.xaml index 85ede98d4..209f1b250 100644 --- a/src/Artemis.UI/Screens/Sidebar/SidebarView.xaml +++ b/src/Artemis.UI/Screens/Sidebar/SidebarView.xaml @@ -91,14 +91,10 @@ - - - - - + + diff --git a/src/Artemis.UI/Screens/Sidebar/SidebarViewModel.cs b/src/Artemis.UI/Screens/Sidebar/SidebarViewModel.cs index 7ed65869e..a80f0f929 100644 --- a/src/Artemis.UI/Screens/Sidebar/SidebarViewModel.cs +++ b/src/Artemis.UI/Screens/Sidebar/SidebarViewModel.cs @@ -69,7 +69,7 @@ namespace Artemis.UI.Screens.Sidebar private void UpdateHeaderDevice() { - HeaderDevice = _rgbService.Devices.FirstOrDefault(d => d.DeviceType == RGBDeviceType.Keyboard && d.Layout.IsValid); + HeaderDevice = _rgbService.Devices.FirstOrDefault(d => d.DeviceType == RGBDeviceType.Keyboard && d.Layout is {IsValid: true}); } public ArtemisDevice HeaderDevice diff --git a/src/Artemis.UI/Services/UpdateService.cs b/src/Artemis.UI/Services/UpdateService.cs index 35dada594..5e3e481ee 100644 --- a/src/Artemis.UI/Services/UpdateService.cs +++ b/src/Artemis.UI/Services/UpdateService.cs @@ -28,7 +28,6 @@ namespace Artemis.UI.Services private const double UpdateCheckInterval = 3600000; // once per hour private const string ApiUrl = "https://dev.azure.com/artemis-rgb/Artemis/_apis/"; - private readonly PluginSetting _autoInstallUpdates; private readonly PluginSetting _checkForUpdates; private readonly IDialogService _dialogService; private readonly ILogger _logger; @@ -42,7 +41,6 @@ namespace Artemis.UI.Services _windowService.MainWindowOpened += WindowServiceOnMainWindowOpened; _checkForUpdates = settingsService.GetSetting("UI.CheckForUpdates", true); - _autoInstallUpdates = settingsService.GetSetting("UI.AutoInstallUpdates", false); _checkForUpdates.SettingChanged += CheckForUpdatesOnSettingChanged; Timer timer = new(UpdateCheckInterval); @@ -136,18 +134,7 @@ namespace Artemis.UI.Services if (_windowService.IsMainWindowOpen) await OfferUpdate(buildInfo); - else if (_autoInstallUpdates.Value) - { - new ToastContentBuilder() - .AddText("Installing new version", AdaptiveTextStyle.Header) - .AddText($"Build {buildNumberDisplay} is available, currently on {Constants.BuildInfo.BuildNumberDisplay}.") - .AddProgressBar(null, null, true) - .Show(); - - await ApplyUpdate(); - } else - { // If auto-install is disabled and the window is closed, best we can do is notify the user and stop. new ToastContentBuilder() .AddText("New version available", AdaptiveTextStyle.Header) @@ -155,7 +142,6 @@ namespace Artemis.UI.Services .AddButton("Update", ToastActivationType.Background, "update") .AddButton("Later", ToastActivationType.Background, "later") .Show(t => t.Activated += TOnActivated); - } return true; }