1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2026-01-02 10:43:31 +00:00

Compare commits

..

No commits in common. "7f5bb589af124fd339ef48c13539371f5410631e" and "b00f5ca73a29e6a4bc40f64a65f5bfbbbad63633" have entirely different histories.

9 changed files with 199 additions and 237 deletions

View File

@ -14,7 +14,6 @@ public class EntryEntity
public int EntryType { get; set; } public int EntryType { get; set; }
public string Author { get; set; } = string.Empty; public string Author { get; set; } = string.Empty;
public bool IsOfficial { get; set; }
public string Name { get; set; } = string.Empty; public string Name { get; set; } = string.Empty;
public string Summary { get; set; } = string.Empty; public string Summary { get; set; } = string.Empty;
public long Downloads { get; set; } public long Downloads { get; set; }

View File

@ -11,8 +11,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace Artemis.Storage.Migrations namespace Artemis.Storage.Migrations
{ {
[DbContext(typeof(ArtemisDbContext))] [DbContext(typeof(ArtemisDbContext))]
[Migration("20240722084220_AutoUpdating")] [Migration("20240706131336_ExpandInstalledEntry")]
partial class AutoUpdating partial class ExpandInstalledEntry
{ {
/// <inheritdoc /> /// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder) protected override void BuildTargetModel(ModelBuilder modelBuilder)
@ -264,9 +264,6 @@ namespace Artemis.Storage.Migrations
b.Property<DateTimeOffset>("InstalledAt") b.Property<DateTimeOffset>("InstalledAt")
.HasColumnType("TEXT"); .HasColumnType("TEXT");
b.Property<bool>("IsOfficial")
.HasColumnType("INTEGER");
b.Property<long?>("LatestReleaseId") b.Property<long?>("LatestReleaseId")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");

View File

@ -6,7 +6,7 @@ using Microsoft.EntityFrameworkCore.Migrations;
namespace Artemis.Storage.Migrations namespace Artemis.Storage.Migrations
{ {
/// <inheritdoc /> /// <inheritdoc />
public partial class AutoUpdating : Migration public partial class ExpandInstalledEntry : Migration
{ {
/// <inheritdoc /> /// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder) protected override void Up(MigrationBuilder migrationBuilder)
@ -38,13 +38,6 @@ namespace Artemis.Storage.Migrations
nullable: false, nullable: false,
defaultValue: 0L); defaultValue: 0L);
migrationBuilder.AddColumn<bool>(
name: "IsOfficial",
table: "Entries",
type: "INTEGER",
nullable: false,
defaultValue: false);
migrationBuilder.AddColumn<long>( migrationBuilder.AddColumn<long>(
name: "LatestReleaseId", name: "LatestReleaseId",
table: "Entries", table: "Entries",
@ -94,10 +87,6 @@ namespace Artemis.Storage.Migrations
name: "Downloads", name: "Downloads",
table: "Entries"); table: "Entries");
migrationBuilder.DropColumn(
name: "IsOfficial",
table: "Entries");
migrationBuilder.DropColumn( migrationBuilder.DropColumn(
name: "LatestReleaseId", name: "LatestReleaseId",
table: "Entries"); table: "Entries");

View File

@ -261,9 +261,6 @@ namespace Artemis.Storage.Migrations
b.Property<DateTimeOffset>("InstalledAt") b.Property<DateTimeOffset>("InstalledAt")
.HasColumnType("TEXT"); .HasColumnType("TEXT");
b.Property<bool>("IsOfficial")
.HasColumnType("INTEGER");
b.Property<long?>("LatestReleaseId") b.Property<long?>("LatestReleaseId")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");

View File

@ -39,7 +39,7 @@
<TextBlock Grid.Row="0" Margin="0 0 0 5" TextTrimming="CharacterEllipsis"> <TextBlock Grid.Row="0" Margin="0 0 0 5" TextTrimming="CharacterEllipsis">
<Run Classes="h5" Text="{CompiledBinding Entry.Name, FallbackValue=Title}" /> <Run Classes="h5" Text="{CompiledBinding Entry.Name, FallbackValue=Title}" />
<Run Classes="subtitle">by you</Run> <Run Classes="subtitle">by you</Run>
<Run Text="{CompiledBinding Emoji}" /> <Run Classes="subtitle" Text="{CompiledBinding Emoji}" />
</TextBlock> </TextBlock>
<TextBlock Grid.Row="1" <TextBlock Grid.Row="1"
Classes="subtitle" Classes="subtitle"

View File

@ -11,7 +11,7 @@ namespace Artemis.UI.Screens.Workshop.Library.Tabs;
public class SubmissionsTabItemViewModel : ViewModelBase public class SubmissionsTabItemViewModel : ViewModelBase
{ {
private static readonly string[] Emojis = ["❤️", "🧡", "💛", "💚", "💙", "💜", "💔", "❣️", "💕", "💞", "💓", "💗", "💖", "💘", "💝", "😍", "🥰"]; private static readonly string[] Emojis = ["❤️", "🧡", "💛", "💚", "💙", "💜", "🤍", "💔", "❣️", "💕", "💞", "💓", "💗", "💖", "💘", "💝", "😍", "🥰"];
private readonly IRouter _router; private readonly IRouter _router;
public SubmissionsTabItemViewModel(IGetSubmittedEntries_SubmittedEntries entry, IRouter router) public SubmissionsTabItemViewModel(IGetSubmittedEntries_SubmittedEntries entry, IRouter router)

View File

@ -4,6 +4,7 @@ using System.Threading.Tasks;
using Artemis.Core; using Artemis.Core;
using Artemis.Core.Services; using Artemis.Core.Services;
using Artemis.UI.Services.Interfaces; using Artemis.UI.Services.Interfaces;
using Artemis.UI.Shared.Services;
using Artemis.UI.Shared.Utilities; using Artemis.UI.Shared.Utilities;
using Artemis.WebClient.Workshop; using Artemis.WebClient.Workshop;
using Artemis.WebClient.Workshop.Handlers.InstallationHandlers; using Artemis.WebClient.Workshop.Handlers.InstallationHandlers;
@ -18,11 +19,13 @@ public class WorkshopUpdateService : IWorkshopUpdateService
{ {
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IWorkshopClient _client; private readonly IWorkshopClient _client;
private readonly INotificationService _notificationService;
private readonly IWorkshopService _workshopService; private readonly IWorkshopService _workshopService;
private readonly Lazy<IUpdateNotificationProvider> _updateNotificationProvider; private readonly Lazy<IUpdateNotificationProvider> _updateNotificationProvider;
private readonly PluginSetting<bool> _showNotifications; private readonly PluginSetting<bool> _showNotifications;
public WorkshopUpdateService(ILogger logger, IWorkshopClient client, IWorkshopService workshopService, ISettingsService settingsService, Lazy<IUpdateNotificationProvider> updateNotificationProvider) public WorkshopUpdateService(ILogger logger, IWorkshopClient client, IWorkshopService workshopService, ISettingsService settingsService,
Lazy<IUpdateNotificationProvider> updateNotificationProvider)
{ {
_logger = logger; _logger = logger;
_client = client; _client = client;
@ -54,42 +57,28 @@ public class WorkshopUpdateService : IWorkshopUpdateService
_updateNotificationProvider.Value.ShowWorkshopNotification(updatedEntries); _updateNotificationProvider.Value.ShowWorkshopNotification(updatedEntries);
} }
public async Task<bool> AutoUpdateEntry(InstalledEntry installedEntry) public async Task<bool> AutoUpdateEntry(InstalledEntry entry)
{ {
// Query the latest version // Query the latest version
IOperationResult<IGetEntryLatestReleaseByIdResult> latestReleaseResult = await _client.GetEntryLatestReleaseById.ExecuteAsync(installedEntry.Id); IOperationResult<IGetEntryLatestReleaseByIdResult> latestReleaseResult = await _client.GetEntryLatestReleaseById.ExecuteAsync(entry.Id);
IEntrySummary? entry = latestReleaseResult.Data?.Entry?.LatestRelease?.Entry;
if (entry == null)
return false;
if (latestReleaseResult.Data?.Entry?.LatestRelease is not IRelease latestRelease) if (latestReleaseResult.Data?.Entry?.LatestRelease is not IRelease latestRelease)
return false; return false;
if (latestRelease.Id == installedEntry.ReleaseId) if (latestRelease.Id == entry.ReleaseId)
return false; return false;
_logger.Information("Auto-updating entry {Entry} to version {Version}", entry, latestRelease.Version); _logger.Information("Auto-updating entry {Entry} to version {Version}", entry, latestRelease.Version);
try
{
EntryInstallResult updateResult = await _workshopService.InstallEntry(entry, latestRelease, new Progress<StreamProgress>(), CancellationToken.None); EntryInstallResult updateResult = await _workshopService.InstallEntry(entry, latestRelease, new Progress<StreamProgress>(), CancellationToken.None);
// This happens during installation too but not on our reference of the entry // This happens during installation too but not on our reference of the entry
if (updateResult.IsSuccess) if (updateResult.IsSuccess)
installedEntry.ApplyRelease(latestRelease); entry.ApplyRelease(latestRelease);
if (updateResult.IsSuccess) _logger.Information("Auto-update result: {Result}", updateResult);
_logger.Information("Auto-update successful for entry {Entry}", entry);
else
_logger.Warning("Auto-update failed for entry {Entry}: {Message}", entry, updateResult.Message);
return updateResult.IsSuccess; return updateResult.IsSuccess;
} }
catch (Exception e)
{
_logger.Warning(e, "Auto-update failed for entry {Entry}", entry);
}
return false;
}
/// <inheritdoc /> /// <inheritdoc />
public void DisableNotifications() public void DisableNotifications()

View File

@ -6,22 +6,22 @@ using Artemis.Storage.Entities.Workshop;
namespace Artemis.WebClient.Workshop.Models; namespace Artemis.WebClient.Workshop.Models;
public class InstalledEntry : CorePropertyChanged public class InstalledEntry : CorePropertyChanged, IEntrySummary
{ {
private string _author;
private bool _autoUpdate;
private IReadOnlyList<InstalledEntryCategory> _categories;
private DateTimeOffset _createdAt;
private long _downloads;
private EntryType _entryType;
private long _id;
private bool _isOfficial;
private long? _latestReleaseId;
private Dictionary<string, JsonNode> _metadata = new(); private Dictionary<string, JsonNode> _metadata = new();
private long _id;
private string _author;
private bool _isOfficial;
private string _name; private string _name;
private string _summary;
private EntryType _entryType;
private long _downloads;
private DateTimeOffset _createdAt;
private long? _latestReleaseId;
private IReadOnlyList<IGetDependantEntries_Entries_Items_Categories> _categories;
private long _releaseId; private long _releaseId;
private string _releaseVersion = string.Empty; private string _releaseVersion = string.Empty;
private string _summary; private bool _autoUpdate;
internal InstalledEntry(EntryEntity entity) internal InstalledEntry(EntryEntity entity)
{ {
@ -40,6 +40,7 @@ public class InstalledEntry : CorePropertyChanged
AutoUpdate = true; AutoUpdate = true;
} }
internal EntryEntity Entity { get; }
public DateTimeOffset InstalledAt { get; set; } public DateTimeOffset InstalledAt { get; set; }
public long ReleaseId public long ReleaseId
@ -60,82 +61,55 @@ public class InstalledEntry : CorePropertyChanged
set => SetAndNotify(ref _autoUpdate, value); set => SetAndNotify(ref _autoUpdate, value);
} }
public long Id internal void Load()
{ {
get => _id; Id = Entity.EntryId;
private set => SetAndNotify(ref _id, value); Author = Entity.Author;
Name = Entity.Name;
Summary = Entity.Summary;
EntryType = (EntryType) Entity.EntryType;
Downloads = Entity.Downloads;
CreatedAt = Entity.CreatedAt;
LatestReleaseId = Entity.LatestReleaseId;
Categories = Entity.Categories?.Select(c => new GetDependantEntries_Entries_Items_Categories_Category(c.Name, c.Icon)).ToList() ?? [];
ReleaseId = Entity.ReleaseId;
ReleaseVersion = Entity.ReleaseVersion;
InstalledAt = Entity.InstalledAt;
AutoUpdate = Entity.AutoUpdate;
_metadata = Entity.Metadata != null ? new Dictionary<string, JsonNode>(Entity.Metadata) : [];
} }
public string Author internal void Save()
{ {
get => _author; Entity.EntryId = Id;
private set => SetAndNotify(ref _author, value); Entity.EntryType = (int) EntryType;
}
public bool IsOfficial Entity.Author = Author;
{ Entity.Name = Name;
get => _isOfficial; Entity.Summary = Summary;
private set => SetAndNotify(ref _isOfficial, value); Entity.Downloads = Downloads;
} Entity.CreatedAt = CreatedAt;
Entity.LatestReleaseId = LatestReleaseId;
Entity.Categories = Categories.Select(c => new EntryCategoryEntity(c.Name, c.Icon)).ToList();
public string Name Entity.ReleaseId = ReleaseId;
{ Entity.ReleaseVersion = ReleaseVersion;
get => _name; Entity.InstalledAt = InstalledAt;
private set => SetAndNotify(ref _name, value); Entity.AutoUpdate = AutoUpdate;
}
public string Summary Entity.Metadata = new Dictionary<string, JsonNode>(_metadata);
{
get => _summary;
private set => SetAndNotify(ref _summary, value);
} }
public EntryType EntryType
{
get => _entryType;
private set => SetAndNotify(ref _entryType, value);
}
public long Downloads
{
get => _downloads;
private set => SetAndNotify(ref _downloads, value);
}
public DateTimeOffset CreatedAt
{
get => _createdAt;
private set => SetAndNotify(ref _createdAt, value);
}
public long? LatestReleaseId
{
get => _latestReleaseId;
private set => SetAndNotify(ref _latestReleaseId, value);
}
public IReadOnlyList<InstalledEntryCategory> Categories
{
get => _categories;
private set => SetAndNotify(ref _categories, value);
}
internal EntryEntity Entity { get; }
/// <summary> /// <summary>
/// Gets the metadata value associated with the specified key. /// Gets the metadata value associated with the specified key.
/// </summary> /// </summary>
/// <param name="key">The key of the value to get.</param> /// <param name="key">The key of the value to get.</param>
/// <param name="value"> /// <param name="value">When this method returns, contains the value associated with the specified key, if the key is found and of type <typeparamref name="T"/>;
/// When this method returns, contains the value associated with the specified key, if the key is found and of type /// otherwise, the default value for the type of the value parameter. This parameter is passed uninitialized.</param>
/// <typeparamref name="T" />;
/// otherwise, the default value for the type of the value parameter. This parameter is passed uninitialized.
/// </param>
/// <typeparam name="T">The type of the value.</typeparam> /// <typeparam name="T">The type of the value.</typeparam>
/// <returns> /// <returns><see langword="true"/> if the metadata contains an element with the specified key; otherwise, <see langword="false"/>.</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? element)) if (!_metadata.TryGetValue(key, out JsonNode? element))
@ -162,7 +136,7 @@ public class InstalledEntry : CorePropertyChanged
/// Removes metadata with the provided key. /// Removes metadata with the provided key.
/// </summary> /// </summary>
/// <param name="key">The key of the metadata to remove</param> /// <param name="key">The key of the metadata to remove</param>
/// <returns><see langword="true" /> if the element is successfully found and removed; otherwise, <see langword="false" />.</returns> /// <returns><see langword="true"/> if the element is successfully found and removed; otherwise, <see langword="false"/>.</returns>
public bool RemoveMetadata(string key) public bool RemoveMetadata(string key)
{ {
return _metadata.Remove(key); return _metadata.Remove(key);
@ -209,55 +183,86 @@ public class InstalledEntry : CorePropertyChanged
Downloads = entry.Downloads; Downloads = entry.Downloads;
CreatedAt = entry.CreatedAt; CreatedAt = entry.CreatedAt;
LatestReleaseId = entry.LatestReleaseId; LatestReleaseId = entry.LatestReleaseId;
Categories = entry.Categories.Select(c => new InstalledEntryCategory(c.Name, c.Icon)).ToList(); Categories = entry.Categories;
} }
#region Implementation of IEntrySummary
/// <inheritdoc />
public long Id
{
get => _id;
private set => SetAndNotify(ref _id, value);
}
/// <inheritdoc />
public string Author
{
get => _author;
private set => SetAndNotify(ref _author, value);
}
/// <inheritdoc />
public bool IsOfficial
{
get => _isOfficial;
private set => SetAndNotify(ref _isOfficial, value);
}
/// <inheritdoc />
public string Name
{
get => _name;
private set => SetAndNotify(ref _name, value);
}
/// <inheritdoc />
public string Summary
{
get => _summary;
private set => SetAndNotify(ref _summary, value);
}
/// <inheritdoc />
public EntryType EntryType
{
get => _entryType;
private set => SetAndNotify(ref _entryType, value);
}
/// <inheritdoc />
public long Downloads
{
get => _downloads;
private set => SetAndNotify(ref _downloads, value);
}
/// <inheritdoc />
public DateTimeOffset CreatedAt
{
get => _createdAt;
private set => SetAndNotify(ref _createdAt, value);
}
/// <inheritdoc />
public long? LatestReleaseId
{
get => _latestReleaseId;
private set => SetAndNotify(ref _latestReleaseId, value);
}
/// <inheritdoc />
public IReadOnlyList<IGetDependantEntries_Entries_Items_Categories> Categories
{
get => _categories;
private set => SetAndNotify(ref _categories, value);
}
#endregion
/// <inheritdoc />
public override string ToString() public override string ToString()
{ {
return $"[{EntryType}] {Id} - {Name}"; return $"[{EntryType}] {Id} - {Name}";
} }
internal void Load()
{
Id = Entity.EntryId;
Author = Entity.Author;
IsOfficial = Entity.IsOfficial;
Name = Entity.Name;
Summary = Entity.Summary;
EntryType = (EntryType) Entity.EntryType;
Downloads = Entity.Downloads;
CreatedAt = Entity.CreatedAt;
LatestReleaseId = Entity.LatestReleaseId;
Categories = Entity.Categories?.Select(c => new InstalledEntryCategory(c.Name, c.Icon)).ToList() ?? [];
ReleaseId = Entity.ReleaseId;
ReleaseVersion = Entity.ReleaseVersion;
InstalledAt = Entity.InstalledAt;
AutoUpdate = Entity.AutoUpdate;
_metadata = Entity.Metadata != null ? new Dictionary<string, JsonNode>(Entity.Metadata) : [];
}
internal void Save()
{
Entity.EntryId = Id;
Entity.EntryType = (int) EntryType;
Entity.Author = Author;
Entity.IsOfficial = IsOfficial;
Entity.Name = Name;
Entity.Summary = Summary;
Entity.Downloads = Downloads;
Entity.CreatedAt = CreatedAt;
Entity.LatestReleaseId = LatestReleaseId;
Entity.Categories = Categories.Select(c => new EntryCategoryEntity(c.Name, c.Icon)).ToList();
Entity.ReleaseId = ReleaseId;
Entity.ReleaseVersion = ReleaseVersion;
Entity.InstalledAt = InstalledAt;
Entity.AutoUpdate = AutoUpdate;
Entity.Metadata = new Dictionary<string, JsonNode>(_metadata);
}
} }

View File

@ -1,14 +0,0 @@
namespace Artemis.WebClient.Workshop.Models;
public class InstalledEntryCategory
{
public InstalledEntryCategory(string name, string icon)
{
Name = name;
Icon = icon;
}
public string Name { get; }
public string Icon { get; }
}