using System; using System.Threading; using System.Threading.Tasks; using Artemis.Core; using Artemis.Core.Services; using Artemis.UI.Shared; using Artemis.UI.Shared.Utilities; using Artemis.WebClient.Workshop; using Artemis.WebClient.Workshop.Handlers.InstallationHandlers; using Artemis.WebClient.Workshop.Models; using Artemis.WebClient.Workshop.Providers; using Artemis.WebClient.Workshop.Services; using Material.Icons; using PropertyChanged.SourceGenerator; using StrawberryShake; namespace Artemis.UI.Screens.Workshop.LayoutFinder; public partial class LayoutFinderDeviceViewModel : ViewModelBase { private readonly IWorkshopClient _client; private readonly IDeviceService _deviceService; private readonly IWorkshopService _workshopService; private readonly WorkshopLayoutProvider _layoutProvider; [Notify] private bool _searching; [Notify] private bool _hasLayout; [Notify] private IEntrySummary? _entry; [Notify] private IRelease? _release; [Notify] private string? _logicalLayout; [Notify] private string? _physicalLayout; public LayoutFinderDeviceViewModel(ArtemisDevice device, IWorkshopClient client, IDeviceService deviceService, IWorkshopService workshopService, WorkshopLayoutProvider layoutProvider) { _client = client; _deviceService = deviceService; _workshopService = workshopService; _layoutProvider = layoutProvider; Device = device; DeviceIcon = DetermineDeviceIcon(); HasLayout = Device.Layout != null && !Device.Layout.IsDefaultLayout; } public ArtemisDevice Device { get; } public MaterialIconKind DeviceIcon { get; } public async Task Search() { if (HasLayout) return; try { Searching = true; Task delayTask = Task.Delay(400); if (Device.DeviceType == RGB.NET.Core.RGBDeviceType.Keyboard) await SearchKeyboardLayout(); else await SearchLayout(); if (Entry != null && Release != null) await InstallAndApplyEntry(Entry, Release); await delayTask; } finally { Searching = false; HasLayout = Device.Layout != null && !Device.Layout.IsDefaultLayout; } } private async Task SearchKeyboardLayout() { IOperationResult result = await _client.SearchKeyboardLayout.ExecuteAsync( Device.DeviceProvider.Plugin.Guid, Device.RgbDevice.DeviceInfo.Model, Device.RgbDevice.DeviceInfo.Manufacturer, Device.LogicalLayout, Enum.Parse(Device.PhysicalLayout.ToString(), true)); Entry = result.Data?.SearchKeyboardLayout?.Entry; Release = result.Data?.SearchKeyboardLayout?.Entry.LatestRelease; LogicalLayout = result.Data?.SearchKeyboardLayout?.LogicalLayout; PhysicalLayout = result.Data?.SearchKeyboardLayout?.PhysicalLayout.ToString(); } private async Task SearchLayout() { IOperationResult result = await _client.SearchLayout.ExecuteAsync( Enum.Parse(Device.DeviceType.ToString(), true), Device.DeviceProvider.Plugin.Guid, Device.RgbDevice.DeviceInfo.Model, Device.RgbDevice.DeviceInfo.Manufacturer); Entry = result.Data?.SearchLayout?.Entry; Release = result.Data?.SearchLayout?.Entry.LatestRelease; LogicalLayout = null; PhysicalLayout = null; } private async Task InstallAndApplyEntry(IEntrySummary entry, IRelease release) { // Try a local install first InstalledEntry? installedEntry = _workshopService.GetInstalledEntry(entry.Id); if (installedEntry == null) { EntryInstallResult result = await _workshopService.InstallEntry(entry, release, new Progress(), CancellationToken.None); installedEntry = result.Entry; } if (installedEntry != null) { _layoutProvider.ConfigureDevice(Device, installedEntry); _deviceService.SaveDevice(Device); _deviceService.LoadDeviceLayout(Device); } } private MaterialIconKind DetermineDeviceIcon() { return Device.DeviceType switch { RGB.NET.Core.RGBDeviceType.None => MaterialIconKind.QuestionMarkCircle, RGB.NET.Core.RGBDeviceType.Keyboard => MaterialIconKind.Keyboard, RGB.NET.Core.RGBDeviceType.Mouse => MaterialIconKind.Mouse, RGB.NET.Core.RGBDeviceType.Headset => MaterialIconKind.Headset, RGB.NET.Core.RGBDeviceType.Mousepad => MaterialIconKind.TextureBox, RGB.NET.Core.RGBDeviceType.LedStripe => MaterialIconKind.LightStrip, RGB.NET.Core.RGBDeviceType.LedMatrix => MaterialIconKind.DrawingBox, RGB.NET.Core.RGBDeviceType.Mainboard => MaterialIconKind.Chip, RGB.NET.Core.RGBDeviceType.GraphicsCard => MaterialIconKind.GraphicsProcessingUnit, RGB.NET.Core.RGBDeviceType.DRAM => MaterialIconKind.Memory, RGB.NET.Core.RGBDeviceType.HeadsetStand => MaterialIconKind.HeadsetDock, RGB.NET.Core.RGBDeviceType.Keypad => MaterialIconKind.Keypad, RGB.NET.Core.RGBDeviceType.Fan => MaterialIconKind.Fan, RGB.NET.Core.RGBDeviceType.Speaker => MaterialIconKind.Speaker, RGB.NET.Core.RGBDeviceType.Cooler => MaterialIconKind.FreezingPoint, RGB.NET.Core.RGBDeviceType.Monitor => MaterialIconKind.DesktopWindows, RGB.NET.Core.RGBDeviceType.LedController => MaterialIconKind.LedStripVariant, RGB.NET.Core.RGBDeviceType.GameController => MaterialIconKind.MicrosoftXboxController, RGB.NET.Core.RGBDeviceType.Unknown => MaterialIconKind.QuestionMarkCircle, RGB.NET.Core.RGBDeviceType.All => MaterialIconKind.QuestionMarkCircle, _ => MaterialIconKind.QuestionMarkCircle }; } }