From 8e263a69840d08887ec3230d77407ff11a425c63 Mon Sep 17 00:00:00 2001 From: halgari Date: Tue, 17 Sep 2024 14:34:20 -0600 Subject: [PATCH 01/11] Oof, I suck at UI --- .../Attributes/FloatAttribute.cs | 18 +++++ .../CollectionTag.cs | 23 ++++++ .../GraphQLResolver.cs | 66 +++++++++++++++++ .../Models/Collection.cs | 49 ++++++++++++ .../Models/CollectionRevision.cs | 49 ++++++++++++ .../Models/User.cs | 28 +++++++ .../NexusModsCollectionLibraryFile.cs | 2 +- .../NexusModsCollectionMetadata.cs | 28 ------- .../NexusModsCollectionRevision.cs | 28 ------- .../Services.cs | 6 +- .../GraphQL/CollectionInfo.graphql | 6 ++ .../GraphQL/CollectionRevisionInfo.graphql | 12 --- .../NexusModsCollectionDownloadJob.cs | 3 +- .../NexusModsLibrary.cs | 74 ++++++++++--------- src/NexusMods.App.UI/NexusMods.App.UI.csproj | 3 + .../CollectionCardDesignViewModel.cs | 21 ++++++ .../Collections/CollectionCardView.axaml | 42 +++++++++++ .../Collections/CollectionCardView.axaml.cs | 59 +++++++++++++++ .../Collections/ICollectionCardViewModel.cs | 30 ++++++++ src/NexusMods.App.UI/Services.cs | 4 + ...sts.CanInstallBasicCollection.verified.txt | 2 +- 21 files changed, 446 insertions(+), 107 deletions(-) create mode 100644 src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Attributes/FloatAttribute.cs create mode 100644 src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/CollectionTag.cs create mode 100644 src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/GraphQLResolver.cs create mode 100644 src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/Collection.cs create mode 100644 src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/CollectionRevision.cs create mode 100644 src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/User.cs delete mode 100644 src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/NexusModsCollectionMetadata.cs delete mode 100644 src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/NexusModsCollectionRevision.cs delete mode 100644 src/Networking/NexusMods.Networking.NexusWebApi/GraphQL/CollectionRevisionInfo.graphql create mode 100644 src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardDesignViewModel.cs create mode 100644 src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardView.axaml create mode 100644 src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardView.axaml.cs create mode 100644 src/NexusMods.App.UI/Pages/LibraryPage/Collections/ICollectionCardViewModel.cs diff --git a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Attributes/FloatAttribute.cs b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Attributes/FloatAttribute.cs new file mode 100644 index 000000000..16292ed72 --- /dev/null +++ b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Attributes/FloatAttribute.cs @@ -0,0 +1,18 @@ +using NexusMods.MnemonicDB.Abstractions; +using NexusMods.MnemonicDB.Abstractions.Attributes; +using NexusMods.MnemonicDB.Abstractions.ElementComparers; + +namespace NexusMods.Abstractions.NexusModsLibrary.Attributes; + +public class FloatAttribute(string ns, string name) : ScalarAttribute(ValueTags.Float32, ns, name) +{ + protected override float ToLowLevel(float value) + { + return value; + } + + protected override float FromLowLevel(float value, ValueTags tags, RegistryId registryId) + { + return value; + } +} diff --git a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/CollectionTag.cs b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/CollectionTag.cs new file mode 100644 index 000000000..2850650c1 --- /dev/null +++ b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/CollectionTag.cs @@ -0,0 +1,23 @@ +using NexusMods.Abstractions.MnemonicDB.Attributes; +using NexusMods.MnemonicDB.Abstractions.Attributes; +using NexusMods.MnemonicDB.Abstractions.Models; + +namespace NexusMods.Abstractions.NexusModsLibrary; + +/// +/// A tag for a collection. +/// +public partial class CollectionTag : IModelDefinition +{ + private const string Namespace = "NexusMods.Abstractions.NexusModsLibrary.CollectionTag"; + + /// + /// The name of the collection tag. + /// + public static readonly StringAttribute Name = new(Namespace, nameof(Name)) { IsIndexed = true }; + + /// + /// The Nexus mods id of the collection tag. + /// + public static readonly ULongAttribute NexusId = new(Namespace, nameof(NexusId)) { IsIndexed = true }; +} diff --git a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/GraphQLResolver.cs b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/GraphQLResolver.cs new file mode 100644 index 000000000..51064379f --- /dev/null +++ b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/GraphQLResolver.cs @@ -0,0 +1,66 @@ +using NexusMods.MnemonicDB.Abstractions; +using NexusMods.MnemonicDB.Abstractions.Attributes; +using NexusMods.MnemonicDB.Abstractions.Models; +using Splat.ModeDetection; + +namespace NexusMods.Abstractions.NexusModsLibrary; + +public struct GraphQLResolver(ITransaction Tx, ReadOnlyModel Model) +{ + public static GraphQLResolver Create(IDb referenceDb, ITransaction tx, ScalarAttribute primaryKeyAttribute, THighLevel primaryKeyValue) where THighLevel : notnull + { + var existing = referenceDb.Datoms(primaryKeyAttribute, primaryKeyValue); + var id = existing.Count == 0 ? tx.TempId() : existing[0].E; + return new GraphQLResolver(tx, new ReadOnlyModel(referenceDb, id)); + } + + /// + /// The id of the entity, may be temporary if this is a new entity. + /// + public EntityId Id => Model.Id; + + public void Add(ScalarAttribute attribute, THighLevel value) + where THighLevel : notnull + { + if (attribute.TryGet(Model, out var foundValue)) + { + // Deduplicate values + if (foundValue.Equals(value)) + return; + } + // Else add the value + Tx.Add(Model.Id, attribute, value); + } + + public void Add(ReferencesAttribute attribute, EntityId id) + where TOther : IModelDefinition + { + if (PartitionId.Temp == id.Partition) + { + Tx.Add(Model.Id, attribute, id); + return; + } + + if (attribute.Get(Model).Contains(id)) + return; + + // Else add the value + Tx.Add(Model.Id, attribute, id); + } + + public void Add(ReferenceAttribute attribute, EntityId id) + where TOther : IModelDefinition + { + if (PartitionId.Temp == id.Partition) + { + Tx.Add(Model.Id, attribute, id); + return; + } + + if (attribute.Get(Model).Equals(id)) + return; + + // Else add the value + Tx.Add(Model.Id, attribute, id); + } +} diff --git a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/Collection.cs b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/Collection.cs new file mode 100644 index 000000000..fd0c6c460 --- /dev/null +++ b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/Collection.cs @@ -0,0 +1,49 @@ +using NexusMods.Abstractions.MnemonicDB.Attributes; +using NexusMods.Abstractions.NexusModsLibrary.Attributes; +using NexusMods.MnemonicDB.Abstractions.Attributes; +using NexusMods.MnemonicDB.Abstractions.Models; + +namespace NexusMods.Abstractions.NexusModsLibrary.Models; + +/// +/// Metadata about a collection on Nexus Mods. +/// +public partial class Collection : IModelDefinition +{ + private const string Namespace = "NexusMods.Library.NexusModsCollectionMetadata"; + + /// + /// The collection slug. + /// + public static readonly CollectionsSlugAttribute Slug = new(Namespace, nameof(Slug)) { IsIndexed = true }; + + /// + /// The name of the collection. + /// + public static readonly StringAttribute Name = new(Namespace, nameof(Name)); + + /// + /// The short description of the collection + /// + public static readonly StringAttribute Summary = new(Namespace, nameof(Summary)); + + /// + /// The Curating user of the collection. + /// + public static readonly ReferenceAttribute User = new(Namespace, nameof(User)); + + /// + /// The revisions of the collection. + /// + public static readonly BackReferenceAttribute Revisions = new(CollectionRevision.Collection); + + /// + /// The tags on the collection. + /// + public static readonly ReferencesAttribute Tags = new(Namespace, nameof(Tags)); + + /// + /// The number of endorsements the collection has. + /// + public static readonly ULongAttribute Endorsements = new(Namespace, nameof(Endorsements)); +} diff --git a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/CollectionRevision.cs b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/CollectionRevision.cs new file mode 100644 index 000000000..94f94d3f6 --- /dev/null +++ b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/CollectionRevision.cs @@ -0,0 +1,49 @@ +using NexusMods.Abstractions.MnemonicDB.Attributes; +using NexusMods.Abstractions.NexusModsLibrary.Attributes; +using NexusMods.MnemonicDB.Abstractions.Attributes; +using NexusMods.MnemonicDB.Abstractions.Models; + +namespace NexusMods.Abstractions.NexusModsLibrary.Models; + +/// +/// Metadata about a collection on Nexus Mods. +/// +public partial class CollectionRevision : IModelDefinition +{ + private const string Namespace = "NexusMods.Library.NexusModsCollectionRevision"; + + /// + /// The globally unique id identifying a specific revision of a collection. + /// + public static readonly RevisionIdAttribute RevisionId = new(Namespace, nameof(RevisionId)) { IsIndexed = true }; + + /// + /// The locally unique revision number (aka "version") of a collection. Only unique within one collection. + /// + public static readonly RevisionNumberAttribute RevisionNumber = new(Namespace, nameof(RevisionNumber)); + + /// + /// The collection this revision belongs to. + /// + public static readonly ReferenceAttribute Collection = new(Namespace, nameof(Collection)); + + /// + /// The number of downloads this revision has. + /// + public static readonly ULongAttribute Downloads = new(Namespace, nameof(Downloads)); + + /// + /// Total size of the revision + /// + public static readonly SizeAttribute TotalSize = new(Namespace, nameof(TotalSize)); + + /// + /// The overall rating of this revision (often displayed as a percentage). + /// + public static readonly FloatAttribute OverallRating = new(Namespace, nameof(OverallRating)); + + /// + /// The total number of ratings this revision has. + /// + public static readonly ULongAttribute TotalRatings = new(Namespace, nameof(TotalRatings)); +} diff --git a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/User.cs b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/User.cs new file mode 100644 index 000000000..710c356cb --- /dev/null +++ b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/User.cs @@ -0,0 +1,28 @@ +using NexusMods.Abstractions.MnemonicDB.Attributes; +using NexusMods.MnemonicDB.Abstractions.Attributes; +using NexusMods.MnemonicDB.Abstractions.Models; + +namespace NexusMods.Abstractions.NexusModsLibrary.Models; + +/// +/// A user on Nexus Mods. +/// +public partial class User : IModelDefinition +{ + private const string Namespace = "NexusMods.Abstractions.NexusModsLibrary.User"; + + /// + /// The user's username. + /// + public static readonly StringAttribute Name = new(Namespace, nameof(Name)) { IsIndexed = true }; + + /// + /// The nexus id of the user. + /// + public static readonly ULongAttribute NexusId = new(Namespace, nameof(NexusId)) { IsIndexed = true }; + + /// + /// The user's avatar URL. + /// + public static readonly UriAttribute Avatar = new(Namespace, nameof(Avatar)); +} diff --git a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/NexusModsCollectionLibraryFile.cs b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/NexusModsCollectionLibraryFile.cs index a3036b31a..44e9411e0 100644 --- a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/NexusModsCollectionLibraryFile.cs +++ b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/NexusModsCollectionLibraryFile.cs @@ -17,5 +17,5 @@ public partial class NexusModsCollectionLibraryFile : IModelDefinition /// /// The collection revision this file belongs to. /// - public static readonly ReferenceAttribute CollectionRevision = new(Namespace, nameof(CollectionRevision)); + public static readonly ReferenceAttribute CollectionRevision = new(Namespace, nameof(CollectionRevision)); } diff --git a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/NexusModsCollectionMetadata.cs b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/NexusModsCollectionMetadata.cs deleted file mode 100644 index 7a49ef24c..000000000 --- a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/NexusModsCollectionMetadata.cs +++ /dev/null @@ -1,28 +0,0 @@ -using NexusMods.Abstractions.NexusModsLibrary.Attributes; -using NexusMods.MnemonicDB.Abstractions.Attributes; -using NexusMods.MnemonicDB.Abstractions.Models; - -namespace NexusMods.Abstractions.NexusModsLibrary; - -/// -/// Metadata about a collection on Nexus Mods. -/// -public partial class NexusModsCollectionMetadata : IModelDefinition -{ - private const string Namespace = "NexusMods.Library.NexusModsCollectionMetadata"; - - /// - /// The collection slug. - /// - public static readonly CollectionsSlugAttribute Slug = new(Namespace, nameof(Slug)) { IsIndexed = true }; - - /// - /// The name of the collection. - /// - public static readonly StringAttribute Name = new(Namespace, nameof(Name)); - - /// - /// The revisions of the collection. - /// - public static readonly BackReferenceAttribute Revisions = new(NexusModsCollectionRevision.Collection); -} diff --git a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/NexusModsCollectionRevision.cs b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/NexusModsCollectionRevision.cs deleted file mode 100644 index 1f7e53861..000000000 --- a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/NexusModsCollectionRevision.cs +++ /dev/null @@ -1,28 +0,0 @@ -using NexusMods.Abstractions.NexusModsLibrary.Attributes; -using NexusMods.MnemonicDB.Abstractions.Attributes; -using NexusMods.MnemonicDB.Abstractions.Models; - -namespace NexusMods.Abstractions.NexusModsLibrary; - -/// -/// Metadata about a collection on Nexus Mods. -/// -public partial class NexusModsCollectionRevision : IModelDefinition -{ - private const string Namespace = "NexusMods.Library.NexusModsCollectionRevision"; - - /// - /// The globally unique id identifying a specific revision of a collection. - /// - public static readonly RevisionIdAttribute RevisionId = new(Namespace, nameof(RevisionId)) { IsIndexed = true }; - - /// - /// The locally unique revision number (aka "version") of a collection. Only unique within one collection. - /// - public static readonly RevisionNumberAttribute RevisionNumber = new(Namespace, nameof(RevisionNumber)); - - /// - /// The collection this revision belongs to. - /// - public static readonly ReferenceAttribute Collection = new(Namespace, nameof(Collection)); -} diff --git a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Services.cs b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Services.cs index 3ea09e002..86a8253ba 100644 --- a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Services.cs +++ b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Services.cs @@ -1,5 +1,6 @@ using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; +using NexusMods.Abstractions.NexusModsLibrary.Models; namespace NexusMods.Abstractions.NexusModsLibrary; @@ -18,8 +19,9 @@ public static IServiceCollection AddNexusModsLibraryModels(this IServiceCollecti .AddNexusModsFileMetadataModel() .AddNexusModsModPageMetadataModel() .AddNexusModsLibraryFileModel() - .AddNexusModsCollectionMetadataModel() - .AddNexusModsCollectionRevisionModel() + .AddCollectionModel() + .AddCollectionRevisionModel() + .AddUserModel() .AddNexusModsCollectionLibraryFileModel(); } } diff --git a/src/Networking/NexusMods.Networking.NexusWebApi/GraphQL/CollectionInfo.graphql b/src/Networking/NexusMods.Networking.NexusWebApi/GraphQL/CollectionInfo.graphql index b3a305649..9658f8e8b 100644 --- a/src/Networking/NexusMods.Networking.NexusWebApi/GraphQL/CollectionInfo.graphql +++ b/src/Networking/NexusMods.Networking.NexusWebApi/GraphQL/CollectionInfo.graphql @@ -6,16 +6,22 @@ query CollectionInfo($slug: String!, $viewAdultContent: Boolean!) { name summary + endorsements revisions { id + totalDownloads assetsSizeBytes revisionNumber adultContent totalSize + overallRating + overallRatingCount } user { name + avatar + memberId } } } diff --git a/src/Networking/NexusMods.Networking.NexusWebApi/GraphQL/CollectionRevisionInfo.graphql b/src/Networking/NexusMods.Networking.NexusWebApi/GraphQL/CollectionRevisionInfo.graphql deleted file mode 100644 index 69986ea17..000000000 --- a/src/Networking/NexusMods.Networking.NexusWebApi/GraphQL/CollectionRevisionInfo.graphql +++ /dev/null @@ -1,12 +0,0 @@ -# Gets information about a collection revision. -query CollectionRevisionInfo($slug: String!, $revision: Int!, $viewAdultContent: Boolean!) -{ - collectionRevision(slug: $slug, revision: $revision, viewAdultContent: $viewAdultContent) - { - id - assetsSizeBytes - revisionNumber - adultContent - totalSize - } -} diff --git a/src/Networking/NexusMods.Networking.NexusWebApi/NexusModsCollectionDownloadJob.cs b/src/Networking/NexusMods.Networking.NexusWebApi/NexusModsCollectionDownloadJob.cs index 16b6422f6..58372bb02 100644 --- a/src/Networking/NexusMods.Networking.NexusWebApi/NexusModsCollectionDownloadJob.cs +++ b/src/Networking/NexusMods.Networking.NexusWebApi/NexusModsCollectionDownloadJob.cs @@ -3,6 +3,7 @@ using NexusMods.Abstractions.Jobs; using NexusMods.Abstractions.Library.Models; using NexusMods.Abstractions.NexusModsLibrary; +using NexusMods.Abstractions.NexusModsLibrary.Models; using NexusMods.Abstractions.NexusWebApi; using NexusMods.Abstractions.NexusWebApi.Types; using NexusMods.MnemonicDB.Abstractions; @@ -24,7 +25,7 @@ public class NexusModsCollectionDownloadJob : IJobDefinitionWithStart /// The metadata of the collection revision. /// - public NexusModsCollectionRevision.ReadOnly? Metadata { get; set; } + public CollectionRevision.ReadOnly? Metadata { get; set; } /// /// The collection slug diff --git a/src/Networking/NexusMods.Networking.NexusWebApi/NexusModsLibrary.cs b/src/Networking/NexusMods.Networking.NexusWebApi/NexusModsLibrary.cs index 82684245c..358243f05 100644 --- a/src/Networking/NexusMods.Networking.NexusWebApi/NexusModsLibrary.cs +++ b/src/Networking/NexusMods.Networking.NexusWebApi/NexusModsLibrary.cs @@ -3,7 +3,9 @@ using Microsoft.Extensions.DependencyInjection; using NexusMods.Abstractions.Games.DTO; using NexusMods.Abstractions.Jobs; +using NexusMods.Abstractions.MnemonicDB.Attributes; using NexusMods.Abstractions.NexusModsLibrary; +using NexusMods.Abstractions.NexusModsLibrary.Models; using NexusMods.Abstractions.NexusWebApi; using NexusMods.Abstractions.NexusWebApi.DTOs; using NexusMods.Abstractions.NexusWebApi.Types; @@ -11,6 +13,7 @@ using NexusMods.MnemonicDB.Abstractions; using NexusMods.Networking.HttpDownloader; using NexusMods.Paths; +using User = NexusMods.Abstractions.NexusModsLibrary.Models.User; namespace NexusMods.Networking.NexusWebApi; @@ -70,58 +73,61 @@ public NexusModsLibrary(IServiceProvider serviceProvider) /// /// Get or add a collection metadata /// - public async Task GetOrAddCollectionMetadata(CollectionSlug slug, CancellationToken token) + public async Task GetOrAddCollectionMetadata(CollectionSlug slug, bool referesh = false, CancellationToken token = default) { - var collections = NexusModsCollectionMetadata.FindBySlug(_connection.Db, slug); - if (collections.TryGetFirst(x => x.Slug == slug, out var collection)) - return collection; + if (!referesh) + { + var collections = Collection.FindBySlug(_connection.Db, slug); + if (collections.TryGetFirst(x => x.Slug == slug, out var collection)) + return collection; + } var info = await _gqlClient.CollectionInfo.ExecuteAsync(slug.Value, true, token); + + var collectionInfo = info.Data!.Collection; using var tx = _connection.BeginTransaction(); - var newCollection = new NexusModsCollectionMetadata.New(tx) - { - Slug = slug, - Name = info.Data!.Collection.Name, - }; - - foreach (var revision in info.Data!.Collection.Revisions) + var db = _connection.Db; + var collectionResolver = GraphQLResolver.Create(db, tx, Collection.Slug, slug); + collectionResolver.Add(Collection.Name, collectionInfo.Name); + collectionResolver.Add(Collection.Summary, collectionInfo.Summary); + collectionResolver.Add(Collection.Endorsements, (ulong)collectionInfo.Endorsements); + + // Remap the user info + var userResolver = GraphQLResolver.Create(db, tx, User.NexusId, (ulong)collectionInfo.User.MemberId); + userResolver.Add(User.Name, collectionInfo.User.Name); + userResolver.Add(User.Avatar, new Uri(collectionInfo.User.Avatar)); + + collectionResolver.Add(Collection.User, userResolver.Id); + + foreach (var revision in collectionInfo.Revisions) { - _ = new NexusModsCollectionRevision.New(tx) - { - CollectionId = newCollection, - RevisionId = RevisionId.From((ulong)revision.Id), - RevisionNumber = RevisionNumber.From((ulong)revision.RevisionNumber), - }; + var revisionResolver = GraphQLResolver.Create(db, tx, CollectionRevision.RevisionId, RevisionId.From((ulong)revision.Id)); + revisionResolver.Add(CollectionRevision.RevisionId, RevisionId.From((ulong)revision.Id)); + revisionResolver.Add(CollectionRevision.RevisionNumber, RevisionNumber.From((ulong)revision.RevisionNumber)); + revisionResolver.Add(CollectionRevision.CollectionId, collectionResolver.Id); + revisionResolver.Add(CollectionRevision.Downloads, (ulong)revision.TotalDownloads); + revisionResolver.Add(CollectionRevision.TotalSize, Size.From(ulong.Parse(revision.TotalSize))); + revisionResolver.Add(CollectionRevision.OverallRating, float.Parse(revision.OverallRating ?? "0.0")); + revisionResolver.Add(CollectionRevision.TotalRatings, (ulong)(revision.OverallRatingCount ?? 0)); } var txResults = await tx.Commit(); - return txResults.Remap(newCollection); + return Collection.Load(txResults.Db, txResults[collectionResolver.Id]); } /// /// Get or add a collection metadata /// - public async Task GetOrAddCollectionRevision(CollectionSlug slug, RevisionNumber revisionNumber, CancellationToken token) + public async Task GetOrAddCollectionRevision(CollectionSlug slug, RevisionNumber revisionNumber, CancellationToken token) { - var collections = await GetOrAddCollectionMetadata(slug, token); - if (collections.Revisions.TryGetFirst(r => r.RevisionNumber == revisionNumber, out var revision)) + var collection = await GetOrAddCollectionMetadata(slug, false, token); + if (collection.Revisions.TryGetFirst(r => r.RevisionNumber == revisionNumber, out var revision)) return revision; - var revisionInfo = await _gqlClient.CollectionRevisionInfo.ExecuteAsync(slug.Value, (int)revisionNumber.Value, true, token); - - using var tx = _connection.BeginTransaction(); - var newRevision = new NexusModsCollectionRevision.New(tx) - { - CollectionId = collections, - RevisionNumber = revisionNumber, - RevisionId = RevisionId.From((ulong)revisionInfo.Data!.CollectionRevision.Id), - }; - - var txResults = await tx.Commit(); - - return txResults.Remap(newRevision); + collection = await GetOrAddCollectionMetadata(slug, true, token); + return collection.Revisions.First(r => r.RevisionNumber == revisionNumber); } public async Task GetOrAddFile( diff --git a/src/NexusMods.App.UI/NexusMods.App.UI.csproj b/src/NexusMods.App.UI/NexusMods.App.UI.csproj index f7ec2ae75..7a113d51b 100644 --- a/src/NexusMods.App.UI/NexusMods.App.UI.csproj +++ b/src/NexusMods.App.UI/NexusMods.App.UI.csproj @@ -635,6 +635,9 @@ MessageBoxOkView.axaml Code + + ICollectionCardViewModel.cs + diff --git a/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardDesignViewModel.cs b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardDesignViewModel.cs new file mode 100644 index 000000000..00f2d89af --- /dev/null +++ b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardDesignViewModel.cs @@ -0,0 +1,21 @@ +using Avalonia.Media.Imaging; +using Avalonia.Platform; +using NexusMods.Abstractions.Jobs; +using NexusMods.Paths; + +namespace NexusMods.App.UI.Pages.LibraryPage.Collections; + +public class CollectionCardDesignViewModel : AViewModel, ICollectionCardViewModel +{ + public string Name => "Vanilla+ [Quality of Life]"; + public Bitmap Image => new Bitmap(AssetLoader.Open(new Uri("avares://NexusMods.App.UI/Assets/DesignTime/cyberpunk_game.png"))); + public string Summary => "1.6.8 This visual mod collection is designed to create a witchy medieval cottage aethetic experience for Stardew Valley, and Stardew Valley Expanded."; + public string Category => "Themed"; + public int ModCount => 9; + public ulong EndorsementCount => 248; + public ulong DownloadCount => 30000; + public Size TotalSize => Size.From(907 * 1024 * 1024); + public Percent OverallRating => Percent.CreateClamped(0.84); + public string AuthorName => "FantasyAuthor"; + public Bitmap AuthorAvatar => new("https://avatars.nexusmods.com/17252164/100"); +} diff --git a/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardView.axaml b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardView.axaml new file mode 100644 index 000000000..a7df10eba --- /dev/null +++ b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardView.axaml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardView.axaml.cs b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardView.axaml.cs new file mode 100644 index 000000000..dc2756de8 --- /dev/null +++ b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardView.axaml.cs @@ -0,0 +1,59 @@ +using System.Reactive.Disposables; +using System.Reactive.Linq; +using Avalonia; +using Avalonia.Controls; +using Avalonia.Markup.Xaml; +using Avalonia.ReactiveUI; +using ReactiveUI; + +namespace NexusMods.App.UI.Pages.LibraryPage.Collections; + +public partial class CollectionCardView : ReactiveUserControl +{ + public CollectionCardView() + { + InitializeComponent(); + + this.WhenActivated(d => + { + + this.WhenAnyValue(view => view.ViewModel!.Name) + .BindTo(this, view => view.TitleText.Text) + .DisposeWith(d); + + + this.WhenAnyValue(view => view.ViewModel!.Image) + .BindTo(this, view => view.TileImage.Source) + .DisposeWith(d); + + this.WhenAnyValue(view => view.ViewModel!.Category) + .BindTo(this, view => view.CategoryText.Text) + .DisposeWith(d); + + this.WhenAnyValue(view => view.ViewModel!.Summary) + .BindTo(this, view => view.SummaryText.Text) + .DisposeWith(d); + this.WhenAnyValue(view => view.ViewModel!.ModCount) + .BindTo(this, view => view.ModCount.Text) + .DisposeWith(d); + + this.WhenAnyValue(view => view.ViewModel!.EndorsementCount) + .BindTo(this, view => view.Endorsements.Text) + .DisposeWith(d); + + this.WhenAnyValue(view => view.ViewModel!.DownloadCount) + .BindTo(this, view => view.Downloads.Text) + .DisposeWith(d); + + this.WhenAnyValue(view => view.ViewModel!.TotalSize) + .BindTo(this, view => view.TotalSize.Text) + .DisposeWith(d); + + this.WhenAnyValue(view => view.ViewModel!.OverallRating) + .BindTo(this, view => view.OverallRating.Text) + .DisposeWith(d); + } + ); + } +} + diff --git a/src/NexusMods.App.UI/Pages/LibraryPage/Collections/ICollectionCardViewModel.cs b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/ICollectionCardViewModel.cs new file mode 100644 index 000000000..b0ac16e15 --- /dev/null +++ b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/ICollectionCardViewModel.cs @@ -0,0 +1,30 @@ +using Avalonia.Media.Imaging; +using NexusMods.Abstractions.Jobs; +using NexusMods.Paths; + +namespace NexusMods.App.UI.Pages.LibraryPage.Collections; + +public interface ICollectionCardViewModel : IViewModelInterface +{ + public string Name { get; } + + public Bitmap Image { get; } + + public string Summary { get; } + + public string Category { get; } + + public int ModCount { get; } + + public ulong EndorsementCount { get; } + + public ulong DownloadCount { get; } + + public Size TotalSize { get; } + + public Percent OverallRating { get; } + + public string AuthorName { get; } + + public Bitmap AuthorAvatar { get; } +} diff --git a/src/NexusMods.App.UI/Services.cs b/src/NexusMods.App.UI/Services.cs index db0dc0a72..7b3c7c298 100644 --- a/src/NexusMods.App.UI/Services.cs +++ b/src/NexusMods.App.UI/Services.cs @@ -46,6 +46,7 @@ using NexusMods.App.UI.Pages.Downloads; using NexusMods.App.UI.Pages.ItemContentsFileTree; using NexusMods.App.UI.Pages.LibraryPage; +using NexusMods.App.UI.Pages.LibraryPage.Collections; using NexusMods.App.UI.Pages.LoadoutPage; using NexusMods.App.UI.Pages.MyGames; using NexusMods.App.UI.Pages.MyLoadouts; @@ -96,6 +97,8 @@ public static IServiceCollection AddUI(this IServiceCollection c) .AddTransient(typeof(DataGridViewModelColumn<,>)) .AddTransient(typeof(DataGridColumnFactory<,,>)) .AddSingleton() + + .AddViewModel() .AddViewModel() .AddViewModel() @@ -127,6 +130,7 @@ public static IServiceCollection AddUI(this IServiceCollection c) .AddViewModel() // Views + .AddView() .AddView() .AddView() .AddView() diff --git a/tests/NexusMods.Collections.Tests/CollectionInstallTests.CanInstallBasicCollection.verified.txt b/tests/NexusMods.Collections.Tests/CollectionInstallTests.CanInstallBasicCollection.verified.txt index cf205c099..768e347f3 100644 --- a/tests/NexusMods.Collections.Tests/CollectionInstallTests.CanInstallBasicCollection.verified.txt +++ b/tests/NexusMods.Collections.Tests/CollectionInstallTests.CanInstallBasicCollection.verified.txt @@ -2,7 +2,7 @@ mods: [ Game Files, Halgari's Helper, - My Collection + My Mods ], files: [ {Game}/archive/pc/mod/_1_Ves_HanakoFixedBodyNaked.archive, From ba8f33088527c5b86298c0e96b34a7696d94eea1 Mon Sep 17 00:00:00 2001 From: halgari Date: Tue, 17 Sep 2024 14:41:25 -0600 Subject: [PATCH 02/11] Bit of implementing the actual VM --- .../Collections/CollectionCardViewModel.cs | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardViewModel.cs diff --git a/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardViewModel.cs b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardViewModel.cs new file mode 100644 index 000000000..f28291fde --- /dev/null +++ b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardViewModel.cs @@ -0,0 +1,33 @@ +using Avalonia.Media.Imaging; +using NexusMods.Abstractions.Jobs; +using NexusMods.Abstractions.NexusModsLibrary.Models; +using NexusMods.Abstractions.NexusWebApi.Types; +using NexusMods.MnemonicDB.Abstractions; +using NexusMods.Paths; + +namespace NexusMods.App.UI.Pages.LibraryPage.Collections; + +public class CollectionCardViewModel : AViewModel, ICollectionCardViewModel +{ + private readonly CollectionRevision.ReadOnly _revision; + private readonly Collection.ReadOnly _collection; + + public CollectionCardViewModel(IConnection connection, RevisionId revision) + { + _revision = CollectionRevision.FindByRevisionId(connection.Db, revision) + .First(); + _collection = _revision.Collection; + } + + public string Name => _collection.Name; + public Bitmap Image => throw new NotImplementedException(); + public string Summary => _collection.Summary; + public string Category => "TODO"; + public int ModCount => -1; + public ulong EndorsementCount => _collection.Endorsements; + public ulong DownloadCount => _revision.Downloads; + public Size TotalSize => _revision.TotalSize; + public Percent OverallRating => Percent.CreateClamped(_revision.OverallRating); + public string AuthorName => _collection.User.Name; + public Bitmap AuthorAvatar => throw new NotImplementedException(); +} From f7acea69dd3217f869755b63d97c3ec990a41e8e Mon Sep 17 00:00:00 2001 From: halgari Date: Wed, 18 Sep 2024 12:05:20 -0600 Subject: [PATCH 03/11] Start on the visual layout for the collection cards --- .../Assets/DesignTime/avatar.webp | Bin 0 -> 16810 bytes .../DesignTime/collection_tile_image.png | Bin 0 -> 143743 bytes .../CollectionCardDesignViewModel.cs | 4 +- .../Collections/CollectionCardView.axaml | 70 ++++++--- .../Collections/CollectionCardView.axaml.cs | 8 ++ .../CollectionCards/CollectionCards.axaml | 133 ++++++++++++++++++ 6 files changed, 194 insertions(+), 21 deletions(-) create mode 100644 src/NexusMods.App.UI/Assets/DesignTime/avatar.webp create mode 100644 src/NexusMods.App.UI/Assets/DesignTime/collection_tile_image.png create mode 100644 src/Themes/NexusMods.Themes.NexusFluentDark/Styles/UserControls/CollectionCards/CollectionCards.axaml diff --git a/src/NexusMods.App.UI/Assets/DesignTime/avatar.webp b/src/NexusMods.App.UI/Assets/DesignTime/avatar.webp new file mode 100644 index 0000000000000000000000000000000000000000..2f1cdb5e89902f92c22782efcc58c2dc881adef1 GIT binary patch literal 16810 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 KXtu-vS+*=wqJMM% literal 0 HcmV?d00001 diff --git a/src/NexusMods.App.UI/Assets/DesignTime/collection_tile_image.png b/src/NexusMods.App.UI/Assets/DesignTime/collection_tile_image.png new file mode 100644 index 0000000000000000000000000000000000000000..d45574f392712c93b0c2daed47eaa26f619ca8bb GIT binary patch literal 143743 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⩔0pB;bMXo!hoT|mM_3>fPZ^!T5(x0XIQI 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 N002ovPDHLkV1g*o0eS!c literal 0 HcmV?d00001 diff --git a/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardDesignViewModel.cs b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardDesignViewModel.cs index 00f2d89af..6b2c68b94 100644 --- a/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardDesignViewModel.cs +++ b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardDesignViewModel.cs @@ -8,7 +8,7 @@ namespace NexusMods.App.UI.Pages.LibraryPage.Collections; public class CollectionCardDesignViewModel : AViewModel, ICollectionCardViewModel { public string Name => "Vanilla+ [Quality of Life]"; - public Bitmap Image => new Bitmap(AssetLoader.Open(new Uri("avares://NexusMods.App.UI/Assets/DesignTime/cyberpunk_game.png"))); + public Bitmap Image => new(AssetLoader.Open(new Uri("avares://NexusMods.App.UI/Assets/DesignTime/collection_tile_image.png"))); public string Summary => "1.6.8 This visual mod collection is designed to create a witchy medieval cottage aethetic experience for Stardew Valley, and Stardew Valley Expanded."; public string Category => "Themed"; public int ModCount => 9; @@ -17,5 +17,5 @@ public class CollectionCardDesignViewModel : AViewModel Size.From(907 * 1024 * 1024); public Percent OverallRating => Percent.CreateClamped(0.84); public string AuthorName => "FantasyAuthor"; - public Bitmap AuthorAvatar => new("https://avatars.nexusmods.com/17252164/100"); + public Bitmap AuthorAvatar => new(AssetLoader.Open(new Uri("avares://NexusMods.App.UI/Assets/DesignTime/avatar.webp"))); } diff --git a/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardView.axaml b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardView.axaml index a7df10eba..0d471670d 100644 --- a/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardView.axaml +++ b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardView.axaml @@ -7,34 +7,66 @@ xmlns:reactiveUi="http://reactiveui.net" xmlns:collections="clr-namespace:NexusMods.App.UI.Pages.LibraryPage.Collections" xmlns:panels="clr-namespace:Avalonia.Labs.Panels;assembly=Avalonia.Labs.Panels" + xmlns:icons="clr-namespace:NexusMods.Icons;assembly=NexusMods.Icons" mc:Ignorable="d" d:DesignWidth="508" d:DesignHeight="288" x:Class="NexusMods.App.UI.Pages.LibraryPage.Collections.CollectionCardView"> - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardView.axaml.cs b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardView.axaml.cs index dc2756de8..5c1695591 100644 --- a/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardView.axaml.cs +++ b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardView.axaml.cs @@ -52,6 +52,14 @@ public CollectionCardView() this.WhenAnyValue(view => view.ViewModel!.OverallRating) .BindTo(this, view => view.OverallRating.Text) .DisposeWith(d); + + this.WhenAnyValue(view => view.ViewModel!.AuthorName) + .BindTo(this, view => view.AuthorName.Text) + .DisposeWith(d); + + this.WhenAnyValue(view => view.ViewModel!.AuthorAvatar) + .BindTo(this, view => view.AuthorAvatarImage.Source) + .DisposeWith(d); } ); } diff --git a/src/Themes/NexusMods.Themes.NexusFluentDark/Styles/UserControls/CollectionCards/CollectionCards.axaml b/src/Themes/NexusMods.Themes.NexusFluentDark/Styles/UserControls/CollectionCards/CollectionCards.axaml new file mode 100644 index 000000000..e4b556530 --- /dev/null +++ b/src/Themes/NexusMods.Themes.NexusFluentDark/Styles/UserControls/CollectionCards/CollectionCards.axaml @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 95caddf287915460a766ae9b17aa2cb10a26b142 Mon Sep 17 00:00:00 2001 From: halgari Date: Wed, 18 Sep 2024 12:09:20 -0600 Subject: [PATCH 04/11] Add the styles to the style index --- .../Styles/StylesIndex.axaml | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/Themes/NexusMods.Themes.NexusFluentDark/Styles/StylesIndex.axaml b/src/Themes/NexusMods.Themes.NexusFluentDark/Styles/StylesIndex.axaml index 40bf62305..cde1cbe84 100644 --- a/src/Themes/NexusMods.Themes.NexusFluentDark/Styles/StylesIndex.axaml +++ b/src/Themes/NexusMods.Themes.NexusFluentDark/Styles/StylesIndex.axaml @@ -30,24 +30,25 @@ - - + + + + - - - - - - - - - + + + + + + + + From 525cf73aa101032436e4e9e8df8774937c2f349a Mon Sep 17 00:00:00 2001 From: halgari Date: Wed, 18 Sep 2024 14:40:07 -0600 Subject: [PATCH 05/11] Add a collections panel and it integrates with the rest of the app to show known collections --- .../GraphQLResolver.cs | 3 + src/NexusMods.App.UI/NexusMods.App.UI.csproj | 6 ++ .../Collections/CollectionsDesignViewModel.cs | 33 +++++++++++ .../Collections/CollectionsPage.cs | 57 +++++++++++++++++++ .../Collections/CollectionsView.axaml | 29 ++++++++++ .../Collections/CollectionsView.axaml.cs | 20 +++++++ .../Collections/CollectionsViewModel.cs | 56 ++++++++++++++++++ .../Collections/ICollectionsViewModel.cs | 9 +++ src/NexusMods.App.UI/Services.cs | 2 + 9 files changed, 215 insertions(+) create mode 100644 src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionsDesignViewModel.cs create mode 100644 src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionsPage.cs create mode 100644 src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionsView.axaml create mode 100644 src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionsView.axaml.cs create mode 100644 src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionsViewModel.cs create mode 100644 src/NexusMods.App.UI/Pages/LibraryPage/Collections/ICollectionsViewModel.cs diff --git a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/GraphQLResolver.cs b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/GraphQLResolver.cs index 51064379f..3979688de 100644 --- a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/GraphQLResolver.cs +++ b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/GraphQLResolver.cs @@ -10,7 +10,10 @@ public struct GraphQLResolver(ITransaction Tx, ReadOnlyModel Model) public static GraphQLResolver Create(IDb referenceDb, ITransaction tx, ScalarAttribute primaryKeyAttribute, THighLevel primaryKeyValue) where THighLevel : notnull { var existing = referenceDb.Datoms(primaryKeyAttribute, primaryKeyValue); + var exists = existing.Count > 0; var id = existing.Count == 0 ? tx.TempId() : existing[0].E; + if (!exists) + tx.Add(id, primaryKeyAttribute, primaryKeyValue); return new GraphQLResolver(tx, new ReadOnlyModel(referenceDb, id)); } diff --git a/src/NexusMods.App.UI/NexusMods.App.UI.csproj b/src/NexusMods.App.UI/NexusMods.App.UI.csproj index 7a113d51b..08b645203 100644 --- a/src/NexusMods.App.UI/NexusMods.App.UI.csproj +++ b/src/NexusMods.App.UI/NexusMods.App.UI.csproj @@ -638,6 +638,12 @@ ICollectionCardViewModel.cs + + ITwoPanelPageViewModel.cs + + + ICollectionsViewModel.cs + diff --git a/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionsDesignViewModel.cs b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionsDesignViewModel.cs new file mode 100644 index 000000000..430da52bc --- /dev/null +++ b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionsDesignViewModel.cs @@ -0,0 +1,33 @@ +using System.Collections.ObjectModel; +using NexusMods.App.UI.Windows; +using NexusMods.App.UI.WorkspaceSystem; +using NexusMods.Icons; + +namespace NexusMods.App.UI.Pages.LibraryPage.Collections; + +public class CollectionsDesignViewModel : AViewModel, ICollectionsViewModel +{ + public CollectionsDesignViewModel() + { + Collections = new ReadOnlyObservableCollection([ + new CollectionCardDesignViewModel(), + new CollectionCardDesignViewModel(), + new CollectionCardDesignViewModel(), + new CollectionCardDesignViewModel(), + new CollectionCardDesignViewModel(), + ] + ); + } + public IconValue TabIcon => IconValues.ModLibrary; + public string TabTitle => "Collections (WIP)"; + public WindowId WindowId { get; set; } + public WorkspaceId WorkspaceId { get; set; } + public PanelId PanelId { get; set; } + public PanelTabId TabId { get; set; } + public bool CanClose() + { + return false; + } + + public ReadOnlyObservableCollection Collections { get; } +} diff --git a/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionsPage.cs b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionsPage.cs new file mode 100644 index 000000000..e54c8c76c --- /dev/null +++ b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionsPage.cs @@ -0,0 +1,57 @@ +using JetBrains.Annotations; +using Microsoft.Extensions.DependencyInjection; +using NexusMods.Abstractions.Loadouts; +using NexusMods.Abstractions.Serialization.Attributes; +using NexusMods.Abstractions.Settings; +using NexusMods.App.UI.Resources; +using NexusMods.App.UI.WorkspaceSystem; +using NexusMods.Icons; +using NexusMods.MnemonicDB.Abstractions; + +namespace NexusMods.App.UI.Pages.LibraryPage.Collections; + +[JsonName("NexusMods.App.UI.Pages.Library.Collections.CollectionsPageContext")] +public record CollectionsPageContext : IPageFactoryContext +{ + public required LoadoutId LoadoutId { get; init; } +} + +[UsedImplicitly] +public class CollectionsPageFactory : APageFactory +{ + private readonly ISettingsManager _settingsManager; + public CollectionsPageFactory(IServiceProvider serviceProvider) : base(serviceProvider) + { + _settingsManager = serviceProvider.GetRequiredService(); + } + + + public static readonly PageFactoryId StaticId = PageFactoryId.From(Guid.Parse("06854703-E839-4CE6-9B3F-C6299FC446D6")); + public override PageFactoryId Id => StaticId; + + public override ICollectionsViewModel CreateViewModel(CollectionsPageContext context) + { + var vm = new CollectionsViewModel(ServiceProvider.GetRequiredService()); + return vm; + } + + public override IEnumerable GetDiscoveryDetails(IWorkspaceContext workspaceContext) + { + if (workspaceContext is not LoadoutContext loadoutContext) yield break; + + yield return new PageDiscoveryDetails + { + SectionName = "Mods", + ItemName = "Collections (WIP)", + Icon = IconValues.ModLibrary, + PageData = new PageData + { + FactoryId = Id, + Context = new CollectionsPageContext + { + LoadoutId = loadoutContext.LoadoutId, + }, + }, + }; + } +} diff --git a/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionsView.axaml b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionsView.axaml new file mode 100644 index 000000000..25efe6512 --- /dev/null +++ b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionsView.axaml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionsView.axaml.cs b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionsView.axaml.cs new file mode 100644 index 000000000..b5c06b91d --- /dev/null +++ b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionsView.axaml.cs @@ -0,0 +1,20 @@ +using System.Reactive.Disposables; +using Avalonia.ReactiveUI; +using ReactiveUI; + +namespace NexusMods.App.UI.Pages.LibraryPage.Collections; + +public partial class CollectionsView : ReactiveUserControl +{ + public CollectionsView() + { + InitializeComponent(); + + this.WhenActivated(d => + { + this.OneWayBind(ViewModel, vm => vm.Collections, view => view.Collections.ItemsSource) + .DisposeWith(d); + }); + } +} + diff --git a/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionsViewModel.cs b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionsViewModel.cs new file mode 100644 index 000000000..e8b981fb4 --- /dev/null +++ b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionsViewModel.cs @@ -0,0 +1,56 @@ +using System.Collections.ObjectModel; +using DynamicData; +using NexusMods.Abstractions.NexusModsLibrary.Attributes; +using NexusMods.Abstractions.NexusModsLibrary.Models; +using NexusMods.App.UI.Windows; +using NexusMods.App.UI.WorkspaceSystem; +using NexusMods.Icons; +using NexusMods.MnemonicDB.Abstractions; +using NexusMods.MnemonicDB.Abstractions.Query; +using ReactiveUI; +using System.Reactive.Disposables; +using System.Reactive.Linq; +using AvaloniaEdit.Utils; +using NexusMods.Abstractions.NexusWebApi.Types; +using ReactiveUI.Fody.Helpers; + +namespace NexusMods.App.UI.Pages.LibraryPage.Collections; + +public class CollectionsViewModel : AViewModel, ICollectionsViewModel +{ + private readonly IConnection _conn; + + public CollectionsViewModel(IConnection conn) + { + _conn = conn; + + this.WhenActivated(d => + { + Collection.ObserveAll(conn) + .Transform(coll => (ICollectionCardViewModel)new CollectionCardViewModel(conn, coll.Revisions.First().RevisionId)) + .Bind(out _collections) + .Subscribe() + .DisposeWith(d); + } + ); + } + + private CollectionRevision.ReadOnly SelectLatest(IGroup group) + { + return group.Cache.Items.MaxBy(r => r.RevisionNumber); + } + + public IconValue TabIcon { get; } = IconValues.ModLibrary; + public string TabTitle { get; } = "Collections (WIP)"; + public WindowId WindowId { get; set; } + public WorkspaceId WorkspaceId { get; set; } + public PanelId PanelId { get; set; } + public PanelTabId TabId { get; set; } + public bool CanClose() + { + return true; + } + + private ReadOnlyObservableCollection _collections = new(new ObservableCollection()); + public ReadOnlyObservableCollection Collections => _collections; +} diff --git a/src/NexusMods.App.UI/Pages/LibraryPage/Collections/ICollectionsViewModel.cs b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/ICollectionsViewModel.cs new file mode 100644 index 000000000..f00eb6be5 --- /dev/null +++ b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/ICollectionsViewModel.cs @@ -0,0 +1,9 @@ +using System.Collections.ObjectModel; +using NexusMods.App.UI.WorkspaceSystem; + +namespace NexusMods.App.UI.Pages.LibraryPage.Collections; + +public interface ICollectionsViewModel : IPageViewModelInterface +{ + public ReadOnlyObservableCollection Collections { get; } +} diff --git a/src/NexusMods.App.UI/Services.cs b/src/NexusMods.App.UI/Services.cs index 7b3c7c298..f39139163 100644 --- a/src/NexusMods.App.UI/Services.cs +++ b/src/NexusMods.App.UI/Services.cs @@ -206,6 +206,7 @@ public static IServiceCollection AddUI(this IServiceCollection c) .AddViewModel() .AddView() + .AddView() .AddView() // workspace system @@ -240,6 +241,7 @@ public static IServiceCollection AddUI(this IServiceCollection c) .AddSingleton() .AddSingleton() .AddSingleton() + .AddSingleton() // LeftMenu factories .AddSingleton() From 94e054fc8d831a57917f1000bd598ae76e7a74c0 Mon Sep 17 00:00:00 2001 From: halgari Date: Wed, 18 Sep 2024 17:48:25 -0600 Subject: [PATCH 06/11] Load images as part of the collection cards --- .../Attributes/MemoryAttribute.cs | 24 +++++++++++++++++++ .../Models/Collection.cs | 5 ++++ .../Models/CollectionRevision.cs | 5 ++++ .../Models/User.cs | 6 +++++ .../Services.cs | 1 + .../GraphQL/CollectionInfo.graphql | 8 +++++++ .../NexusModsLibrary.cs | 17 ++++++++++++- .../Collections/CollectionCardViewModel.cs | 9 +++---- 8 files changed, 70 insertions(+), 5 deletions(-) create mode 100644 src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Attributes/MemoryAttribute.cs diff --git a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Attributes/MemoryAttribute.cs b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Attributes/MemoryAttribute.cs new file mode 100644 index 000000000..e5f5ec594 --- /dev/null +++ b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Attributes/MemoryAttribute.cs @@ -0,0 +1,24 @@ +using System.Buffers; +using NexusMods.MnemonicDB.Abstractions; +using NexusMods.MnemonicDB.Abstractions.Attributes; +using NexusMods.MnemonicDB.Abstractions.ElementComparers; + +namespace NexusMods.Abstractions.NexusModsLibrary.Attributes; + +/// +/// A hashed blob attribute for . +/// +public class MemoryAttribute(string ns, string name) : HashedBlobAttribute>(ns, name) +{ + /// + protected override Memory FromLowLevel(ReadOnlySpan value, ValueTags tags, RegistryId registryId) + { + return new Memory(value.ToArray()); + } + + /// + protected override void WriteValue(Memory value, TWriter writer) + { + writer.Write(value.Span); + } +} diff --git a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/Collection.cs b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/Collection.cs index fd0c6c460..2cf977e29 100644 --- a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/Collection.cs +++ b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/Collection.cs @@ -46,4 +46,9 @@ public partial class Collection : IModelDefinition /// The number of endorsements the collection has. /// public static readonly ULongAttribute Endorsements = new(Namespace, nameof(Endorsements)); + + /// + /// The collections' image. + /// + public static readonly MemoryAttribute TileImage = new(Namespace, nameof(TileImage)); } diff --git a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/CollectionRevision.cs b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/CollectionRevision.cs index 94f94d3f6..15d368542 100644 --- a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/CollectionRevision.cs +++ b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/CollectionRevision.cs @@ -46,4 +46,9 @@ public partial class CollectionRevision : IModelDefinition /// The total number of ratings this revision has. /// public static readonly ULongAttribute TotalRatings = new(Namespace, nameof(TotalRatings)); + + /// + /// The total number of mods in this revision. + /// + public static readonly ULongAttribute ModCount = new(Namespace, nameof(ModCount)); } diff --git a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/User.cs b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/User.cs index 710c356cb..b8d388702 100644 --- a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/User.cs +++ b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/User.cs @@ -1,4 +1,5 @@ using NexusMods.Abstractions.MnemonicDB.Attributes; +using NexusMods.Abstractions.NexusModsLibrary.Attributes; using NexusMods.MnemonicDB.Abstractions.Attributes; using NexusMods.MnemonicDB.Abstractions.Models; @@ -25,4 +26,9 @@ public partial class User : IModelDefinition /// The user's avatar URL. /// public static readonly UriAttribute Avatar = new(Namespace, nameof(Avatar)); + + /// + /// The user's avatar image. + /// + public static readonly MemoryAttribute AvatarImage = new(Namespace, nameof(AvatarImage)); } diff --git a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Services.cs b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Services.cs index 86a8253ba..43f8a95fd 100644 --- a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Services.cs +++ b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Services.cs @@ -21,6 +21,7 @@ public static IServiceCollection AddNexusModsLibraryModels(this IServiceCollecti .AddNexusModsLibraryFileModel() .AddCollectionModel() .AddCollectionRevisionModel() + .AddCollectionTagModel() .AddUserModel() .AddNexusModsCollectionLibraryFileModel(); } diff --git a/src/Networking/NexusMods.Networking.NexusWebApi/GraphQL/CollectionInfo.graphql b/src/Networking/NexusMods.Networking.NexusWebApi/GraphQL/CollectionInfo.graphql index 9658f8e8b..5ad1721da 100644 --- a/src/Networking/NexusMods.Networking.NexusWebApi/GraphQL/CollectionInfo.graphql +++ b/src/Networking/NexusMods.Networking.NexusWebApi/GraphQL/CollectionInfo.graphql @@ -7,6 +7,13 @@ query CollectionInfo($slug: String!, $viewAdultContent: Boolean!) name summary endorsements + tileImage { + thumbnailUrl(size: small) + } + tags { + name + id + } revisions { id @@ -17,6 +24,7 @@ query CollectionInfo($slug: String!, $viewAdultContent: Boolean!) totalSize overallRating overallRatingCount + modCount } user { name diff --git a/src/Networking/NexusMods.Networking.NexusWebApi/NexusModsLibrary.cs b/src/Networking/NexusMods.Networking.NexusWebApi/NexusModsLibrary.cs index 358243f05..68684bd72 100644 --- a/src/Networking/NexusMods.Networking.NexusWebApi/NexusModsLibrary.cs +++ b/src/Networking/NexusMods.Networking.NexusWebApi/NexusModsLibrary.cs @@ -24,13 +24,15 @@ public class NexusModsLibrary private readonly IConnection _connection; private readonly INexusApiClient _apiClient; private readonly NexusGraphQLClient _gqlClient; - + private readonly HttpClient _httpClient; + /// /// Constructor. /// public NexusModsLibrary(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; + _httpClient = serviceProvider.GetRequiredService().CreateClient(); _connection = serviceProvider.GetRequiredService(); _apiClient = serviceProvider.GetRequiredService(); _gqlClient = serviceProvider.GetRequiredService(); @@ -85,6 +87,8 @@ public NexusModsLibrary(IServiceProvider serviceProvider) var info = await _gqlClient.CollectionInfo.ExecuteAsync(slug.Value, true, token); var collectionInfo = info.Data!.Collection; + var collectionTileImage = _httpClient.GetByteArrayAsync(new Uri(collectionInfo.TileImage!.ThumbnailUrl), token); + var avatarImage = _httpClient.GetByteArrayAsync(new Uri(collectionInfo.User.Avatar), token); using var tx = _connection.BeginTransaction(); var db = _connection.Db; @@ -92,14 +96,17 @@ public NexusModsLibrary(IServiceProvider serviceProvider) collectionResolver.Add(Collection.Name, collectionInfo.Name); collectionResolver.Add(Collection.Summary, collectionInfo.Summary); collectionResolver.Add(Collection.Endorsements, (ulong)collectionInfo.Endorsements); + collectionResolver.Add(Collection.TileImage, await collectionTileImage); // Remap the user info var userResolver = GraphQLResolver.Create(db, tx, User.NexusId, (ulong)collectionInfo.User.MemberId); userResolver.Add(User.Name, collectionInfo.User.Name); userResolver.Add(User.Avatar, new Uri(collectionInfo.User.Avatar)); + userResolver.Add(User.AvatarImage, await avatarImage); collectionResolver.Add(Collection.User, userResolver.Id); + // Remap the revisions foreach (var revision in collectionInfo.Revisions) { var revisionResolver = GraphQLResolver.Create(db, tx, CollectionRevision.RevisionId, RevisionId.From((ulong)revision.Id)); @@ -110,6 +117,14 @@ public NexusModsLibrary(IServiceProvider serviceProvider) revisionResolver.Add(CollectionRevision.TotalSize, Size.From(ulong.Parse(revision.TotalSize))); revisionResolver.Add(CollectionRevision.OverallRating, float.Parse(revision.OverallRating ?? "0.0")); revisionResolver.Add(CollectionRevision.TotalRatings, (ulong)(revision.OverallRatingCount ?? 0)); + revisionResolver.Add(CollectionRevision.ModCount, (ulong)revision.ModCount); + } + + foreach (var tag in collectionInfo.Tags) + { + var categoryResolver = GraphQLResolver.Create(db, tx, CollectionTag.NexusId, ulong.Parse(tag.Id)); + categoryResolver.Add(CollectionTag.Name, tag.Name); + collectionResolver.Add(Collection.Tags, categoryResolver.Id); } var txResults = await tx.Commit(); diff --git a/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardViewModel.cs b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardViewModel.cs index f28291fde..27ca41dda 100644 --- a/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardViewModel.cs +++ b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardViewModel.cs @@ -1,4 +1,5 @@ using Avalonia.Media.Imaging; +using Avalonia.Platform; using NexusMods.Abstractions.Jobs; using NexusMods.Abstractions.NexusModsLibrary.Models; using NexusMods.Abstractions.NexusWebApi.Types; @@ -20,14 +21,14 @@ public CollectionCardViewModel(IConnection connection, RevisionId revision) } public string Name => _collection.Name; - public Bitmap Image => throw new NotImplementedException(); + public Bitmap Image => new(new MemoryStream(_collection.TileImage.ToArray())); public string Summary => _collection.Summary; - public string Category => "TODO"; - public int ModCount => -1; + public string Category => string.Join(" ", _collection.Tags.Select(t => t.Name)); + public int ModCount => (int)_revision.ModCount; public ulong EndorsementCount => _collection.Endorsements; public ulong DownloadCount => _revision.Downloads; public Size TotalSize => _revision.TotalSize; public Percent OverallRating => Percent.CreateClamped(_revision.OverallRating); public string AuthorName => _collection.User.Name; - public Bitmap AuthorAvatar => throw new NotImplementedException(); + public Bitmap AuthorAvatar => new(new MemoryStream(_collection.User.AvatarImage.ToArray())); } From 2663339b5cecf2e6f9106ced85b5bcc315370211 Mon Sep 17 00:00:00 2001 From: halgari Date: Wed, 18 Sep 2024 18:05:15 -0600 Subject: [PATCH 07/11] Few more code comments --- .../GraphQLResolver.cs | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/GraphQLResolver.cs b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/GraphQLResolver.cs index 3979688de..47153853c 100644 --- a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/GraphQLResolver.cs +++ b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/GraphQLResolver.cs @@ -5,8 +5,20 @@ namespace NexusMods.Abstractions.NexusModsLibrary; -public struct GraphQLResolver(ITransaction Tx, ReadOnlyModel Model) +/// +/// A helper for upserting entities in the database. When created, you must define a "pimary key" attribute and value, +/// these are used to determine if the entity already exists in the database. If it does, the existing entity is updated, +/// otherwise a new entity is created. +/// +/// For each attribute you want to add to the entity, call the Add method with the attribute and value and any duplicate values +/// will not be added. +/// +// ReSharper disable once InconsistentNaming +public readonly struct GraphQLResolver(ITransaction Tx, ReadOnlyModel Model) { + /// + /// Create a new resolver using the given primary key attribute and value. + /// public static GraphQLResolver Create(IDb referenceDb, ITransaction tx, ScalarAttribute primaryKeyAttribute, THighLevel primaryKeyValue) where THighLevel : notnull { var existing = referenceDb.Datoms(primaryKeyAttribute, primaryKeyValue); @@ -22,6 +34,9 @@ public static GraphQLResolver Create(IDb referenceDb, ITr /// public EntityId Id => Model.Id; + /// + /// Add a value to the entity. If the value already exists, it will not be added again. + /// public void Add(ScalarAttribute attribute, THighLevel value) where THighLevel : notnull { @@ -35,6 +50,9 @@ public void Add(ScalarAttribute at Tx.Add(Model.Id, attribute, value); } + /// + /// Add a value to the entity. If the value already exists, it will not be added again. + /// public void Add(ReferencesAttribute attribute, EntityId id) where TOther : IModelDefinition { @@ -51,6 +69,9 @@ public void Add(ReferencesAttribute attribute, EntityId id) Tx.Add(Model.Id, attribute, id); } + /// + /// Add a value to the entity. If the value already exists, it will not be added again. + /// public void Add(ReferenceAttribute attribute, EntityId id) where TOther : IModelDefinition { From c52fb6d56f47ca34074351b121a28c1bea5d8838 Mon Sep 17 00:00:00 2001 From: halgari Date: Wed, 18 Sep 2024 18:06:46 -0600 Subject: [PATCH 08/11] Document the ICollectionCardViewModel.cs file --- .../Collections/ICollectionCardViewModel.cs | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/NexusMods.App.UI/Pages/LibraryPage/Collections/ICollectionCardViewModel.cs b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/ICollectionCardViewModel.cs index b0ac16e15..235d92e73 100644 --- a/src/NexusMods.App.UI/Pages/LibraryPage/Collections/ICollectionCardViewModel.cs +++ b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/ICollectionCardViewModel.cs @@ -4,27 +4,63 @@ namespace NexusMods.App.UI.Pages.LibraryPage.Collections; +/// +/// View model for a collection card. +/// public interface ICollectionCardViewModel : IViewModelInterface { + /// + /// The name of the collection. + /// public string Name { get; } + /// + /// The tile image of the collection. + /// public Bitmap Image { get; } + /// + /// Summary of the collection. + /// public string Summary { get; } + /// + /// The website category of the collection. + /// public string Category { get; } + /// + /// Number of mods in the collection. + /// public int ModCount { get; } + /// + /// Endorsement count of the collection. + /// public ulong EndorsementCount { get; } + /// + /// Number of downloads of the collection. + /// public ulong DownloadCount { get; } + /// + /// Total size of the collection (including all mods). + /// public Size TotalSize { get; } + /// + /// The overall rating of the collection. + /// public Percent OverallRating { get; } + /// + /// The name of the author of the collection. + /// public string AuthorName { get; } + /// + /// The author's avatar. + /// public Bitmap AuthorAvatar { get; } } From bb5416399b64986a22f5f82e52b41c8c5ef6a445 Mon Sep 17 00:00:00 2001 From: halgari Date: Thu, 19 Sep 2024 06:29:25 -0600 Subject: [PATCH 09/11] Bit of code cleanup --- .../Models/CollectionRevision.cs | 5 +++-- src/NexusMods.App.UI/NexusMods.App.UI.csproj | 3 --- .../LibraryPage/Collections/CollectionsViewModel.cs | 11 +++-------- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/CollectionRevision.cs b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/CollectionRevision.cs index 15d368542..69b749bdf 100644 --- a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/CollectionRevision.cs +++ b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/CollectionRevision.cs @@ -6,7 +6,8 @@ namespace NexusMods.Abstractions.NexusModsLibrary.Models; /// -/// Metadata about a collection on Nexus Mods. +/// Metadata about a collection revision on Nexus Mods. A revision references a collection, but is itself immutable. +/// Each change to a collection is expressed as a separate revision. /// public partial class CollectionRevision : IModelDefinition { @@ -33,7 +34,7 @@ public partial class CollectionRevision : IModelDefinition public static readonly ULongAttribute Downloads = new(Namespace, nameof(Downloads)); /// - /// Total size of the revision + /// Total size of all files in this revision, including the size of the revision's files. /// public static readonly SizeAttribute TotalSize = new(Namespace, nameof(TotalSize)); diff --git a/src/NexusMods.App.UI/NexusMods.App.UI.csproj b/src/NexusMods.App.UI/NexusMods.App.UI.csproj index 08b645203..39b730151 100644 --- a/src/NexusMods.App.UI/NexusMods.App.UI.csproj +++ b/src/NexusMods.App.UI/NexusMods.App.UI.csproj @@ -638,9 +638,6 @@ ICollectionCardViewModel.cs - - ITwoPanelPageViewModel.cs - ICollectionsViewModel.cs diff --git a/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionsViewModel.cs b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionsViewModel.cs index e8b981fb4..d7b799570 100644 --- a/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionsViewModel.cs +++ b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionsViewModel.cs @@ -16,11 +16,11 @@ namespace NexusMods.App.UI.Pages.LibraryPage.Collections; -public class CollectionsViewModel : AViewModel, ICollectionsViewModel +public class CollectionsViewModel : APageViewModel, ICollectionsViewModel { private readonly IConnection _conn; - public CollectionsViewModel(IConnection conn) + public CollectionsViewModel(IConnection conn, IWindowManager windowManager) : base(windowManager) { _conn = conn; @@ -34,12 +34,7 @@ public CollectionsViewModel(IConnection conn) } ); } - - private CollectionRevision.ReadOnly SelectLatest(IGroup group) - { - return group.Cache.Items.MaxBy(r => r.RevisionNumber); - } - + public IconValue TabIcon { get; } = IconValues.ModLibrary; public string TabTitle { get; } = "Collections (WIP)"; public WindowId WindowId { get; set; } From d292b73f9a566d5b14efde0805e03147b9a0977c Mon Sep 17 00:00:00 2001 From: halgari Date: Thu, 19 Sep 2024 06:52:30 -0600 Subject: [PATCH 10/11] clarify the comments on `TotalSize` --- .../Models/CollectionRevision.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/CollectionRevision.cs b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/CollectionRevision.cs index 69b749bdf..6c6acc797 100644 --- a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/CollectionRevision.cs +++ b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/CollectionRevision.cs @@ -34,7 +34,7 @@ public partial class CollectionRevision : IModelDefinition public static readonly ULongAttribute Downloads = new(Namespace, nameof(Downloads)); /// - /// Total size of all files in this revision, including the size of the revision's files. + /// Total download size of all files in this revision, including the size of the revision's files. /// public static readonly SizeAttribute TotalSize = new(Namespace, nameof(TotalSize)); From d53d88399eb6e4ef8b0f3d472dc3ef9871b5e41d Mon Sep 17 00:00:00 2001 From: halgari Date: Thu, 19 Sep 2024 06:57:40 -0600 Subject: [PATCH 11/11] Bit more code cleanup --- .../{Collection.cs => CollectionMetadata.cs} | 6 +-- ...ision.cs => CollectionRevisionMetadata.cs} | 4 +- .../NexusModsCollectionLibraryFile.cs | 2 +- .../Services.cs | 4 +- .../NexusModsCollectionDownloadJob.cs | 2 +- .../NexusModsLibrary.cs | 40 +++++++++---------- .../Collections/CollectionCardViewModel.cs | 10 ++--- .../Collections/CollectionsPage.cs | 4 +- .../Collections/CollectionsViewModel.cs | 2 +- 9 files changed, 38 insertions(+), 36 deletions(-) rename src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/{Collection.cs => CollectionMetadata.cs} (88%) rename src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/{CollectionRevision.cs => CollectionRevisionMetadata.cs} (92%) diff --git a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/Collection.cs b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/CollectionMetadata.cs similarity index 88% rename from src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/Collection.cs rename to src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/CollectionMetadata.cs index 2cf977e29..630e0bba1 100644 --- a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/Collection.cs +++ b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/CollectionMetadata.cs @@ -8,7 +8,7 @@ namespace NexusMods.Abstractions.NexusModsLibrary.Models; /// /// Metadata about a collection on Nexus Mods. /// -public partial class Collection : IModelDefinition +public partial class CollectionMetadata : IModelDefinition { private const string Namespace = "NexusMods.Library.NexusModsCollectionMetadata"; @@ -30,12 +30,12 @@ public partial class Collection : IModelDefinition /// /// The Curating user of the collection. /// - public static readonly ReferenceAttribute User = new(Namespace, nameof(User)); + public static readonly ReferenceAttribute Author = new(Namespace, nameof(Author)); /// /// The revisions of the collection. /// - public static readonly BackReferenceAttribute Revisions = new(CollectionRevision.Collection); + public static readonly BackReferenceAttribute Revisions = new(CollectionRevisionMetadata.Collection); /// /// The tags on the collection. diff --git a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/CollectionRevision.cs b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/CollectionRevisionMetadata.cs similarity index 92% rename from src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/CollectionRevision.cs rename to src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/CollectionRevisionMetadata.cs index 6c6acc797..82bc789c4 100644 --- a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/CollectionRevision.cs +++ b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/CollectionRevisionMetadata.cs @@ -9,7 +9,7 @@ namespace NexusMods.Abstractions.NexusModsLibrary.Models; /// Metadata about a collection revision on Nexus Mods. A revision references a collection, but is itself immutable. /// Each change to a collection is expressed as a separate revision. /// -public partial class CollectionRevision : IModelDefinition +public partial class CollectionRevisionMetadata : IModelDefinition { private const string Namespace = "NexusMods.Library.NexusModsCollectionRevision"; @@ -26,7 +26,7 @@ public partial class CollectionRevision : IModelDefinition /// /// The collection this revision belongs to. /// - public static readonly ReferenceAttribute Collection = new(Namespace, nameof(Collection)); + public static readonly ReferenceAttribute Collection = new(Namespace, nameof(Collection)); /// /// The number of downloads this revision has. diff --git a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/NexusModsCollectionLibraryFile.cs b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/NexusModsCollectionLibraryFile.cs index 44e9411e0..39b374a47 100644 --- a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/NexusModsCollectionLibraryFile.cs +++ b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/NexusModsCollectionLibraryFile.cs @@ -17,5 +17,5 @@ public partial class NexusModsCollectionLibraryFile : IModelDefinition /// /// The collection revision this file belongs to. /// - public static readonly ReferenceAttribute CollectionRevision = new(Namespace, nameof(CollectionRevision)); + public static readonly ReferenceAttribute CollectionRevision = new(Namespace, nameof(CollectionRevision)); } diff --git a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Services.cs b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Services.cs index 43f8a95fd..5164a16d5 100644 --- a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Services.cs +++ b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Services.cs @@ -19,8 +19,8 @@ public static IServiceCollection AddNexusModsLibraryModels(this IServiceCollecti .AddNexusModsFileMetadataModel() .AddNexusModsModPageMetadataModel() .AddNexusModsLibraryFileModel() - .AddCollectionModel() - .AddCollectionRevisionModel() + .AddCollectionMetadataModel() + .AddCollectionRevisionMetadataModel() .AddCollectionTagModel() .AddUserModel() .AddNexusModsCollectionLibraryFileModel(); diff --git a/src/Networking/NexusMods.Networking.NexusWebApi/NexusModsCollectionDownloadJob.cs b/src/Networking/NexusMods.Networking.NexusWebApi/NexusModsCollectionDownloadJob.cs index 58372bb02..013997684 100644 --- a/src/Networking/NexusMods.Networking.NexusWebApi/NexusModsCollectionDownloadJob.cs +++ b/src/Networking/NexusMods.Networking.NexusWebApi/NexusModsCollectionDownloadJob.cs @@ -25,7 +25,7 @@ public class NexusModsCollectionDownloadJob : IJobDefinitionWithStart /// The metadata of the collection revision. /// - public CollectionRevision.ReadOnly? Metadata { get; set; } + public CollectionRevisionMetadata.ReadOnly? Metadata { get; set; } /// /// The collection slug diff --git a/src/Networking/NexusMods.Networking.NexusWebApi/NexusModsLibrary.cs b/src/Networking/NexusMods.Networking.NexusWebApi/NexusModsLibrary.cs index 68684bd72..5732b10b0 100644 --- a/src/Networking/NexusMods.Networking.NexusWebApi/NexusModsLibrary.cs +++ b/src/Networking/NexusMods.Networking.NexusWebApi/NexusModsLibrary.cs @@ -75,11 +75,11 @@ public NexusModsLibrary(IServiceProvider serviceProvider) /// /// Get or add a collection metadata /// - public async Task GetOrAddCollectionMetadata(CollectionSlug slug, bool referesh = false, CancellationToken token = default) + public async Task GetOrAddCollectionMetadata(CollectionSlug slug, bool referesh = false, CancellationToken token = default) { if (!referesh) { - var collections = Collection.FindBySlug(_connection.Db, slug); + var collections = CollectionMetadata.FindBySlug(_connection.Db, slug); if (collections.TryGetFirst(x => x.Slug == slug, out var collection)) return collection; } @@ -92,11 +92,11 @@ public NexusModsLibrary(IServiceProvider serviceProvider) using var tx = _connection.BeginTransaction(); var db = _connection.Db; - var collectionResolver = GraphQLResolver.Create(db, tx, Collection.Slug, slug); - collectionResolver.Add(Collection.Name, collectionInfo.Name); - collectionResolver.Add(Collection.Summary, collectionInfo.Summary); - collectionResolver.Add(Collection.Endorsements, (ulong)collectionInfo.Endorsements); - collectionResolver.Add(Collection.TileImage, await collectionTileImage); + var collectionResolver = GraphQLResolver.Create(db, tx, CollectionMetadata.Slug, slug); + collectionResolver.Add(CollectionMetadata.Name, collectionInfo.Name); + collectionResolver.Add(CollectionMetadata.Summary, collectionInfo.Summary); + collectionResolver.Add(CollectionMetadata.Endorsements, (ulong)collectionInfo.Endorsements); + collectionResolver.Add(CollectionMetadata.TileImage, await collectionTileImage); // Remap the user info var userResolver = GraphQLResolver.Create(db, tx, User.NexusId, (ulong)collectionInfo.User.MemberId); @@ -104,38 +104,38 @@ public NexusModsLibrary(IServiceProvider serviceProvider) userResolver.Add(User.Avatar, new Uri(collectionInfo.User.Avatar)); userResolver.Add(User.AvatarImage, await avatarImage); - collectionResolver.Add(Collection.User, userResolver.Id); + collectionResolver.Add(CollectionMetadata.Author, userResolver.Id); // Remap the revisions foreach (var revision in collectionInfo.Revisions) { - var revisionResolver = GraphQLResolver.Create(db, tx, CollectionRevision.RevisionId, RevisionId.From((ulong)revision.Id)); - revisionResolver.Add(CollectionRevision.RevisionId, RevisionId.From((ulong)revision.Id)); - revisionResolver.Add(CollectionRevision.RevisionNumber, RevisionNumber.From((ulong)revision.RevisionNumber)); - revisionResolver.Add(CollectionRevision.CollectionId, collectionResolver.Id); - revisionResolver.Add(CollectionRevision.Downloads, (ulong)revision.TotalDownloads); - revisionResolver.Add(CollectionRevision.TotalSize, Size.From(ulong.Parse(revision.TotalSize))); - revisionResolver.Add(CollectionRevision.OverallRating, float.Parse(revision.OverallRating ?? "0.0")); - revisionResolver.Add(CollectionRevision.TotalRatings, (ulong)(revision.OverallRatingCount ?? 0)); - revisionResolver.Add(CollectionRevision.ModCount, (ulong)revision.ModCount); + var revisionResolver = GraphQLResolver.Create(db, tx, CollectionRevisionMetadata.RevisionId, RevisionId.From((ulong)revision.Id)); + revisionResolver.Add(CollectionRevisionMetadata.RevisionId, RevisionId.From((ulong)revision.Id)); + revisionResolver.Add(CollectionRevisionMetadata.RevisionNumber, RevisionNumber.From((ulong)revision.RevisionNumber)); + revisionResolver.Add(CollectionRevisionMetadata.CollectionId, collectionResolver.Id); + revisionResolver.Add(CollectionRevisionMetadata.Downloads, (ulong)revision.TotalDownloads); + revisionResolver.Add(CollectionRevisionMetadata.TotalSize, Size.From(ulong.Parse(revision.TotalSize))); + revisionResolver.Add(CollectionRevisionMetadata.OverallRating, float.Parse(revision.OverallRating ?? "0.0")); + revisionResolver.Add(CollectionRevisionMetadata.TotalRatings, (ulong)(revision.OverallRatingCount ?? 0)); + revisionResolver.Add(CollectionRevisionMetadata.ModCount, (ulong)revision.ModCount); } foreach (var tag in collectionInfo.Tags) { var categoryResolver = GraphQLResolver.Create(db, tx, CollectionTag.NexusId, ulong.Parse(tag.Id)); categoryResolver.Add(CollectionTag.Name, tag.Name); - collectionResolver.Add(Collection.Tags, categoryResolver.Id); + collectionResolver.Add(CollectionMetadata.Tags, categoryResolver.Id); } var txResults = await tx.Commit(); - return Collection.Load(txResults.Db, txResults[collectionResolver.Id]); + return CollectionMetadata.Load(txResults.Db, txResults[collectionResolver.Id]); } /// /// Get or add a collection metadata /// - public async Task GetOrAddCollectionRevision(CollectionSlug slug, RevisionNumber revisionNumber, CancellationToken token) + public async Task GetOrAddCollectionRevision(CollectionSlug slug, RevisionNumber revisionNumber, CancellationToken token) { var collection = await GetOrAddCollectionMetadata(slug, false, token); if (collection.Revisions.TryGetFirst(r => r.RevisionNumber == revisionNumber, out var revision)) diff --git a/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardViewModel.cs b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardViewModel.cs index 27ca41dda..29357e5a4 100644 --- a/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardViewModel.cs +++ b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardViewModel.cs @@ -10,12 +10,12 @@ namespace NexusMods.App.UI.Pages.LibraryPage.Collections; public class CollectionCardViewModel : AViewModel, ICollectionCardViewModel { - private readonly CollectionRevision.ReadOnly _revision; - private readonly Collection.ReadOnly _collection; + private readonly CollectionRevisionMetadata.ReadOnly _revision; + private readonly CollectionMetadata.ReadOnly _collection; public CollectionCardViewModel(IConnection connection, RevisionId revision) { - _revision = CollectionRevision.FindByRevisionId(connection.Db, revision) + _revision = CollectionRevisionMetadata.FindByRevisionId(connection.Db, revision) .First(); _collection = _revision.Collection; } @@ -29,6 +29,6 @@ public CollectionCardViewModel(IConnection connection, RevisionId revision) public ulong DownloadCount => _revision.Downloads; public Size TotalSize => _revision.TotalSize; public Percent OverallRating => Percent.CreateClamped(_revision.OverallRating); - public string AuthorName => _collection.User.Name; - public Bitmap AuthorAvatar => new(new MemoryStream(_collection.User.AvatarImage.ToArray())); + public string AuthorName => _collection.Author.Name; + public Bitmap AuthorAvatar => new(new MemoryStream(_collection.Author.AvatarImage.ToArray())); } diff --git a/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionsPage.cs b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionsPage.cs index e54c8c76c..fa51b0c68 100644 --- a/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionsPage.cs +++ b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionsPage.cs @@ -4,6 +4,7 @@ using NexusMods.Abstractions.Serialization.Attributes; using NexusMods.Abstractions.Settings; using NexusMods.App.UI.Resources; +using NexusMods.App.UI.Windows; using NexusMods.App.UI.WorkspaceSystem; using NexusMods.Icons; using NexusMods.MnemonicDB.Abstractions; @@ -31,7 +32,8 @@ public CollectionsPageFactory(IServiceProvider serviceProvider) : base(servicePr public override ICollectionsViewModel CreateViewModel(CollectionsPageContext context) { - var vm = new CollectionsViewModel(ServiceProvider.GetRequiredService()); + var vm = new CollectionsViewModel(ServiceProvider.GetRequiredService(), + ServiceProvider.GetRequiredService()); return vm; } diff --git a/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionsViewModel.cs b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionsViewModel.cs index d7b799570..dc44bf18d 100644 --- a/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionsViewModel.cs +++ b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionsViewModel.cs @@ -26,7 +26,7 @@ public CollectionsViewModel(IConnection conn, IWindowManager windowManager) : ba this.WhenActivated(d => { - Collection.ObserveAll(conn) + CollectionMetadata.ObserveAll(conn) .Transform(coll => (ICollectionCardViewModel)new CollectionCardViewModel(conn, coll.Revisions.First().RevisionId)) .Bind(out _collections) .Subscribe()