mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-31 09:43:46 +00:00
Storage - Got it to build and even run
This commit is contained in:
parent
10850adb24
commit
41a7543778
@ -31,6 +31,7 @@ public static class ContainerExtensions
|
|||||||
|
|
||||||
// Bind storage
|
// Bind storage
|
||||||
container.RegisterDelegate(() => StorageManager.CreateRepository(Constants.DataFolder), Reuse.Singleton);
|
container.RegisterDelegate(() => StorageManager.CreateRepository(Constants.DataFolder), Reuse.Singleton);
|
||||||
|
container.RegisterDelegate(() => StorageManager.CreateDbContext(Constants.DataFolder), Reuse.Transient);
|
||||||
container.RegisterMany(storageAssembly, type => type.IsAssignableTo<IRepository>(), Reuse.Singleton);
|
container.RegisterMany(storageAssembly, type => type.IsAssignableTo<IRepository>(), Reuse.Singleton);
|
||||||
|
|
||||||
// Bind migrations
|
// Bind migrations
|
||||||
|
|||||||
@ -175,7 +175,7 @@ public class ProfileCategory : CorePropertyChanged, IStorageModel
|
|||||||
Order = Entity.Order;
|
Order = Entity.Order;
|
||||||
|
|
||||||
_profileConfigurations.Clear();
|
_profileConfigurations.Clear();
|
||||||
foreach (ProfileConfigurationEntity entityProfileConfiguration in Entity.ProfileConfigurations)
|
foreach (ProfileContainerEntity entityProfileConfiguration in Entity.ProfileConfigurations)
|
||||||
_profileConfigurations.Add(new ProfileConfiguration(this, entityProfileConfiguration));
|
_profileConfigurations.Add(new ProfileConfiguration(this, entityProfileConfiguration));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,11 +188,8 @@ public class ProfileCategory : CorePropertyChanged, IStorageModel
|
|||||||
Entity.Order = Order;
|
Entity.Order = Order;
|
||||||
|
|
||||||
Entity.ProfileConfigurations.Clear();
|
Entity.ProfileConfigurations.Clear();
|
||||||
foreach (ProfileConfiguration profileConfiguration in ProfileConfigurations)
|
foreach (ProfileConfiguration profileConfiguration in _profileConfigurations)
|
||||||
{
|
|
||||||
profileConfiguration.Save();
|
|
||||||
Entity.ProfileConfigurations.Add(profileConfiguration.Entity);
|
Entity.ProfileConfigurations.Add(profileConfiguration.Entity);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@ -37,13 +37,13 @@ public class ProfileConfiguration : BreakableModel, IStorageModel, IDisposable,
|
|||||||
_name = name;
|
_name = name;
|
||||||
_category = category;
|
_category = category;
|
||||||
|
|
||||||
Entity = new ProfileConfigurationEntity();
|
Entity = new ProfileContainerEntity();
|
||||||
Icon = new ProfileConfigurationIcon(Entity);
|
Icon = new ProfileConfigurationIcon(Entity);
|
||||||
Icon.SetIconByName(icon);
|
Icon.SetIconByName(icon);
|
||||||
ActivationCondition = new NodeScript<bool>("Activate profile", "Whether or not the profile should be active", this);
|
ActivationCondition = new NodeScript<bool>("Activate profile", "Whether or not the profile should be active", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal ProfileConfiguration(ProfileCategory category, ProfileConfigurationEntity entity)
|
internal ProfileConfiguration(ProfileCategory category, ProfileContainerEntity entity)
|
||||||
{
|
{
|
||||||
// Will be loaded from the entity
|
// Will be loaded from the entity
|
||||||
_name = null!;
|
_name = null!;
|
||||||
@ -192,12 +192,12 @@ public class ProfileConfiguration : BreakableModel, IStorageModel, IDisposable,
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the entity used by this profile config
|
/// Gets the entity used by this profile config
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ProfileConfigurationEntity Entity { get; }
|
public ProfileContainerEntity Entity { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the ID of the profile of this profile configuration
|
/// Gets the ID of the profile of this profile configuration
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Guid ProfileId => Entity.ProfileId;
|
public Guid ProfileId => Entity.Profile.Id;
|
||||||
|
|
||||||
#region Overrides of BreakableModel
|
#region Overrides of BreakableModel
|
||||||
|
|
||||||
@ -265,8 +265,8 @@ public class ProfileConfiguration : BreakableModel, IStorageModel, IDisposable,
|
|||||||
if (_disposed)
|
if (_disposed)
|
||||||
throw new ObjectDisposedException("ProfileConfiguration");
|
throw new ObjectDisposedException("ProfileConfiguration");
|
||||||
|
|
||||||
Module = enabledModules.FirstOrDefault(m => m.Id == Entity.ModuleId);
|
Module = enabledModules.FirstOrDefault(m => m.Id == Entity.ProfileConfiguration.ModuleId);
|
||||||
IsMissingModule = Module == null && Entity.ModuleId != null;
|
IsMissingModule = Module == null && Entity.ProfileConfiguration.ModuleId != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@ -284,20 +284,20 @@ public class ProfileConfiguration : BreakableModel, IStorageModel, IDisposable,
|
|||||||
if (_disposed)
|
if (_disposed)
|
||||||
throw new ObjectDisposedException("ProfileConfiguration");
|
throw new ObjectDisposedException("ProfileConfiguration");
|
||||||
|
|
||||||
Name = Entity.Name;
|
Name = Entity.ProfileConfiguration.Name;
|
||||||
IsSuspended = Entity.IsSuspended;
|
IsSuspended = Entity.ProfileConfiguration.IsSuspended;
|
||||||
ActivationBehaviour = (ActivationBehaviour) Entity.ActivationBehaviour;
|
ActivationBehaviour = (ActivationBehaviour) Entity.ProfileConfiguration.ActivationBehaviour;
|
||||||
HotkeyMode = (ProfileConfigurationHotkeyMode) Entity.HotkeyMode;
|
HotkeyMode = (ProfileConfigurationHotkeyMode) Entity.ProfileConfiguration.HotkeyMode;
|
||||||
FadeInAndOut = Entity.FadeInAndOut;
|
FadeInAndOut = Entity.ProfileConfiguration.FadeInAndOut;
|
||||||
Order = Entity.Order;
|
Order = Entity.ProfileConfiguration.Order;
|
||||||
|
|
||||||
Icon.Load();
|
Icon.Load();
|
||||||
|
|
||||||
if (Entity.ActivationCondition != null)
|
if (Entity.ProfileConfiguration.ActivationCondition != null)
|
||||||
ActivationCondition.LoadFromEntity(Entity.ActivationCondition);
|
ActivationCondition.LoadFromEntity(Entity.ProfileConfiguration.ActivationCondition);
|
||||||
|
|
||||||
EnableHotkey = Entity.EnableHotkey != null ? new Hotkey(Entity.EnableHotkey) : null;
|
EnableHotkey = Entity.ProfileConfiguration.EnableHotkey != null ? new Hotkey(Entity.ProfileConfiguration.EnableHotkey) : null;
|
||||||
DisableHotkey = Entity.DisableHotkey != null ? new Hotkey(Entity.DisableHotkey) : null;
|
DisableHotkey = Entity.ProfileConfiguration.DisableHotkey != null ? new Hotkey(Entity.ProfileConfiguration.DisableHotkey) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@ -306,26 +306,26 @@ public class ProfileConfiguration : BreakableModel, IStorageModel, IDisposable,
|
|||||||
if (_disposed)
|
if (_disposed)
|
||||||
throw new ObjectDisposedException("ProfileConfiguration");
|
throw new ObjectDisposedException("ProfileConfiguration");
|
||||||
|
|
||||||
Entity.Name = Name;
|
Entity.ProfileConfiguration.Name = Name;
|
||||||
Entity.IsSuspended = IsSuspended;
|
Entity.ProfileConfiguration.IsSuspended = IsSuspended;
|
||||||
Entity.ActivationBehaviour = (int) ActivationBehaviour;
|
Entity.ProfileConfiguration.ActivationBehaviour = (int) ActivationBehaviour;
|
||||||
Entity.HotkeyMode = (int) HotkeyMode;
|
Entity.ProfileConfiguration.HotkeyMode = (int) HotkeyMode;
|
||||||
Entity.ProfileCategoryId = Category.Entity.Id;
|
Entity.ProfileConfiguration.ProfileCategoryId = Category.Entity.Id;
|
||||||
Entity.FadeInAndOut = FadeInAndOut;
|
Entity.ProfileConfiguration.FadeInAndOut = FadeInAndOut;
|
||||||
Entity.Order = Order;
|
Entity.ProfileConfiguration.Order = Order;
|
||||||
|
|
||||||
Icon.Save();
|
Icon.Save();
|
||||||
|
|
||||||
ActivationCondition.Save();
|
ActivationCondition.Save();
|
||||||
Entity.ActivationCondition = ActivationCondition.Entity;
|
Entity.ProfileConfiguration.ActivationCondition = ActivationCondition.Entity;
|
||||||
|
|
||||||
EnableHotkey?.Save();
|
EnableHotkey?.Save();
|
||||||
Entity.EnableHotkey = EnableHotkey?.Entity;
|
Entity.ProfileConfiguration.EnableHotkey = EnableHotkey?.Entity;
|
||||||
DisableHotkey?.Save();
|
DisableHotkey?.Save();
|
||||||
Entity.DisableHotkey = DisableHotkey?.Entity;
|
Entity.ProfileConfiguration.DisableHotkey = DisableHotkey?.Entity;
|
||||||
|
|
||||||
if (!IsMissingModule)
|
if (!IsMissingModule)
|
||||||
Entity.ModuleId = Module?.Id;
|
Entity.ProfileConfiguration.ModuleId = Module?.Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@ -10,13 +10,13 @@ namespace Artemis.Core;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class ProfileConfigurationIcon : CorePropertyChanged, IStorageModel
|
public class ProfileConfigurationIcon : CorePropertyChanged, IStorageModel
|
||||||
{
|
{
|
||||||
private readonly ProfileConfigurationEntity _entity;
|
private readonly ProfileContainerEntity _entity;
|
||||||
private bool _fill;
|
private bool _fill;
|
||||||
private string? _iconName;
|
private string? _iconName;
|
||||||
private Stream? _iconStream;
|
private byte[]? _iconBytes;
|
||||||
private ProfileConfigurationIconType _iconType;
|
private ProfileConfigurationIconType _iconType;
|
||||||
|
|
||||||
internal ProfileConfigurationIcon(ProfileConfigurationEntity entity)
|
internal ProfileConfigurationIcon(ProfileContainerEntity entity)
|
||||||
{
|
{
|
||||||
_entity = entity;
|
_entity = entity;
|
||||||
}
|
}
|
||||||
@ -48,6 +48,15 @@ public class ProfileConfigurationIcon : CorePropertyChanged, IStorageModel
|
|||||||
set => SetAndNotify(ref _fill, value);
|
set => SetAndNotify(ref _fill, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the icon bytes if <see cref="IconType" /> is <see cref="ProfileConfigurationIconType.BitmapImage" />
|
||||||
|
/// </summary>
|
||||||
|
public byte[]? IconBytes
|
||||||
|
{
|
||||||
|
get => _iconBytes;
|
||||||
|
private set => SetAndNotify(ref _iconBytes, value);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates the <see cref="IconName" /> to the provided value and changes the <see cref="IconType" /> is
|
/// Updates the <see cref="IconName" /> to the provided value and changes the <see cref="IconType" /> is
|
||||||
/// <see cref="ProfileConfigurationIconType.MaterialIcon" />
|
/// <see cref="ProfileConfigurationIconType.MaterialIcon" />
|
||||||
@ -55,9 +64,9 @@ public class ProfileConfigurationIcon : CorePropertyChanged, IStorageModel
|
|||||||
/// <param name="iconName">The name of the icon</param>
|
/// <param name="iconName">The name of the icon</param>
|
||||||
public void SetIconByName(string iconName)
|
public void SetIconByName(string iconName)
|
||||||
{
|
{
|
||||||
if (iconName == null) throw new ArgumentNullException(nameof(iconName));
|
ArgumentNullException.ThrowIfNull(iconName);
|
||||||
|
|
||||||
_iconStream?.Dispose();
|
IconBytes = null;
|
||||||
IconName = iconName;
|
IconName = iconName;
|
||||||
IconType = ProfileConfigurationIconType.MaterialIcon;
|
IconType = ProfileConfigurationIconType.MaterialIcon;
|
||||||
|
|
||||||
@ -65,42 +74,27 @@ public class ProfileConfigurationIcon : CorePropertyChanged, IStorageModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates the stream returned by <see cref="GetIconStream" /> to the provided stream
|
/// Updates the <see cref="IconBytes" /> to the provided value and changes the <see cref="IconType" /> is
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="stream">The stream to copy</param>
|
/// <param name="stream">The stream to copy</param>
|
||||||
public void SetIconByStream(Stream stream)
|
public void SetIconByStream(Stream stream)
|
||||||
{
|
{
|
||||||
if (stream == null) throw new ArgumentNullException(nameof(stream));
|
ArgumentNullException.ThrowIfNull(stream);
|
||||||
|
|
||||||
_iconStream?.Dispose();
|
|
||||||
_iconStream = new MemoryStream();
|
|
||||||
if (stream.CanSeek)
|
if (stream.CanSeek)
|
||||||
stream.Seek(0, SeekOrigin.Begin);
|
stream.Seek(0, SeekOrigin.Begin);
|
||||||
stream.CopyTo(_iconStream);
|
|
||||||
_iconStream.Seek(0, SeekOrigin.Begin);
|
using (MemoryStream ms = new())
|
||||||
|
{
|
||||||
|
stream.CopyTo(ms);
|
||||||
|
IconBytes = ms.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
IconName = null;
|
IconName = null;
|
||||||
IconType = ProfileConfigurationIconType.BitmapImage;
|
IconType = ProfileConfigurationIconType.BitmapImage;
|
||||||
OnIconUpdated();
|
OnIconUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a copy of the stream containing the icon
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>A stream containing the icon</returns>
|
|
||||||
public Stream? GetIconStream()
|
|
||||||
{
|
|
||||||
if (_iconStream == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
MemoryStream stream = new();
|
|
||||||
_iconStream.CopyTo(stream);
|
|
||||||
|
|
||||||
stream.Seek(0, SeekOrigin.Begin);
|
|
||||||
_iconStream.Seek(0, SeekOrigin.Begin);
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Occurs when the icon was updated
|
/// Occurs when the icon was updated
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -119,21 +113,24 @@ public class ProfileConfigurationIcon : CorePropertyChanged, IStorageModel
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void Load()
|
public void Load()
|
||||||
{
|
{
|
||||||
IconType = (ProfileConfigurationIconType) _entity.IconType;
|
IconType = (ProfileConfigurationIconType) _entity.ProfileConfiguration.IconType;
|
||||||
Fill = _entity.IconFill;
|
Fill = _entity.ProfileConfiguration.IconFill;
|
||||||
if (IconType != ProfileConfigurationIconType.MaterialIcon)
|
if (IconType != ProfileConfigurationIconType.MaterialIcon)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
IconName = _entity.MaterialIcon;
|
IconName = _entity.ProfileConfiguration.MaterialIcon;
|
||||||
|
IconBytes = IconType == ProfileConfigurationIconType.BitmapImage ? _entity.Icon : null;
|
||||||
|
|
||||||
OnIconUpdated();
|
OnIconUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void Save()
|
public void Save()
|
||||||
{
|
{
|
||||||
_entity.IconType = (int) IconType;
|
_entity.ProfileConfiguration.IconType = (int) IconType;
|
||||||
_entity.MaterialIcon = IconType == ProfileConfigurationIconType.MaterialIcon ? IconName : null;
|
_entity.ProfileConfiguration.MaterialIcon = IconType == ProfileConfigurationIconType.MaterialIcon ? IconName : null;
|
||||||
_entity.IconFill = Fill;
|
_entity.ProfileConfiguration.IconFill = Fill;
|
||||||
|
_entity.Icon = IconBytes ?? Array.Empty<byte>();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@ -18,14 +18,8 @@ public interface IPluginSetting
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
string Name { get; }
|
string Name { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Determines whether the setting has been changed
|
|
||||||
/// </summary>
|
|
||||||
bool HasChanged { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets whether changes must automatically be saved
|
/// Gets or sets whether changes must automatically be saved
|
||||||
/// <para>Note: When set to <c>true</c> <see cref="HasChanged" /> is always <c>false</c></para>
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool AutoSave { get; set; }
|
bool AutoSave { get; set; }
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Nodes;
|
|
||||||
using Artemis.Storage.Entities.Plugins;
|
using Artemis.Storage.Entities.Plugins;
|
||||||
using Artemis.Storage.Repositories.Interfaces;
|
using Artemis.Storage.Repositories.Interfaces;
|
||||||
|
|
||||||
@ -24,7 +23,7 @@ public class PluginSetting<T> : CorePropertyChanged, IPluginSetting
|
|||||||
Name = pluginSettingEntity.Name;
|
Name = pluginSettingEntity.Name;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_value = pluginSettingEntity.Value.Deserialize<T>(IPluginSetting.SerializerOptions) ?? default!;
|
_value = CoreJson.Deserialize<T>(pluginSettingEntity.Value)!;
|
||||||
}
|
}
|
||||||
catch (JsonException)
|
catch (JsonException)
|
||||||
{
|
{
|
||||||
@ -77,7 +76,7 @@ public class PluginSetting<T> : CorePropertyChanged, IPluginSetting
|
|||||||
public string Name { get; }
|
public string Name { get; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool HasChanged => !JsonNode.DeepEquals(JsonSerializer.SerializeToNode(Value, IPluginSetting.SerializerOptions), _pluginSettingEntity.Value);
|
public bool HasChanged => CoreJson.Serialize(Value) != _pluginSettingEntity.Value;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool AutoSave { get; set; }
|
public bool AutoSave { get; set; }
|
||||||
@ -85,7 +84,7 @@ public class PluginSetting<T> : CorePropertyChanged, IPluginSetting
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void RejectChanges()
|
public void RejectChanges()
|
||||||
{
|
{
|
||||||
Value = _pluginSettingEntity.Value.Deserialize<T>(IPluginSetting.SerializerOptions) ?? default!;
|
Value = CoreJson.Deserialize<T>(_pluginSettingEntity.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@ -94,7 +93,7 @@ public class PluginSetting<T> : CorePropertyChanged, IPluginSetting
|
|||||||
if (!HasChanged)
|
if (!HasChanged)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_pluginSettingEntity.Value = JsonSerializer.SerializeToNode(Value, IPluginSetting.SerializerOptions) ?? new JsonObject();
|
_pluginSettingEntity.Value = CoreJson.Serialize(Value);
|
||||||
_pluginRepository.SaveChanges();
|
_pluginRepository.SaveChanges();
|
||||||
OnSettingSaved();
|
OnSettingSaved();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,7 +29,6 @@ internal class CoreService : ICoreService
|
|||||||
// ReSharper disable UnusedParameter.Local
|
// ReSharper disable UnusedParameter.Local
|
||||||
public CoreService(IContainer container,
|
public CoreService(IContainer container,
|
||||||
ILogger logger,
|
ILogger logger,
|
||||||
StorageMigrationService _1, // injected to ensure migration runs early
|
|
||||||
ISettingsService settingsService,
|
ISettingsService settingsService,
|
||||||
IPluginManagementService pluginManagementService,
|
IPluginManagementService pluginManagementService,
|
||||||
IProfileService profileService,
|
IProfileService profileService,
|
||||||
|
|||||||
@ -202,7 +202,7 @@ internal class DeviceService : IDeviceService
|
|||||||
_enabledDevices.Add(device);
|
_enabledDevices.Add(device);
|
||||||
device.IsEnabled = true;
|
device.IsEnabled = true;
|
||||||
device.Save();
|
device.Save();
|
||||||
_deviceRepository.Save(device.DeviceEntity);
|
_deviceRepository.SaveChanges();
|
||||||
|
|
||||||
OnDeviceEnabled(new DeviceEventArgs(device));
|
OnDeviceEnabled(new DeviceEventArgs(device));
|
||||||
UpdateLeds();
|
UpdateLeds();
|
||||||
@ -217,7 +217,7 @@ internal class DeviceService : IDeviceService
|
|||||||
_enabledDevices.Remove(device);
|
_enabledDevices.Remove(device);
|
||||||
device.IsEnabled = false;
|
device.IsEnabled = false;
|
||||||
device.Save();
|
device.Save();
|
||||||
_deviceRepository.Save(device.DeviceEntity);
|
_deviceRepository.SaveChanges();
|
||||||
|
|
||||||
OnDeviceDisabled(new DeviceEventArgs(device));
|
OnDeviceDisabled(new DeviceEventArgs(device));
|
||||||
UpdateLeds();
|
UpdateLeds();
|
||||||
@ -227,7 +227,7 @@ internal class DeviceService : IDeviceService
|
|||||||
public void SaveDevice(ArtemisDevice artemisDevice)
|
public void SaveDevice(ArtemisDevice artemisDevice)
|
||||||
{
|
{
|
||||||
artemisDevice.Save();
|
artemisDevice.Save();
|
||||||
_deviceRepository.Save(artemisDevice.DeviceEntity);
|
_deviceRepository.SaveChanges();
|
||||||
UpdateLeds();
|
UpdateLeds();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,7 +236,7 @@ internal class DeviceService : IDeviceService
|
|||||||
{
|
{
|
||||||
foreach (ArtemisDevice artemisDevice in _devices)
|
foreach (ArtemisDevice artemisDevice in _devices)
|
||||||
artemisDevice.Save();
|
artemisDevice.Save();
|
||||||
_deviceRepository.Save(_devices.Select(d => d.DeviceEntity));
|
_deviceRepository.SaveChanges();
|
||||||
UpdateLeds();
|
UpdateLeds();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,6 +254,8 @@ internal class DeviceService : IDeviceService
|
|||||||
{
|
{
|
||||||
_logger.Information("No device config found for {DeviceInfo}, device hash: {DeviceHashCode}. Adding a new entry", rgbDevice.DeviceInfo, deviceIdentifier);
|
_logger.Information("No device config found for {DeviceInfo}, device hash: {DeviceHashCode}. Adding a new entry", rgbDevice.DeviceInfo, deviceIdentifier);
|
||||||
device = new ArtemisDevice(rgbDevice, deviceProvider);
|
device = new ArtemisDevice(rgbDevice, deviceProvider);
|
||||||
|
_deviceRepository.Add(device.DeviceEntity);
|
||||||
|
_deviceRepository.SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadDeviceLayout(device);
|
LoadDeviceLayout(device);
|
||||||
|
|||||||
@ -807,7 +807,7 @@ internal class PluginManagementService : IPluginManagementService
|
|||||||
plugin.Entity.Features.Add(featureInfo.Instance!.Entity);
|
plugin.Entity.Features.Add(featureInfo.Instance!.Entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
_pluginRepository.SavePlugin(plugin.Entity);
|
_pluginRepository.SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@ -29,10 +29,13 @@ internal class ScriptingService : IScriptingService
|
|||||||
// No need to sub to Deactivated, scripts will deactivate themselves
|
// No need to sub to Deactivated, scripts will deactivate themselves
|
||||||
profileService.ProfileActivated += ProfileServiceOnProfileActivated;
|
profileService.ProfileActivated += ProfileServiceOnProfileActivated;
|
||||||
|
|
||||||
foreach (ProfileConfiguration profileConfiguration in _profileService.ProfileConfigurations)
|
foreach (ProfileCategory profileCategory in _profileService.ProfileCategories)
|
||||||
{
|
{
|
||||||
if (profileConfiguration.Profile != null)
|
foreach (ProfileConfiguration profileConfiguration in profileCategory.ProfileConfigurations)
|
||||||
InitializeProfileScripts(profileConfiguration.Profile);
|
{
|
||||||
|
if (profileConfiguration.Profile != null)
|
||||||
|
InitializeProfileScripts(profileConfiguration.Profile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,10 +116,13 @@ internal class ScriptingService : IScriptingService
|
|||||||
_scriptingProviders.Clear();
|
_scriptingProviders.Clear();
|
||||||
_scriptingProviders.AddRange(_pluginManagementService.GetFeaturesOfType<ScriptingProvider>());
|
_scriptingProviders.AddRange(_pluginManagementService.GetFeaturesOfType<ScriptingProvider>());
|
||||||
|
|
||||||
foreach (ProfileConfiguration profileConfiguration in _profileService.ProfileConfigurations)
|
foreach (ProfileCategory profileCategory in _profileService.ProfileCategories)
|
||||||
{
|
{
|
||||||
if (profileConfiguration.Profile != null)
|
foreach (ProfileConfiguration profileConfiguration in profileCategory.ProfileConfigurations)
|
||||||
InitializeProfileScripts(profileConfiguration.Profile);
|
{
|
||||||
|
if (profileConfiguration.Profile != null)
|
||||||
|
InitializeProfileScripts(profileConfiguration.Profile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,11 +16,6 @@ public interface IProfileService : IArtemisService
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
ReadOnlyCollection<ProfileCategory> ProfileCategories { get; }
|
ReadOnlyCollection<ProfileCategory> ProfileCategories { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a read only collection containing all the profile configurations.
|
|
||||||
/// </summary>
|
|
||||||
ReadOnlyCollection<ProfileConfiguration> ProfileConfigurations { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the focused profile configuration which is rendered exclusively.
|
/// Gets or sets the focused profile configuration which is rendered exclusively.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -101,16 +96,6 @@ public interface IProfileService : IArtemisService
|
|||||||
/// <param name="profileConfiguration"></param>
|
/// <param name="profileConfiguration"></param>
|
||||||
void RemoveProfileConfiguration(ProfileConfiguration profileConfiguration);
|
void RemoveProfileConfiguration(ProfileConfiguration profileConfiguration);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Loads the icon of this profile configuration if needed and puts it into <c>ProfileConfiguration.Icon.FileIcon</c>.
|
|
||||||
/// </summary>
|
|
||||||
void LoadProfileConfigurationIcon(ProfileConfiguration profileConfiguration);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Saves the current icon of this profile.
|
|
||||||
/// </summary>
|
|
||||||
void SaveProfileConfigurationIcon(ProfileConfiguration profileConfiguration);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Writes the profile to persistent storage.
|
/// Writes the profile to persistent storage.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -25,7 +25,6 @@ internal class ProfileService : IProfileService
|
|||||||
private readonly IDeviceService _deviceService;
|
private readonly IDeviceService _deviceService;
|
||||||
private readonly List<ArtemisKeyboardKeyEventArgs> _pendingKeyboardEvents = new();
|
private readonly List<ArtemisKeyboardKeyEventArgs> _pendingKeyboardEvents = new();
|
||||||
private readonly List<ProfileCategory> _profileCategories;
|
private readonly List<ProfileCategory> _profileCategories;
|
||||||
private readonly IProfileRepository _profileRepository;
|
|
||||||
private readonly List<IProfileMigration> _profileMigrators;
|
private readonly List<IProfileMigration> _profileMigrators;
|
||||||
private readonly List<Exception> _renderExceptions = new();
|
private readonly List<Exception> _renderExceptions = new();
|
||||||
private readonly List<Exception> _updateExceptions = new();
|
private readonly List<Exception> _updateExceptions = new();
|
||||||
@ -38,17 +37,17 @@ internal class ProfileService : IProfileService
|
|||||||
IPluginManagementService pluginManagementService,
|
IPluginManagementService pluginManagementService,
|
||||||
IInputService inputService,
|
IInputService inputService,
|
||||||
IDeviceService deviceService,
|
IDeviceService deviceService,
|
||||||
IProfileRepository profileRepository,
|
|
||||||
List<IProfileMigration> profileMigrators)
|
List<IProfileMigration> profileMigrators)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_profileCategoryRepository = profileCategoryRepository;
|
_profileCategoryRepository = profileCategoryRepository;
|
||||||
_pluginManagementService = pluginManagementService;
|
_pluginManagementService = pluginManagementService;
|
||||||
_deviceService = deviceService;
|
_deviceService = deviceService;
|
||||||
_profileRepository = profileRepository;
|
|
||||||
_profileMigrators = profileMigrators;
|
_profileMigrators = profileMigrators;
|
||||||
_profileCategories = new List<ProfileCategory>(_profileCategoryRepository.GetAll().Select(c => new ProfileCategory(c)).OrderBy(c => c.Order));
|
_profileCategories = new List<ProfileCategory>(_profileCategoryRepository.GetAll().Select(c => new ProfileCategory(c)).OrderBy(c => c.Order));
|
||||||
|
|
||||||
|
ProfileCategories = new ReadOnlyCollection<ProfileCategory>(_profileCategories);
|
||||||
|
|
||||||
_deviceService.LedsChanged += DeviceServiceOnLedsChanged;
|
_deviceService.LedsChanged += DeviceServiceOnLedsChanged;
|
||||||
_pluginManagementService.PluginFeatureEnabled += PluginManagementServiceOnPluginFeatureToggled;
|
_pluginManagementService.PluginFeatureEnabled += PluginManagementServiceOnPluginFeatureToggled;
|
||||||
_pluginManagementService.PluginFeatureDisabled += PluginManagementServiceOnPluginFeatureToggled;
|
_pluginManagementService.PluginFeatureDisabled += PluginManagementServiceOnPluginFeatureToggled;
|
||||||
@ -166,50 +165,7 @@ internal class ProfileService : IProfileService
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ReadOnlyCollection<ProfileCategory> ProfileCategories
|
public ReadOnlyCollection<ProfileCategory> ProfileCategories { get; }
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
lock (_profileRepository)
|
|
||||||
{
|
|
||||||
return _profileCategories.AsReadOnly();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public ReadOnlyCollection<ProfileConfiguration> ProfileConfigurations
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
lock (_profileRepository)
|
|
||||||
{
|
|
||||||
return _profileCategories.SelectMany(c => c.ProfileConfigurations).ToList().AsReadOnly();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void LoadProfileConfigurationIcon(ProfileConfiguration profileConfiguration)
|
|
||||||
{
|
|
||||||
if (profileConfiguration.Icon.IconType == ProfileConfigurationIconType.MaterialIcon)
|
|
||||||
return;
|
|
||||||
|
|
||||||
using Stream? stream = _profileCategoryRepository.GetProfileIconStream(profileConfiguration.Entity.FileIconId);
|
|
||||||
if (stream != null)
|
|
||||||
profileConfiguration.Icon.SetIconByStream(stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void SaveProfileConfigurationIcon(ProfileConfiguration profileConfiguration)
|
|
||||||
{
|
|
||||||
if (profileConfiguration.Icon.IconType == ProfileConfigurationIconType.MaterialIcon)
|
|
||||||
return;
|
|
||||||
|
|
||||||
using Stream? stream = profileConfiguration.Icon.GetIconStream();
|
|
||||||
if (stream != null)
|
|
||||||
_profileCategoryRepository.SaveProfileIconStream(profileConfiguration.Entity, stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ProfileConfiguration CloneProfileConfiguration(ProfileConfiguration profileConfiguration)
|
public ProfileConfiguration CloneProfileConfiguration(ProfileConfiguration profileConfiguration)
|
||||||
@ -226,21 +182,7 @@ internal class ProfileService : IProfileService
|
|||||||
return profileConfiguration.Profile;
|
return profileConfiguration.Profile;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProfileEntity? profileEntity;
|
Profile profile = new(profileConfiguration, profileConfiguration.Entity.Profile);
|
||||||
try
|
|
||||||
{
|
|
||||||
profileEntity = _profileRepository.Get(profileConfiguration.Entity.ProfileId);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
profileConfiguration.SetBrokenState("Failed to activate profile", e);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (profileEntity == null)
|
|
||||||
throw new ArtemisCoreException($"Cannot find profile named: {profileConfiguration.Name} ID: {profileConfiguration.Entity.ProfileId}");
|
|
||||||
|
|
||||||
Profile profile = new(profileConfiguration, profileEntity);
|
|
||||||
profile.PopulateLeds(_deviceService.EnabledDevices);
|
profile.PopulateLeds(_deviceService.EnabledDevices);
|
||||||
|
|
||||||
if (profile.IsFreshImport)
|
if (profile.IsFreshImport)
|
||||||
@ -285,39 +227,34 @@ internal class ProfileService : IProfileService
|
|||||||
{
|
{
|
||||||
DeactivateProfile(profileConfiguration);
|
DeactivateProfile(profileConfiguration);
|
||||||
|
|
||||||
ProfileEntity? profileEntity = _profileRepository.Get(profileConfiguration.Entity.ProfileId);
|
ProfileCategory category = profileConfiguration.Category;
|
||||||
if (profileEntity == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
profileConfiguration.Category.RemoveProfileConfiguration(profileConfiguration);
|
category.RemoveProfileConfiguration(profileConfiguration);
|
||||||
_profileRepository.Remove(profileEntity);
|
category.Entity.ProfileConfigurations.Remove(profileConfiguration.Entity);
|
||||||
SaveProfileCategory(profileConfiguration.Category);
|
|
||||||
|
_profileCategoryRepository.SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ProfileCategory CreateProfileCategory(string name, bool addToTop = false)
|
public ProfileCategory CreateProfileCategory(string name, bool addToTop = false)
|
||||||
{
|
{
|
||||||
ProfileCategory profileCategory;
|
ProfileCategory profileCategory;
|
||||||
lock (_profileRepository)
|
if (addToTop)
|
||||||
{
|
{
|
||||||
if (addToTop)
|
profileCategory = new ProfileCategory(name, 1);
|
||||||
|
foreach (ProfileCategory category in _profileCategories)
|
||||||
{
|
{
|
||||||
profileCategory = new ProfileCategory(name, 1);
|
category.Order++;
|
||||||
foreach (ProfileCategory category in _profileCategories)
|
category.Save();
|
||||||
{
|
|
||||||
category.Order++;
|
|
||||||
category.Save();
|
|
||||||
_profileCategoryRepository.Save(category.Entity);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
profileCategory = new ProfileCategory(name, _profileCategories.Count + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
_profileCategories.Add(profileCategory);
|
|
||||||
SaveProfileCategory(profileCategory);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
profileCategory = new ProfileCategory(name, _profileCategories.Count + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
_profileCategoryRepository.Add(profileCategory.Entity);
|
||||||
|
_profileCategories.Add(profileCategory);
|
||||||
|
|
||||||
OnProfileCategoryAdded(new ProfileCategoryEventArgs(profileCategory));
|
OnProfileCategoryAdded(new ProfileCategoryEventArgs(profileCategory));
|
||||||
return profileCategory;
|
return profileCategory;
|
||||||
@ -326,15 +263,11 @@ internal class ProfileService : IProfileService
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void DeleteProfileCategory(ProfileCategory profileCategory)
|
public void DeleteProfileCategory(ProfileCategory profileCategory)
|
||||||
{
|
{
|
||||||
List<ProfileConfiguration> profileConfigurations = profileCategory.ProfileConfigurations.ToList();
|
foreach (ProfileConfiguration profileConfiguration in profileCategory.ProfileConfigurations.ToList())
|
||||||
foreach (ProfileConfiguration profileConfiguration in profileConfigurations)
|
|
||||||
RemoveProfileConfiguration(profileConfiguration);
|
RemoveProfileConfiguration(profileConfiguration);
|
||||||
|
|
||||||
lock (_profileRepository)
|
_profileCategories.Remove(profileCategory);
|
||||||
{
|
_profileCategoryRepository.Remove(profileCategory.Entity);
|
||||||
_profileCategories.Remove(profileCategory);
|
|
||||||
_profileCategoryRepository.Remove(profileCategory.Entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
OnProfileCategoryRemoved(new ProfileCategoryEventArgs(profileCategory));
|
OnProfileCategoryRemoved(new ProfileCategoryEventArgs(profileCategory));
|
||||||
}
|
}
|
||||||
@ -343,24 +276,20 @@ internal class ProfileService : IProfileService
|
|||||||
public ProfileConfiguration CreateProfileConfiguration(ProfileCategory category, string name, string icon)
|
public ProfileConfiguration CreateProfileConfiguration(ProfileCategory category, string name, string icon)
|
||||||
{
|
{
|
||||||
ProfileConfiguration configuration = new(category, name, icon);
|
ProfileConfiguration configuration = new(category, name, icon);
|
||||||
ProfileEntity entity = new();
|
|
||||||
_profileRepository.Add(entity);
|
|
||||||
|
|
||||||
configuration.Entity.ProfileId = entity.Id;
|
|
||||||
category.AddProfileConfiguration(configuration, 0);
|
category.AddProfileConfiguration(configuration, 0);
|
||||||
|
SaveProfileCategory(category);
|
||||||
return configuration;
|
return configuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void RemoveProfileConfiguration(ProfileConfiguration profileConfiguration)
|
public void RemoveProfileConfiguration(ProfileConfiguration profileConfiguration)
|
||||||
{
|
{
|
||||||
profileConfiguration.Category.RemoveProfileConfiguration(profileConfiguration);
|
ProfileCategory category = profileConfiguration.Category;
|
||||||
|
category.RemoveProfileConfiguration(profileConfiguration);
|
||||||
|
|
||||||
DeactivateProfile(profileConfiguration);
|
DeactivateProfile(profileConfiguration);
|
||||||
SaveProfileCategory(profileConfiguration.Category);
|
SaveProfileCategory(profileConfiguration.Category);
|
||||||
ProfileEntity? profileEntity = _profileRepository.Get(profileConfiguration.Entity.ProfileId);
|
|
||||||
if (profileEntity != null)
|
|
||||||
_profileRepository.Remove(profileEntity);
|
|
||||||
|
|
||||||
profileConfiguration.Dispose();
|
profileConfiguration.Dispose();
|
||||||
}
|
}
|
||||||
@ -369,7 +298,7 @@ internal class ProfileService : IProfileService
|
|||||||
public void SaveProfileCategory(ProfileCategory profileCategory)
|
public void SaveProfileCategory(ProfileCategory profileCategory)
|
||||||
{
|
{
|
||||||
profileCategory.Save();
|
profileCategory.Save();
|
||||||
_profileCategoryRepository.Save(profileCategory.Entity);
|
_profileCategoryRepository.SaveChanges();
|
||||||
|
|
||||||
lock (_profileCategories)
|
lock (_profileCategories)
|
||||||
{
|
{
|
||||||
@ -392,11 +321,13 @@ internal class ProfileService : IProfileService
|
|||||||
profile.IsFreshImport = false;
|
profile.IsFreshImport = false;
|
||||||
profile.ProfileEntity.IsFreshImport = false;
|
profile.ProfileEntity.IsFreshImport = false;
|
||||||
|
|
||||||
_profileRepository.Save(profile.ProfileEntity);
|
SaveProfileCategory(profile.Configuration.Category);
|
||||||
|
|
||||||
// If the provided profile is external (cloned or from the workshop?) but it is loaded locally too, reload the local instance
|
// If the provided profile is external (cloned or from the workshop?) but it is loaded locally too, reload the local instance
|
||||||
// A bit dodge but it ensures local instances always represent the latest stored version
|
// A bit dodge but it ensures local instances always represent the latest stored version
|
||||||
ProfileConfiguration? localInstance = ProfileConfigurations.FirstOrDefault(p => p.Profile != null && p.Profile != profile && p.ProfileId == profile.ProfileEntity.Id);
|
ProfileConfiguration? localInstance = ProfileCategories
|
||||||
|
.SelectMany(c => c.ProfileConfigurations)
|
||||||
|
.FirstOrDefault(p => p.Profile != null && p.Profile != profile && p.ProfileId == profile.ProfileEntity.Id);
|
||||||
if (localInstance == null)
|
if (localInstance == null)
|
||||||
return;
|
return;
|
||||||
DeactivateProfile(localInstance);
|
DeactivateProfile(localInstance);
|
||||||
@ -406,12 +337,8 @@ internal class ProfileService : IProfileService
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public async Task<Stream> ExportProfile(ProfileConfiguration profileConfiguration)
|
public async Task<Stream> ExportProfile(ProfileConfiguration profileConfiguration)
|
||||||
{
|
{
|
||||||
ProfileEntity? profileEntity = _profileRepository.Get(profileConfiguration.Entity.ProfileId);
|
string configurationJson = CoreJson.Serialize(profileConfiguration.Entity.ProfileConfiguration);
|
||||||
if (profileEntity == null)
|
string profileJson = CoreJson.Serialize(profileConfiguration.Entity.Profile);
|
||||||
throw new ArtemisCoreException("Could not locate profile entity");
|
|
||||||
|
|
||||||
string configurationJson = CoreJson.Serialize(profileConfiguration.Entity);
|
|
||||||
string profileJson = CoreJson.Serialize(profileEntity);
|
|
||||||
|
|
||||||
MemoryStream archiveStream = new();
|
MemoryStream archiveStream = new();
|
||||||
|
|
||||||
@ -430,12 +357,11 @@ internal class ProfileService : IProfileService
|
|||||||
await entryStream.WriteAsync(Encoding.Default.GetBytes(profileJson));
|
await entryStream.WriteAsync(Encoding.Default.GetBytes(profileJson));
|
||||||
}
|
}
|
||||||
|
|
||||||
await using Stream? iconStream = profileConfiguration.Icon.GetIconStream();
|
if (profileConfiguration.Icon.IconBytes != null)
|
||||||
if (iconStream != null)
|
|
||||||
{
|
{
|
||||||
ZipArchiveEntry iconEntry = archive.CreateEntry("icon.png");
|
ZipArchiveEntry iconEntry = archive.CreateEntry("icon.png");
|
||||||
await using Stream entryStream = iconEntry.Open();
|
await using Stream entryStream = iconEntry.Open();
|
||||||
await iconStream.CopyToAsync(entryStream);
|
await entryStream.WriteAsync(profileConfiguration.Icon.IconBytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -495,26 +421,26 @@ internal class ProfileService : IProfileService
|
|||||||
if (markAsFreshImport)
|
if (markAsFreshImport)
|
||||||
profileEntity.IsFreshImport = true;
|
profileEntity.IsFreshImport = true;
|
||||||
|
|
||||||
if (_profileRepository.Get(profileEntity.Id) == null)
|
if (makeUnique && ProfileCategories.SelectMany(c => c.ProfileConfigurations).Any(c => c.ProfileId == profileEntity.Id))
|
||||||
_profileRepository.Add(profileEntity);
|
|
||||||
else
|
|
||||||
throw new ArtemisCoreException($"Cannot import this profile without {nameof(makeUnique)} being true");
|
throw new ArtemisCoreException($"Cannot import this profile without {nameof(makeUnique)} being true");
|
||||||
|
|
||||||
// A new GUID will be given on save
|
ProfileContainerEntity containerEntity = new() {ProfileConfiguration = configurationEntity, Profile = profileEntity};
|
||||||
configurationEntity.FileIconId = Guid.Empty;
|
|
||||||
ProfileConfiguration profileConfiguration = new(category, configurationEntity);
|
|
||||||
if (nameAffix != null)
|
|
||||||
profileConfiguration.Name = $"{profileConfiguration.Name} - {nameAffix}";
|
|
||||||
|
|
||||||
// If an icon was provided, import that as well
|
// If an icon was provided, import that as well
|
||||||
if (iconEntry != null)
|
if (iconEntry != null)
|
||||||
{
|
{
|
||||||
await using Stream iconStream = iconEntry.Open();
|
await using Stream iconStream = iconEntry.Open();
|
||||||
profileConfiguration.Icon.SetIconByStream(iconStream);
|
using MemoryStream ms = new();
|
||||||
SaveProfileConfigurationIcon(profileConfiguration);
|
await iconStream.CopyToAsync(ms);
|
||||||
|
containerEntity.Icon = ms.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
profileConfiguration.Entity.ProfileId = profileEntity.Id;
|
// A new GUID will be given on save
|
||||||
|
configurationEntity.FileIconId = Guid.Empty;
|
||||||
|
ProfileConfiguration profileConfiguration = new(category, containerEntity);
|
||||||
|
if (nameAffix != null)
|
||||||
|
profileConfiguration.Name = $"{profileConfiguration.Name} - {nameAffix}";
|
||||||
|
|
||||||
|
profileConfiguration.Entity.ProfileConfiguration.ProfileId = profileEntity.Id;
|
||||||
category.AddProfileConfiguration(profileConfiguration, targetIndex);
|
category.AddProfileConfiguration(profileConfiguration, targetIndex);
|
||||||
|
|
||||||
List<Module> modules = _pluginManagementService.GetFeaturesOfType<Module>();
|
List<Module> modules = _pluginManagementService.GetFeaturesOfType<Module>();
|
||||||
@ -548,7 +474,7 @@ internal class ProfileService : IProfileService
|
|||||||
renderProfileElement.Save();
|
renderProfileElement.Save();
|
||||||
|
|
||||||
_logger.Debug("Adapt profile - Saving " + profile);
|
_logger.Debug("Adapt profile - Saving " + profile);
|
||||||
_profileRepository.Save(profile.ProfileEntity);
|
SaveProfileCategory(profile.Configuration.Category);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InputServiceOnKeyboardKeyUp(object? sender, ArtemisKeyboardKeyEventArgs e)
|
private void InputServiceOnKeyboardKeyUp(object? sender, ArtemisKeyboardKeyEventArgs e)
|
||||||
@ -581,27 +507,27 @@ internal class ProfileService : IProfileService
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void ActiveProfilesPopulateLeds()
|
private void ActiveProfilesPopulateLeds()
|
||||||
{
|
{
|
||||||
foreach (ProfileConfiguration profileConfiguration in ProfileConfigurations)
|
foreach (ProfileCategory profileCategory in ProfileCategories)
|
||||||
{
|
{
|
||||||
if (profileConfiguration.Profile == null) continue;
|
foreach (ProfileConfiguration profileConfiguration in profileCategory.ProfileConfigurations)
|
||||||
profileConfiguration.Profile.PopulateLeds(_deviceService.EnabledDevices);
|
{
|
||||||
|
if (profileConfiguration.Profile == null) continue;
|
||||||
|
profileConfiguration.Profile.PopulateLeds(_deviceService.EnabledDevices);
|
||||||
|
|
||||||
if (!profileConfiguration.Profile.IsFreshImport) continue;
|
if (!profileConfiguration.Profile.IsFreshImport) continue;
|
||||||
_logger.Debug("Profile is a fresh import, adapting to surface - {profile}", profileConfiguration.Profile);
|
_logger.Debug("Profile is a fresh import, adapting to surface - {profile}", profileConfiguration.Profile);
|
||||||
AdaptProfile(profileConfiguration.Profile);
|
AdaptProfile(profileConfiguration.Profile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateModules()
|
private void UpdateModules()
|
||||||
{
|
{
|
||||||
lock (_profileRepository)
|
List<Module> modules = _pluginManagementService.GetFeaturesOfType<Module>();
|
||||||
|
foreach (ProfileCategory profileCategory in ProfileCategories)
|
||||||
{
|
{
|
||||||
List<Module> modules = _pluginManagementService.GetFeaturesOfType<Module>();
|
foreach (ProfileConfiguration profileConfiguration in profileCategory.ProfileConfigurations)
|
||||||
foreach (ProfileCategory profileCategory in _profileCategories)
|
profileConfiguration.LoadModules(modules);
|
||||||
{
|
|
||||||
foreach (ProfileConfiguration profileConfiguration in profileCategory.ProfileConfigurations)
|
|
||||||
profileConfiguration.LoadModules(modules);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
22
src/Artemis.Storage.Migrator/Artemis.Storage.Migrator.csproj
Normal file
22
src/Artemis.Storage.Migrator/Artemis.Storage.Migrator.csproj
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Artemis.Core\Artemis.Core.csproj" />
|
||||||
|
<ProjectReference Include="..\Artemis.Storage\Artemis.Storage.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
21
src/Artemis.Storage.Migrator/Program.cs
Normal file
21
src/Artemis.Storage.Migrator/Program.cs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
using Artemis.Core.DryIoc;
|
||||||
|
using DryIoc;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace Artemis.Storage.Migrator;
|
||||||
|
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
static void Main(string[] args)
|
||||||
|
{
|
||||||
|
Container container = new Container(rules => rules
|
||||||
|
.WithMicrosoftDependencyInjectionRules()
|
||||||
|
.WithConcreteTypeDynamicRegistrations()
|
||||||
|
.WithoutThrowOnRegisteringDisposableTransient());
|
||||||
|
|
||||||
|
container.RegisterCore();
|
||||||
|
|
||||||
|
container.Resolve<ArtemisDbContext>().Database.EnsureCreated();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
src/Artemis.Storage.Migrator/artemis.db
Normal file
BIN
src/Artemis.Storage.Migrator/artemis.db
Normal file
Binary file not shown.
@ -1,3 +1,7 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text.Json;
|
||||||
using Artemis.Storage.Entities.General;
|
using Artemis.Storage.Entities.General;
|
||||||
using Artemis.Storage.Entities.Plugins;
|
using Artemis.Storage.Entities.Plugins;
|
||||||
using Artemis.Storage.Entities.Profile;
|
using Artemis.Storage.Entities.Profile;
|
||||||
@ -14,9 +18,17 @@ public class ArtemisDbContext : DbContext
|
|||||||
public DbSet<PluginEntity> Plugins => Set<PluginEntity>();
|
public DbSet<PluginEntity> Plugins => Set<PluginEntity>();
|
||||||
public DbSet<PluginSettingEntity> PluginSettings => Set<PluginSettingEntity>();
|
public DbSet<PluginSettingEntity> PluginSettings => Set<PluginSettingEntity>();
|
||||||
public DbSet<ProfileCategoryEntity> ProfileCategories => Set<ProfileCategoryEntity>();
|
public DbSet<ProfileCategoryEntity> ProfileCategories => Set<ProfileCategoryEntity>();
|
||||||
public DbSet<ProfileContainerEntity> Profiles => Set<ProfileContainerEntity>();
|
|
||||||
public DbSet<ReleaseEntity> Releases => Set<ReleaseEntity>();
|
public DbSet<ReleaseEntity> Releases => Set<ReleaseEntity>();
|
||||||
|
|
||||||
|
public string DataFolder { get; set; } = string.Empty;
|
||||||
|
public JsonSerializerOptions JsonSerializerOptions { get; set; } = JsonSerializerOptions.Default;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||||
|
{
|
||||||
|
optionsBuilder.UseSqlite($"Data Source={Path.Combine(DataFolder, "artemis.db")}");
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
{
|
{
|
||||||
@ -25,13 +37,21 @@ public class ArtemisDbContext : DbContext
|
|||||||
.OwnsOne(d => d.InputMappings, builder => builder.ToJson());
|
.OwnsOne(d => d.InputMappings, builder => builder.ToJson());
|
||||||
|
|
||||||
modelBuilder.Entity<EntryEntity>()
|
modelBuilder.Entity<EntryEntity>()
|
||||||
.OwnsOne(e => e.Metadata, builder => builder.ToJson());
|
.Property(e => e.Metadata)
|
||||||
|
.HasConversion(
|
||||||
modelBuilder.Entity<PluginSettingEntity>()
|
v => JsonSerializer.Serialize(v, JsonSerializerOptions),
|
||||||
.OwnsOne(s => s.Value, builder => builder.ToJson());
|
v => JsonSerializer.Deserialize<Dictionary<string, object>>(v, JsonSerializerOptions) ?? new Dictionary<string, object>());
|
||||||
|
|
||||||
modelBuilder.Entity<ProfileContainerEntity>()
|
modelBuilder.Entity<ProfileContainerEntity>()
|
||||||
.OwnsOne(c => c.ProfileConfiguration, builder => builder.ToJson())
|
.Property(e => e.ProfileConfiguration)
|
||||||
.OwnsOne(c => c.Profile, builder => builder.ToJson());
|
.HasConversion(
|
||||||
|
v => JsonSerializer.Serialize(v, JsonSerializerOptions),
|
||||||
|
v => JsonSerializer.Deserialize<ProfileConfigurationEntity>(v, JsonSerializerOptions) ?? new ProfileConfigurationEntity());
|
||||||
|
|
||||||
|
modelBuilder.Entity<ProfileContainerEntity>()
|
||||||
|
.Property(e => e.Profile)
|
||||||
|
.HasConversion(
|
||||||
|
v => JsonSerializer.Serialize(v, JsonSerializerOptions),
|
||||||
|
v => JsonSerializer.Deserialize<ProfileEntity>(v, JsonSerializerOptions) ?? new ProfileEntity());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -24,6 +24,8 @@ public class PluginEntity
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class PluginFeatureEntity
|
public class PluginFeatureEntity
|
||||||
{
|
{
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
public string Type { get; set; } = string.Empty;
|
public string Type { get; set; } = string.Empty;
|
||||||
public bool IsEnabled { get; set; }
|
public bool IsEnabled { get; set; }
|
||||||
}
|
}
|
||||||
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Text.Json.Nodes;
|
|
||||||
|
|
||||||
namespace Artemis.Storage.Entities.Plugins;
|
namespace Artemis.Storage.Entities.Plugins;
|
||||||
|
|
||||||
@ -12,5 +11,5 @@ public class PluginSettingEntity
|
|||||||
public Guid PluginGuid { get; set; }
|
public Guid PluginGuid { get; set; }
|
||||||
|
|
||||||
public string Name { get; set; } = string.Empty;
|
public string Name { get; set; } = string.Empty;
|
||||||
public JsonNode Value { get; set; } = new JsonObject();
|
public string Value { get; set; } = string.Empty;
|
||||||
}
|
}
|
||||||
@ -14,10 +14,3 @@ public class ProfileCategoryEntity
|
|||||||
|
|
||||||
public List<ProfileContainerEntity> ProfileConfigurations { get; set; } = new();
|
public List<ProfileContainerEntity> ProfileConfigurations { get; set; } = new();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ProfileContainerEntity
|
|
||||||
{
|
|
||||||
public byte[] Icon { get; set; } = Array.Empty<byte>();
|
|
||||||
public ProfileConfigurationEntity ProfileConfiguration { get; set; } = new();
|
|
||||||
public ProfileEntity Profile { get; set; } = new();
|
|
||||||
}
|
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Artemis.Storage.Entities.Profile;
|
||||||
|
|
||||||
|
public class ProfileContainerEntity
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
public byte[] Icon { get; set; } = Array.Empty<byte>();
|
||||||
|
|
||||||
|
public ProfileCategoryEntity ProfileCategory { get; set; } = null!;
|
||||||
|
|
||||||
|
public ProfileConfigurationEntity ProfileConfiguration { get; set; } = new();
|
||||||
|
public ProfileEntity Profile { get; set; } = new();
|
||||||
|
}
|
||||||
@ -18,5 +18,5 @@ public class EntryEntity
|
|||||||
public string ReleaseVersion { get; set; } = string.Empty;
|
public string ReleaseVersion { get; set; } = string.Empty;
|
||||||
public DateTimeOffset InstalledAt { get; set; }
|
public DateTimeOffset InstalledAt { get; set; }
|
||||||
|
|
||||||
public Dictionary<string,JsonNode>? Metadata { get; set; }
|
public Dictionary<string, object> Metadata { get; set; }
|
||||||
}
|
}
|
||||||
323
src/Artemis.Storage/Migrations/20240308203921_Initial.Designer.cs
generated
Normal file
323
src/Artemis.Storage/Migrations/20240308203921_Initial.Designer.cs
generated
Normal file
@ -0,0 +1,323 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Artemis.Storage;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Artemis.Storage.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(ArtemisDbContext))]
|
||||||
|
[Migration("20240308203921_Initial")]
|
||||||
|
partial class Initial
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder.HasAnnotation("ProductVersion", "8.0.2");
|
||||||
|
|
||||||
|
modelBuilder.Entity("Artemis.Storage.Entities.General.ReleaseEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset?>("InstalledAt")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Version")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Releases");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Artemis.Storage.Entities.Plugins.PluginEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("IsEnabled")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Plugins");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Artemis.Storage.Entities.Plugins.PluginFeatureEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("IsEnabled")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<Guid?>("PluginEntityId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Type")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("PluginEntityId");
|
||||||
|
|
||||||
|
b.ToTable("PluginFeatureEntity");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Artemis.Storage.Entities.Plugins.PluginSettingEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<Guid>("PluginGuid")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Value")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("PluginSettings");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Artemis.Storage.Entities.Profile.ProfileCategoryEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("IsCollapsed")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("IsSuspended")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("Order")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("ProfileCategories");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Artemis.Storage.Entities.Profile.ProfileContainerEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<byte[]>("Icon")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("BLOB");
|
||||||
|
|
||||||
|
b.Property<string>("Profile")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<Guid>("ProfileCategoryId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ProfileConfiguration")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("ProfileCategoryId");
|
||||||
|
|
||||||
|
b.ToTable("ProfileContainerEntity");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Artemis.Storage.Entities.Surface.DeviceEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<float>("BlueScale")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<string>("Categories")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("DeviceProvider")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<float>("GreenScale")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<bool>("IsEnabled")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("LayoutParameter")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("LayoutType")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("LogicalLayout")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("PhysicalLayout")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<float>("RedScale")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<float>("Rotation")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<float>("Scale")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<float>("X")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<float>("Y")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<int>("ZIndex")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Devices");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Artemis.Storage.Entities.Workshop.EntryEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Author")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<long>("EntryId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("EntryType")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset>("InstalledAt")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Metadata")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<long>("ReleaseId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("ReleaseVersion")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Entries");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Artemis.Storage.Entities.Plugins.PluginFeatureEntity", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Artemis.Storage.Entities.Plugins.PluginEntity", null)
|
||||||
|
.WithMany("Features")
|
||||||
|
.HasForeignKey("PluginEntityId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Artemis.Storage.Entities.Profile.ProfileContainerEntity", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Artemis.Storage.Entities.Profile.ProfileCategoryEntity", "ProfileCategory")
|
||||||
|
.WithMany("ProfileConfigurations")
|
||||||
|
.HasForeignKey("ProfileCategoryId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("ProfileCategory");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Artemis.Storage.Entities.Surface.DeviceEntity", b =>
|
||||||
|
{
|
||||||
|
b.OwnsOne("System.Collections.Generic.List<Artemis.Storage.Entities.Surface.DeviceInputIdentifierEntity>", "InputIdentifiers", b1 =>
|
||||||
|
{
|
||||||
|
b1.Property<string>("DeviceEntityId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b1.Property<int>("Capacity")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b1.HasKey("DeviceEntityId");
|
||||||
|
|
||||||
|
b1.ToTable("Devices");
|
||||||
|
|
||||||
|
b1.ToJson("InputIdentifiers");
|
||||||
|
|
||||||
|
b1.WithOwner()
|
||||||
|
.HasForeignKey("DeviceEntityId");
|
||||||
|
});
|
||||||
|
|
||||||
|
b.OwnsOne("System.Collections.Generic.List<Artemis.Storage.Entities.Surface.InputMappingEntity>", "InputMappings", b1 =>
|
||||||
|
{
|
||||||
|
b1.Property<string>("DeviceEntityId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b1.Property<int>("Capacity")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b1.HasKey("DeviceEntityId");
|
||||||
|
|
||||||
|
b1.ToTable("Devices");
|
||||||
|
|
||||||
|
b1.ToJson("InputMappings");
|
||||||
|
|
||||||
|
b1.WithOwner()
|
||||||
|
.HasForeignKey("DeviceEntityId");
|
||||||
|
});
|
||||||
|
|
||||||
|
b.Navigation("InputIdentifiers")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("InputMappings")
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Artemis.Storage.Entities.Plugins.PluginEntity", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Features");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Artemis.Storage.Entities.Profile.ProfileCategoryEntity", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("ProfileConfigurations");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
194
src/Artemis.Storage/Migrations/20240308203921_Initial.cs
Normal file
194
src/Artemis.Storage/Migrations/20240308203921_Initial.cs
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Artemis.Storage.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class Initial : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "Devices",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<string>(type: "TEXT", nullable: false),
|
||||||
|
DeviceProvider = table.Column<string>(type: "TEXT", nullable: false),
|
||||||
|
X = table.Column<float>(type: "REAL", nullable: false),
|
||||||
|
Y = table.Column<float>(type: "REAL", nullable: false),
|
||||||
|
Rotation = table.Column<float>(type: "REAL", nullable: false),
|
||||||
|
Scale = table.Column<float>(type: "REAL", nullable: false),
|
||||||
|
ZIndex = table.Column<int>(type: "INTEGER", nullable: false),
|
||||||
|
RedScale = table.Column<float>(type: "REAL", nullable: false),
|
||||||
|
GreenScale = table.Column<float>(type: "REAL", nullable: false),
|
||||||
|
BlueScale = table.Column<float>(type: "REAL", nullable: false),
|
||||||
|
IsEnabled = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||||
|
PhysicalLayout = table.Column<int>(type: "INTEGER", nullable: false),
|
||||||
|
LogicalLayout = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
LayoutType = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
LayoutParameter = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
Categories = table.Column<string>(type: "TEXT", nullable: false),
|
||||||
|
InputIdentifiers = table.Column<string>(type: "TEXT", nullable: false),
|
||||||
|
InputMappings = table.Column<string>(type: "TEXT", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_Devices", x => x.Id);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "Entries",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||||
|
EntryId = table.Column<long>(type: "INTEGER", nullable: false),
|
||||||
|
EntryType = table.Column<int>(type: "INTEGER", nullable: false),
|
||||||
|
Author = table.Column<string>(type: "TEXT", nullable: false),
|
||||||
|
Name = table.Column<string>(type: "TEXT", nullable: false),
|
||||||
|
ReleaseId = table.Column<long>(type: "INTEGER", nullable: false),
|
||||||
|
ReleaseVersion = table.Column<string>(type: "TEXT", nullable: false),
|
||||||
|
InstalledAt = table.Column<DateTimeOffset>(type: "TEXT", nullable: false),
|
||||||
|
Metadata = table.Column<string>(type: "TEXT", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_Entries", x => x.Id);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "Plugins",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||||
|
IsEnabled = table.Column<bool>(type: "INTEGER", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_Plugins", x => x.Id);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "PluginSettings",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||||
|
PluginGuid = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||||
|
Name = table.Column<string>(type: "TEXT", nullable: false),
|
||||||
|
Value = table.Column<string>(type: "TEXT", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_PluginSettings", x => x.Id);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "ProfileCategories",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||||
|
Name = table.Column<string>(type: "TEXT", nullable: false),
|
||||||
|
IsCollapsed = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||||
|
IsSuspended = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||||
|
Order = table.Column<int>(type: "INTEGER", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_ProfileCategories", x => x.Id);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "Releases",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||||
|
Version = table.Column<string>(type: "TEXT", nullable: false),
|
||||||
|
InstalledAt = table.Column<DateTimeOffset>(type: "TEXT", nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_Releases", x => x.Id);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "PluginFeatureEntity",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||||
|
Type = table.Column<string>(type: "TEXT", nullable: false),
|
||||||
|
IsEnabled = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||||
|
PluginEntityId = table.Column<Guid>(type: "TEXT", nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_PluginFeatureEntity", x => x.Id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_PluginFeatureEntity_Plugins_PluginEntityId",
|
||||||
|
column: x => x.PluginEntityId,
|
||||||
|
principalTable: "Plugins",
|
||||||
|
principalColumn: "Id");
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "ProfileContainerEntity",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||||
|
Icon = table.Column<byte[]>(type: "BLOB", nullable: false),
|
||||||
|
ProfileCategoryId = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||||
|
ProfileConfiguration = table.Column<string>(type: "TEXT", nullable: false),
|
||||||
|
Profile = table.Column<string>(type: "TEXT", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_ProfileContainerEntity", x => x.Id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_ProfileContainerEntity_ProfileCategories_ProfileCategoryId",
|
||||||
|
column: x => x.ProfileCategoryId,
|
||||||
|
principalTable: "ProfileCategories",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_PluginFeatureEntity_PluginEntityId",
|
||||||
|
table: "PluginFeatureEntity",
|
||||||
|
column: "PluginEntityId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_ProfileContainerEntity_ProfileCategoryId",
|
||||||
|
table: "ProfileContainerEntity",
|
||||||
|
column: "ProfileCategoryId");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "Devices");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "Entries");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "PluginFeatureEntity");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "PluginSettings");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "ProfileContainerEntity");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "Releases");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "Plugins");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "ProfileCategories");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
320
src/Artemis.Storage/Migrations/ArtemisDbContextModelSnapshot.cs
Normal file
320
src/Artemis.Storage/Migrations/ArtemisDbContextModelSnapshot.cs
Normal file
@ -0,0 +1,320 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Artemis.Storage;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Artemis.Storage.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(ArtemisDbContext))]
|
||||||
|
partial class ArtemisDbContextModelSnapshot : ModelSnapshot
|
||||||
|
{
|
||||||
|
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder.HasAnnotation("ProductVersion", "8.0.2");
|
||||||
|
|
||||||
|
modelBuilder.Entity("Artemis.Storage.Entities.General.ReleaseEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset?>("InstalledAt")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Version")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Releases");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Artemis.Storage.Entities.Plugins.PluginEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("IsEnabled")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Plugins");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Artemis.Storage.Entities.Plugins.PluginFeatureEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("IsEnabled")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<Guid?>("PluginEntityId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Type")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("PluginEntityId");
|
||||||
|
|
||||||
|
b.ToTable("PluginFeatureEntity");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Artemis.Storage.Entities.Plugins.PluginSettingEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<Guid>("PluginGuid")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Value")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("PluginSettings");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Artemis.Storage.Entities.Profile.ProfileCategoryEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("IsCollapsed")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("IsSuspended")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("Order")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("ProfileCategories");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Artemis.Storage.Entities.Profile.ProfileContainerEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<byte[]>("Icon")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("BLOB");
|
||||||
|
|
||||||
|
b.Property<string>("Profile")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<Guid>("ProfileCategoryId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ProfileConfiguration")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("ProfileCategoryId");
|
||||||
|
|
||||||
|
b.ToTable("ProfileContainerEntity");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Artemis.Storage.Entities.Surface.DeviceEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Id")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<float>("BlueScale")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<string>("Categories")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("DeviceProvider")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<float>("GreenScale")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<bool>("IsEnabled")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("LayoutParameter")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("LayoutType")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("LogicalLayout")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("PhysicalLayout")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<float>("RedScale")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<float>("Rotation")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<float>("Scale")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<float>("X")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<float>("Y")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<int>("ZIndex")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Devices");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Artemis.Storage.Entities.Workshop.EntryEntity", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Author")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<long>("EntryId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("EntryType")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset>("InstalledAt")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Metadata")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<long>("ReleaseId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("ReleaseVersion")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Entries");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Artemis.Storage.Entities.Plugins.PluginFeatureEntity", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Artemis.Storage.Entities.Plugins.PluginEntity", null)
|
||||||
|
.WithMany("Features")
|
||||||
|
.HasForeignKey("PluginEntityId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Artemis.Storage.Entities.Profile.ProfileContainerEntity", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Artemis.Storage.Entities.Profile.ProfileCategoryEntity", "ProfileCategory")
|
||||||
|
.WithMany("ProfileConfigurations")
|
||||||
|
.HasForeignKey("ProfileCategoryId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("ProfileCategory");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Artemis.Storage.Entities.Surface.DeviceEntity", b =>
|
||||||
|
{
|
||||||
|
b.OwnsOne("System.Collections.Generic.List<Artemis.Storage.Entities.Surface.DeviceInputIdentifierEntity>", "InputIdentifiers", b1 =>
|
||||||
|
{
|
||||||
|
b1.Property<string>("DeviceEntityId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b1.Property<int>("Capacity")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b1.HasKey("DeviceEntityId");
|
||||||
|
|
||||||
|
b1.ToTable("Devices");
|
||||||
|
|
||||||
|
b1.ToJson("InputIdentifiers");
|
||||||
|
|
||||||
|
b1.WithOwner()
|
||||||
|
.HasForeignKey("DeviceEntityId");
|
||||||
|
});
|
||||||
|
|
||||||
|
b.OwnsOne("System.Collections.Generic.List<Artemis.Storage.Entities.Surface.InputMappingEntity>", "InputMappings", b1 =>
|
||||||
|
{
|
||||||
|
b1.Property<string>("DeviceEntityId")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b1.Property<int>("Capacity")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b1.HasKey("DeviceEntityId");
|
||||||
|
|
||||||
|
b1.ToTable("Devices");
|
||||||
|
|
||||||
|
b1.ToJson("InputMappings");
|
||||||
|
|
||||||
|
b1.WithOwner()
|
||||||
|
.HasForeignKey("DeviceEntityId");
|
||||||
|
});
|
||||||
|
|
||||||
|
b.Navigation("InputIdentifiers")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("InputMappings")
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Artemis.Storage.Entities.Plugins.PluginEntity", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Features");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Artemis.Storage.Entities.Profile.ProfileCategoryEntity", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("ProfileConfigurations");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,14 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Artemis.Storage.Entities.Profile;
|
|
||||||
|
|
||||||
namespace Artemis.Storage.Repositories.Interfaces;
|
|
||||||
|
|
||||||
public interface IProfileRepository : IRepository
|
|
||||||
{
|
|
||||||
void Add(ProfileContainerEntity profileContainerEntity);
|
|
||||||
void Remove(ProfileContainerEntity profileContainerEntity);
|
|
||||||
List<ProfileContainerEntity> GetAll();
|
|
||||||
ProfileContainerEntity? Get(Guid id);
|
|
||||||
void SaveChanges();
|
|
||||||
}
|
|
||||||
@ -1,45 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Artemis.Storage.Entities.Profile;
|
|
||||||
using Artemis.Storage.Repositories.Interfaces;
|
|
||||||
using LiteDB;
|
|
||||||
|
|
||||||
namespace Artemis.Storage.Repositories;
|
|
||||||
|
|
||||||
internal class ProfileRepository : IProfileRepository
|
|
||||||
{
|
|
||||||
private readonly ArtemisDbContext _dbContext;
|
|
||||||
|
|
||||||
public ProfileRepository(ArtemisDbContext dbContext)
|
|
||||||
{
|
|
||||||
_dbContext = dbContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Add(ProfileContainerEntity profileContainerEntity)
|
|
||||||
{
|
|
||||||
_dbContext.Profiles.Add(profileContainerEntity);
|
|
||||||
SaveChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Remove(ProfileContainerEntity profileContainerEntity)
|
|
||||||
{
|
|
||||||
_dbContext.Profiles.Remove(profileContainerEntity);
|
|
||||||
SaveChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ProfileContainerEntity> GetAll()
|
|
||||||
{
|
|
||||||
return _dbContext.Profiles.ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProfileContainerEntity? Get(Guid id)
|
|
||||||
{
|
|
||||||
return _dbContext.Profiles.FirstOrDefault(c => c.Profile.Id == id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SaveChanges()
|
|
||||||
{
|
|
||||||
_dbContext.SaveChanges();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -59,4 +59,12 @@ public static class StorageManager
|
|||||||
throw new Exception($"LiteDB threw error code {e.ErrorCode}. See inner exception for more details", e);
|
throw new Exception($"LiteDB threw error code {e.ErrorCode}. See inner exception for more details", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ArtemisDbContext CreateDbContext(string dataFolder)
|
||||||
|
{
|
||||||
|
return new ArtemisDbContext()
|
||||||
|
{
|
||||||
|
DataFolder = dataFolder
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -46,17 +46,10 @@ public partial class ProfileConfigurationIcon : UserControl, IDisposable
|
|||||||
? new MaterialIcon {Kind = parsedIcon!}
|
? new MaterialIcon {Kind = parsedIcon!}
|
||||||
: new MaterialIcon {Kind = MaterialIconKind.QuestionMark};
|
: new MaterialIcon {Kind = MaterialIconKind.QuestionMark};
|
||||||
}
|
}
|
||||||
|
else if (ConfigurationIcon.IconBytes != null)
|
||||||
|
Dispatcher.UIThread.Post(() => LoadFromBitmap(ConfigurationIcon, new MemoryStream(ConfigurationIcon.IconBytes)), DispatcherPriority.ApplicationIdle);
|
||||||
else
|
else
|
||||||
{
|
Content = new MaterialIcon {Kind = MaterialIconKind.QuestionMark};
|
||||||
Dispatcher.UIThread.Post(() =>
|
|
||||||
{
|
|
||||||
Stream? stream = ConfigurationIcon?.GetIconStream();
|
|
||||||
if (stream == null || ConfigurationIcon == null)
|
|
||||||
Content = new MaterialIcon {Kind = MaterialIconKind.QuestionMark};
|
|
||||||
else
|
|
||||||
LoadFromBitmap(ConfigurationIcon, stream);
|
|
||||||
}, DispatcherPriority.ApplicationIdle);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -186,7 +186,7 @@ public partial class ProfileEditorViewModel : RoutableScreen<ProfileEditorViewMo
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override async Task OnNavigating(ProfileEditorViewModelParameters parameters, NavigationArguments args, CancellationToken cancellationToken)
|
public override async Task OnNavigating(ProfileEditorViewModelParameters parameters, NavigationArguments args, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
ProfileConfiguration? profileConfiguration = _profileService.ProfileConfigurations.FirstOrDefault(c => c.ProfileId == parameters.ProfileId);
|
ProfileConfiguration? profileConfiguration = _profileService.ProfileCategories.SelectMany(c => c.ProfileConfigurations).FirstOrDefault(c => c.ProfileId == parameters.ProfileId);
|
||||||
|
|
||||||
// If the profile doesn't exist, cancel navigation
|
// If the profile doesn't exist, cancel navigation
|
||||||
if (profileConfiguration == null)
|
if (profileConfiguration == null)
|
||||||
|
|||||||
@ -123,7 +123,6 @@ public partial class ProfileConfigurationEditViewModel : DialogViewModelBase<Pro
|
|||||||
|
|
||||||
await SaveIcon();
|
await SaveIcon();
|
||||||
|
|
||||||
_profileService.SaveProfileConfigurationIcon(ProfileConfiguration);
|
|
||||||
_profileService.SaveProfileCategory(_profileCategory);
|
_profileService.SaveProfileCategory(_profileCategory);
|
||||||
Close(ProfileConfiguration);
|
Close(ProfileConfiguration);
|
||||||
}
|
}
|
||||||
@ -144,7 +143,7 @@ public partial class ProfileConfigurationEditViewModel : DialogViewModelBase<Pro
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Stream? iconStream = _profileConfiguration.Icon.GetIconStream();
|
Stream? iconStream = _profileConfiguration.Icon.IconBytes != null ? new MemoryStream(_profileConfiguration.Icon.IconBytes) : null;
|
||||||
SelectedBitmapSource = iconStream != null ? new Bitmap(iconStream) : null;
|
SelectedBitmapSource = iconStream != null ? new Bitmap(iconStream) : null;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|||||||
@ -40,15 +40,6 @@ public class SidebarProfileConfigurationViewModel : ActivatableViewModelBase
|
|||||||
.Select(p => p == null)
|
.Select(p => p == null)
|
||||||
.ToProperty(this, vm => vm.IsDisabled)
|
.ToProperty(this, vm => vm.IsDisabled)
|
||||||
.DisposeWith(d));
|
.DisposeWith(d));
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_profileService.LoadProfileConfigurationIcon(ProfileConfiguration);
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
// ignored, too bad but don't crash over corrupt icons
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProfileConfiguration ProfileConfiguration { get; }
|
public ProfileConfiguration ProfileConfiguration { get; }
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reactive.Disposables;
|
using System.Reactive.Disposables;
|
||||||
using System.Reactive.Linq;
|
using System.Reactive.Linq;
|
||||||
@ -27,10 +28,7 @@ public partial class ProfileSelectionStepViewModel : SubmissionViewModel
|
|||||||
_profileService = profileService;
|
_profileService = profileService;
|
||||||
|
|
||||||
// Use copies of the profiles, the originals are used by the core and could be disposed
|
// Use copies of the profiles, the originals are used by the core and could be disposed
|
||||||
Profiles = new ObservableCollection<ProfileConfiguration>(_profileService.ProfileConfigurations.Select(_profileService.CloneProfileConfiguration));
|
Profiles = new ObservableCollection<ProfileConfiguration>(_profileService.ProfileCategories.SelectMany(c => c.ProfileConfigurations).Select(_profileService.CloneProfileConfiguration));
|
||||||
foreach (ProfileConfiguration profileConfiguration in Profiles)
|
|
||||||
_profileService.LoadProfileConfigurationIcon(profileConfiguration);
|
|
||||||
|
|
||||||
ProfilePreview = profilePreviewViewModel;
|
ProfilePreview = profilePreviewViewModel;
|
||||||
|
|
||||||
GoBack = ReactiveCommand.Create(() => State.ChangeScreen<EntryTypeStepViewModel>());
|
GoBack = ReactiveCommand.Create(() => State.ChangeScreen<EntryTypeStepViewModel>());
|
||||||
@ -70,7 +68,7 @@ public partial class ProfileSelectionStepViewModel : SubmissionViewModel
|
|||||||
|
|
||||||
State.EntrySource = new ProfileEntrySource(SelectedProfile, SelectedProfile.GetFeatureDependencies().Distinct().ToList());
|
State.EntrySource = new ProfileEntrySource(SelectedProfile, SelectedProfile.GetFeatureDependencies().Distinct().ToList());
|
||||||
State.Name = SelectedProfile.Name;
|
State.Name = SelectedProfile.Name;
|
||||||
State.Icon = SelectedProfile.Icon.GetIconStream();
|
State.Icon = SelectedProfile.Icon.IconBytes != null ? new MemoryStream(SelectedProfile.Icon.IconBytes) : null;
|
||||||
|
|
||||||
// Render the material icon of the profile
|
// Render the material icon of the profile
|
||||||
if (State.Icon == null && SelectedProfile.Icon.IconName != null)
|
if (State.Icon == null && SelectedProfile.Icon.IconName != null)
|
||||||
|
|||||||
@ -74,7 +74,7 @@ public class ProfileEntryInstallationHandler : IEntryInstallationHandler
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Find the profile if still there
|
// Find the profile if still there
|
||||||
ProfileConfiguration? profile = _profileService.ProfileConfigurations.FirstOrDefault(c => c.ProfileId == profileId);
|
ProfileConfiguration? profile = _profileService.ProfileCategories.SelectMany(c => c.ProfileConfigurations).FirstOrDefault(c => c.ProfileId == profileId);
|
||||||
if (profile != null)
|
if (profile != null)
|
||||||
_profileService.DeleteProfile(profile);
|
_profileService.DeleteProfile(profile);
|
||||||
|
|
||||||
|
|||||||
@ -1,16 +1,12 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Text.Json;
|
|
||||||
using System.Text.Json.Nodes;
|
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.Storage.Entities.Workshop;
|
using Artemis.Storage.Entities.Workshop;
|
||||||
using Artemis.WebClient.Workshop.Exceptions;
|
|
||||||
|
|
||||||
namespace Artemis.WebClient.Workshop.Models;
|
namespace Artemis.WebClient.Workshop.Models;
|
||||||
|
|
||||||
public class InstalledEntry
|
public class InstalledEntry
|
||||||
{
|
{
|
||||||
private static readonly JsonSerializerOptions JsonSerializerOptions = CoreJson.GetJsonSerializerOptions();
|
private Dictionary<string, object> _metadata = new();
|
||||||
private Dictionary<string, JsonNode> _metadata = new();
|
|
||||||
|
|
||||||
internal InstalledEntry(EntryEntity entity)
|
internal InstalledEntry(EntryEntity entity)
|
||||||
{
|
{
|
||||||
@ -56,7 +52,7 @@ public class InstalledEntry
|
|||||||
ReleaseVersion = Entity.ReleaseVersion;
|
ReleaseVersion = Entity.ReleaseVersion;
|
||||||
InstalledAt = Entity.InstalledAt;
|
InstalledAt = Entity.InstalledAt;
|
||||||
|
|
||||||
_metadata = Entity.Metadata != null ? new Dictionary<string, JsonNode>(Entity.Metadata) : new Dictionary<string, JsonNode>();
|
_metadata = Entity.Metadata != null ? new Dictionary<string, object>(Entity.Metadata) : new Dictionary<string, object>();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Save()
|
internal void Save()
|
||||||
@ -71,7 +67,7 @@ public class InstalledEntry
|
|||||||
Entity.ReleaseVersion = ReleaseVersion;
|
Entity.ReleaseVersion = ReleaseVersion;
|
||||||
Entity.InstalledAt = InstalledAt;
|
Entity.InstalledAt = InstalledAt;
|
||||||
|
|
||||||
Entity.Metadata = new Dictionary<string, JsonNode>(_metadata);
|
Entity.Metadata = new Dictionary<string, object>(_metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -84,29 +80,14 @@ public class InstalledEntry
|
|||||||
/// <returns><see langword="true"/> if the metadata contains an element with the specified key; otherwise, <see langword="false"/>.</returns>
|
/// <returns><see langword="true"/> if the metadata contains an element with the specified key; otherwise, <see langword="false"/>.</returns>
|
||||||
public bool TryGetMetadata<T>(string key, [NotNullWhen(true)] out T? value)
|
public bool TryGetMetadata<T>(string key, [NotNullWhen(true)] out T? value)
|
||||||
{
|
{
|
||||||
if (!_metadata.TryGetValue(key, out JsonNode? jsonNode))
|
if (!_metadata.TryGetValue(key, out object? objectValue) || objectValue is not T result)
|
||||||
{
|
{
|
||||||
value = default;
|
value = default;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
value = result;
|
||||||
{
|
return true;
|
||||||
T? deserialized = jsonNode.Deserialize<T>(JsonSerializerOptions);
|
|
||||||
if (deserialized != null)
|
|
||||||
{
|
|
||||||
value = deserialized;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
value = default;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
value = default;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -116,8 +97,7 @@ public class InstalledEntry
|
|||||||
/// <param name="value">The value to set.</param>
|
/// <param name="value">The value to set.</param>
|
||||||
public void SetMetadata(string key, object value)
|
public void SetMetadata(string key, object value)
|
||||||
{
|
{
|
||||||
JsonNode? jsonNode = JsonSerializer.SerializeToNode(value, JsonSerializerOptions);
|
_metadata[key] = value;
|
||||||
_metadata[key] = jsonNode ?? throw new ArtemisWorkshopException("Failed to serialize metadata value");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -29,6 +29,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
|||||||
Directory.Build.props = Directory.Build.props
|
Directory.Build.props = Directory.Build.props
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Artemis.Storage.Migrator", "Artemis.Storage.Migrator\Artemis.Storage.Migrator.csproj", "{D7B0966D-774A-40E4-9455-00C1261ACB6A}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|x64 = Debug|x64
|
Debug|x64 = Debug|x64
|
||||||
@ -71,6 +73,10 @@ Global
|
|||||||
{2B982C2E-3CBC-4DAB-9167-CCCA4C78E92B}.Debug|x64.Build.0 = Debug|x64
|
{2B982C2E-3CBC-4DAB-9167-CCCA4C78E92B}.Debug|x64.Build.0 = Debug|x64
|
||||||
{2B982C2E-3CBC-4DAB-9167-CCCA4C78E92B}.Release|x64.ActiveCfg = Release|x64
|
{2B982C2E-3CBC-4DAB-9167-CCCA4C78E92B}.Release|x64.ActiveCfg = Release|x64
|
||||||
{2B982C2E-3CBC-4DAB-9167-CCCA4C78E92B}.Release|x64.Build.0 = Release|x64
|
{2B982C2E-3CBC-4DAB-9167-CCCA4C78E92B}.Release|x64.Build.0 = Release|x64
|
||||||
|
{D7B0966D-774A-40E4-9455-00C1261ACB6A}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{D7B0966D-774A-40E4-9455-00C1261ACB6A}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{D7B0966D-774A-40E4-9455-00C1261ACB6A}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{D7B0966D-774A-40E4-9455-00C1261ACB6A}.Release|x64.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
@ -30,6 +30,7 @@
|
|||||||
<PackageVersion Include="Material.Icons.Avalonia" Version="2.1.0" />
|
<PackageVersion Include="Material.Icons.Avalonia" Version="2.1.0" />
|
||||||
<PackageVersion Include="McMaster.NETCore.Plugins" Version="1.4.0" />
|
<PackageVersion Include="McMaster.NETCore.Plugins" Version="1.4.0" />
|
||||||
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="8.0.2" />
|
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="8.0.2" />
|
||||||
|
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.2" />
|
||||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.2" />
|
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.2" />
|
||||||
<PackageVersion Include="Microsoft.Extensions.Http" Version="8.0.0" />
|
<PackageVersion Include="Microsoft.Extensions.Http" Version="8.0.0" />
|
||||||
<PackageVersion Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.3" />
|
<PackageVersion Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.3" />
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user