diff --git a/src/Artemis.UI/Services/Updating/WorkshopUpdateService.cs b/src/Artemis.UI/Services/Updating/WorkshopUpdateService.cs index fc91709b4..9b7a13132 100644 --- a/src/Artemis.UI/Services/Updating/WorkshopUpdateService.cs +++ b/src/Artemis.UI/Services/Updating/WorkshopUpdateService.cs @@ -54,14 +54,16 @@ public class WorkshopUpdateService : IWorkshopUpdateService _updateNotificationProvider.Value.ShowWorkshopNotification(updatedEntries); } - public async Task AutoUpdateEntry(InstalledEntry entry) + public async Task AutoUpdateEntry(InstalledEntry installedEntry) { // Query the latest version - IOperationResult latestReleaseResult = await _client.GetEntryLatestReleaseById.ExecuteAsync(entry.Id); - + IOperationResult latestReleaseResult = await _client.GetEntryLatestReleaseById.ExecuteAsync(installedEntry.Id); + IGetEntryById_Entry_LatestRelease_Entry? entry = latestReleaseResult.Data?.Entry?.LatestRelease?.Entry; + if (entry == null) + return false; if (latestReleaseResult.Data?.Entry?.LatestRelease is not IRelease latestRelease) return false; - if (latestRelease.Id == entry.ReleaseId) + if (latestRelease.Id == installedEntry.ReleaseId) return false; _logger.Information("Auto-updating entry {Entry} to version {Version}", entry, latestRelease.Version); @@ -72,7 +74,7 @@ public class WorkshopUpdateService : IWorkshopUpdateService // This happens during installation too but not on our reference of the entry if (updateResult.IsSuccess) - entry.ApplyRelease(latestRelease); + installedEntry.ApplyRelease(latestRelease); if (updateResult.IsSuccess) _logger.Information("Auto-update successful for entry {Entry}", entry); diff --git a/src/Artemis.WebClient.Workshop/Models/InstalledEntry.cs b/src/Artemis.WebClient.Workshop/Models/InstalledEntry.cs index 76f0487c1..b07033ca6 100644 --- a/src/Artemis.WebClient.Workshop/Models/InstalledEntry.cs +++ b/src/Artemis.WebClient.Workshop/Models/InstalledEntry.cs @@ -6,22 +6,22 @@ using Artemis.Storage.Entities.Workshop; namespace Artemis.WebClient.Workshop.Models; -public class InstalledEntry : CorePropertyChanged, IEntrySummary +public class InstalledEntry : CorePropertyChanged { - private Dictionary _metadata = new(); - private long _id; private string _author; - private bool _isOfficial; - private string _name; - private string _summary; - private EntryType _entryType; - private long _downloads; + private bool _autoUpdate; + private IReadOnlyList _categories; private DateTimeOffset _createdAt; + private long _downloads; + private EntryType _entryType; + private long _id; + private bool _isOfficial; private long? _latestReleaseId; - private IReadOnlyList _categories; + private Dictionary _metadata = new(); + private string _name; private long _releaseId; private string _releaseVersion = string.Empty; - private bool _autoUpdate; + private string _summary; internal InstalledEntry(EntryEntity entity) { @@ -40,7 +40,6 @@ public class InstalledEntry : CorePropertyChanged, IEntrySummary AutoUpdate = true; } - internal EntryEntity Entity { get; } public DateTimeOffset InstalledAt { get; set; } public long ReleaseId @@ -61,6 +60,164 @@ public class InstalledEntry : CorePropertyChanged, IEntrySummary set => SetAndNotify(ref _autoUpdate, value); } + public long Id + { + get => _id; + private set => SetAndNotify(ref _id, value); + } + + public string Author + { + get => _author; + private set => SetAndNotify(ref _author, value); + } + + public bool IsOfficial + { + get => _isOfficial; + private set => SetAndNotify(ref _isOfficial, value); + } + + public string Name + { + get => _name; + private set => SetAndNotify(ref _name, value); + } + + public string Summary + { + 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 Categories + { + get => _categories; + private set => SetAndNotify(ref _categories, value); + } + + internal EntryEntity Entity { get; } + + /// + /// Gets the metadata value associated with the specified key. + /// + /// The key of the value to get. + /// + /// 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. + /// + /// The type of the value. + /// + /// if the metadata contains an element with the specified key; otherwise, + /// . + /// + public bool TryGetMetadata(string key, [NotNullWhen(true)] out T? value) + { + if (!_metadata.TryGetValue(key, out JsonNode? element)) + { + value = default; + return false; + } + + value = element.GetValue(); + return value != null; + } + + /// + /// Sets metadata with the provided key to the provided value. + /// + /// The key of the value to set + /// The value to set. + public void SetMetadata(string key, object value) + { + _metadata[key] = JsonSerializer.SerializeToNode(value) ?? throw new InvalidOperationException(); + } + + /// + /// Removes metadata with the provided key. + /// + /// The key of the metadata to remove + /// if the element is successfully found and removed; otherwise, . + public bool RemoveMetadata(string key) + { + return _metadata.Remove(key); + } + + /// + /// Returns the directory info of the entry, where any files would be stored if applicable. + /// + /// The directory info of the directory. + public DirectoryInfo GetDirectory() + { + return new DirectoryInfo(Path.Combine(Constants.WorkshopFolder, $"{Id}-{StringUtilities.UrlFriendly(Name)}")); + } + + /// + /// Returns the directory info of a release of this entry, where any files would be stored if applicable. + /// + /// The release to use, if none provided the current release is used. + /// The directory info of the directory. + public DirectoryInfo GetReleaseDirectory(IRelease? release = null) + { + return new DirectoryInfo(Path.Combine(GetDirectory().FullName, StringUtilities.UrlFriendly(release?.Version ?? ReleaseVersion))); + } + + /// + /// Applies the provided release to the installed entry. + /// + /// The release to apply. + public void ApplyRelease(IRelease release) + { + ReleaseId = release.Id; + ReleaseVersion = release.Version; + InstalledAt = DateTimeOffset.UtcNow; + } + + public void ApplyEntrySummary(IEntrySummary entry) + { + Id = entry.Id; + Author = entry.Author; + IsOfficial = entry.IsOfficial; + Name = entry.Name; + Summary = entry.Summary; + EntryType = entry.EntryType; + Downloads = entry.Downloads; + CreatedAt = entry.CreatedAt; + LatestReleaseId = entry.LatestReleaseId; + Categories = entry.Categories.Select(c => new InstalledEntryCategory(c.Name, c.Icon)).ToList(); + } + + + public override string ToString() + { + return $"[{EntryType}] {Id} - {Name}"; + } + internal void Load() { Id = Entity.EntryId; @@ -72,8 +229,8 @@ public class InstalledEntry : CorePropertyChanged, IEntrySummary 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() ?? []; - + Categories = Entity.Categories?.Select(c => new InstalledEntryCategory(c.Name, c.Icon)).ToList() ?? []; + ReleaseId = Entity.ReleaseId; ReleaseVersion = Entity.ReleaseVersion; InstalledAt = Entity.InstalledAt; @@ -100,171 +257,7 @@ public class InstalledEntry : CorePropertyChanged, IEntrySummary Entity.ReleaseVersion = ReleaseVersion; Entity.InstalledAt = InstalledAt; Entity.AutoUpdate = AutoUpdate; - + Entity.Metadata = new Dictionary(_metadata); } - - /// - /// Gets the metadata value associated with the specified key. - /// - /// The key of the value to get. - /// 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. - /// The type of the value. - /// if the metadata contains an element with the specified key; otherwise, . - public bool TryGetMetadata(string key, [NotNullWhen(true)] out T? value) - { - if (!_metadata.TryGetValue(key, out JsonNode? element)) - { - value = default; - return false; - } - - value = element.GetValue(); - return value != null; - } - - /// - /// Sets metadata with the provided key to the provided value. - /// - /// The key of the value to set - /// The value to set. - public void SetMetadata(string key, object value) - { - _metadata[key] = JsonSerializer.SerializeToNode(value) ?? throw new InvalidOperationException(); - } - - /// - /// Removes metadata with the provided key. - /// - /// The key of the metadata to remove - /// if the element is successfully found and removed; otherwise, . - public bool RemoveMetadata(string key) - { - return _metadata.Remove(key); - } - - /// - /// Returns the directory info of the entry, where any files would be stored if applicable. - /// - /// The directory info of the directory. - public DirectoryInfo GetDirectory() - { - return new DirectoryInfo(Path.Combine(Constants.WorkshopFolder, $"{Id}-{StringUtilities.UrlFriendly(Name)}")); - } - - /// - /// Returns the directory info of a release of this entry, where any files would be stored if applicable. - /// - /// The release to use, if none provided the current release is used. - /// The directory info of the directory. - public DirectoryInfo GetReleaseDirectory(IRelease? release = null) - { - return new DirectoryInfo(Path.Combine(GetDirectory().FullName, StringUtilities.UrlFriendly(release?.Version ?? ReleaseVersion))); - } - - /// - /// Applies the provided release to the installed entry. - /// - /// The release to apply. - public void ApplyRelease(IRelease release) - { - ReleaseId = release.Id; - ReleaseVersion = release.Version; - InstalledAt = DateTimeOffset.UtcNow; - } - - public void ApplyEntrySummary(IEntrySummary entry) - { - Id = entry.Id; - Author = entry.Author; - IsOfficial = entry.IsOfficial; - Name = entry.Name; - Summary = entry.Summary; - EntryType = entry.EntryType; - Downloads = entry.Downloads; - CreatedAt = entry.CreatedAt; - LatestReleaseId = entry.LatestReleaseId; - Categories = entry.Categories; - } - - #region Implementation of IEntrySummary - - /// - public long Id - { - get => _id; - private set => SetAndNotify(ref _id, value); - } - - /// - public string Author - { - get => _author; - private set => SetAndNotify(ref _author, value); - } - - /// - public bool IsOfficial - { - get => _isOfficial; - private set => SetAndNotify(ref _isOfficial, value); - } - - /// - public string Name - { - get => _name; - private set => SetAndNotify(ref _name, value); - } - - /// - public string Summary - { - 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 Categories - { - get => _categories; - private set => SetAndNotify(ref _categories, value); - } - - #endregion - - /// - public override string ToString() - { - return $"[{EntryType}] {Id} - {Name}"; - } } \ No newline at end of file diff --git a/src/Artemis.WebClient.Workshop/Models/InstalledEntryCategory.cs b/src/Artemis.WebClient.Workshop/Models/InstalledEntryCategory.cs new file mode 100644 index 000000000..5a2421406 --- /dev/null +++ b/src/Artemis.WebClient.Workshop/Models/InstalledEntryCategory.cs @@ -0,0 +1,14 @@ +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; } +} \ No newline at end of file