-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Oof, I suck at UI * Bit of implementing the actual VM * Start on the visual layout for the collection cards * Add the styles to the style index * Add a collections panel and it integrates with the rest of the app to show known collections * Load images as part of the collection cards * Few more code comments * Document the ICollectionCardViewModel.cs file * Bit of code cleanup * clarify the comments on `TotalSize` * Bit more code cleanup
- Loading branch information
Showing
32 changed files
with
994 additions
and
116 deletions.
There are no files selected for viewing
18 changes: 18 additions & 0 deletions
18
src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Attributes/FloatAttribute.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<float, float>(ValueTags.Float32, ns, name) | ||
{ | ||
protected override float ToLowLevel(float value) | ||
{ | ||
return value; | ||
} | ||
|
||
protected override float FromLowLevel(float value, ValueTags tags, RegistryId registryId) | ||
{ | ||
return value; | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Attributes/MemoryAttribute.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
|
||
/// <summary> | ||
/// A hashed blob attribute for <see cref="Memory{T}"/>. | ||
/// </summary> | ||
public class MemoryAttribute(string ns, string name) : HashedBlobAttribute<Memory<byte>>(ns, name) | ||
{ | ||
/// <inheritdoc /> | ||
protected override Memory<byte> FromLowLevel(ReadOnlySpan<byte> value, ValueTags tags, RegistryId registryId) | ||
{ | ||
return new Memory<byte>(value.ToArray()); | ||
} | ||
|
||
/// <inheritdoc /> | ||
protected override void WriteValue<TWriter>(Memory<byte> value, TWriter writer) | ||
{ | ||
writer.Write(value.Span); | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/CollectionTag.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
using NexusMods.Abstractions.MnemonicDB.Attributes; | ||
using NexusMods.MnemonicDB.Abstractions.Attributes; | ||
using NexusMods.MnemonicDB.Abstractions.Models; | ||
|
||
namespace NexusMods.Abstractions.NexusModsLibrary; | ||
|
||
/// <summary> | ||
/// A tag for a collection. | ||
/// </summary> | ||
public partial class CollectionTag : IModelDefinition | ||
{ | ||
private const string Namespace = "NexusMods.Abstractions.NexusModsLibrary.CollectionTag"; | ||
|
||
/// <summary> | ||
/// The name of the collection tag. | ||
/// </summary> | ||
public static readonly StringAttribute Name = new(Namespace, nameof(Name)) { IsIndexed = true }; | ||
|
||
/// <summary> | ||
/// The Nexus mods id of the collection tag. | ||
/// </summary> | ||
public static readonly ULongAttribute NexusId = new(Namespace, nameof(NexusId)) { IsIndexed = true }; | ||
} |
90 changes: 90 additions & 0 deletions
90
src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/GraphQLResolver.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
using NexusMods.MnemonicDB.Abstractions; | ||
using NexusMods.MnemonicDB.Abstractions.Attributes; | ||
using NexusMods.MnemonicDB.Abstractions.Models; | ||
using Splat.ModeDetection; | ||
|
||
namespace NexusMods.Abstractions.NexusModsLibrary; | ||
|
||
/// <summary> | ||
/// 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. | ||
/// </summary> | ||
// ReSharper disable once InconsistentNaming | ||
public readonly struct GraphQLResolver(ITransaction Tx, ReadOnlyModel Model) | ||
{ | ||
/// <summary> | ||
/// Create a new resolver using the given primary key attribute and value. | ||
/// </summary> | ||
public static GraphQLResolver Create<THighLevel, TLowLevel>(IDb referenceDb, ITransaction tx, ScalarAttribute<THighLevel, TLowLevel> 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)); | ||
} | ||
|
||
/// <summary> | ||
/// The id of the entity, may be temporary if this is a new entity. | ||
/// </summary> | ||
public EntityId Id => Model.Id; | ||
|
||
/// <summary> | ||
/// Add a value to the entity. If the value already exists, it will not be added again. | ||
/// </summary> | ||
public void Add<THighLevel, TLowLevel>(ScalarAttribute<THighLevel, TLowLevel> 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); | ||
} | ||
|
||
/// <summary> | ||
/// Add a value to the entity. If the value already exists, it will not be added again. | ||
/// </summary> | ||
public void Add<TOther>(ReferencesAttribute<TOther> 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); | ||
} | ||
|
||
/// <summary> | ||
/// Add a value to the entity. If the value already exists, it will not be added again. | ||
/// </summary> | ||
public void Add<TOther>(ReferenceAttribute<TOther> 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); | ||
} | ||
} |
54 changes: 54 additions & 0 deletions
54
src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/CollectionMetadata.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
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; | ||
|
||
/// <summary> | ||
/// Metadata about a collection on Nexus Mods. | ||
/// </summary> | ||
public partial class CollectionMetadata : IModelDefinition | ||
{ | ||
private const string Namespace = "NexusMods.Library.NexusModsCollectionMetadata"; | ||
|
||
/// <summary> | ||
/// The collection slug. | ||
/// </summary> | ||
public static readonly CollectionsSlugAttribute Slug = new(Namespace, nameof(Slug)) { IsIndexed = true }; | ||
|
||
/// <summary> | ||
/// The name of the collection. | ||
/// </summary> | ||
public static readonly StringAttribute Name = new(Namespace, nameof(Name)); | ||
|
||
/// <summary> | ||
/// The short description of the collection | ||
/// </summary> | ||
public static readonly StringAttribute Summary = new(Namespace, nameof(Summary)); | ||
|
||
/// <summary> | ||
/// The Curating user of the collection. | ||
/// </summary> | ||
public static readonly ReferenceAttribute<User> Author = new(Namespace, nameof(Author)); | ||
|
||
/// <summary> | ||
/// The revisions of the collection. | ||
/// </summary> | ||
public static readonly BackReferenceAttribute<CollectionRevisionMetadata> Revisions = new(CollectionRevisionMetadata.Collection); | ||
|
||
/// <summary> | ||
/// The tags on the collection. | ||
/// </summary> | ||
public static readonly ReferencesAttribute<CollectionTag> Tags = new(Namespace, nameof(Tags)); | ||
|
||
/// <summary> | ||
/// The number of endorsements the collection has. | ||
/// </summary> | ||
public static readonly ULongAttribute Endorsements = new(Namespace, nameof(Endorsements)); | ||
|
||
/// <summary> | ||
/// The collections' image. | ||
/// </summary> | ||
public static readonly MemoryAttribute TileImage = new(Namespace, nameof(TileImage)); | ||
} |
55 changes: 55 additions & 0 deletions
55
...Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/CollectionRevisionMetadata.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
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; | ||
|
||
/// <summary> | ||
/// 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. | ||
/// </summary> | ||
public partial class CollectionRevisionMetadata : IModelDefinition | ||
{ | ||
private const string Namespace = "NexusMods.Library.NexusModsCollectionRevision"; | ||
|
||
/// <summary> | ||
/// The globally unique id identifying a specific revision of a collection. | ||
/// </summary> | ||
public static readonly RevisionIdAttribute RevisionId = new(Namespace, nameof(RevisionId)) { IsIndexed = true }; | ||
|
||
/// <summary> | ||
/// The locally unique revision number (aka "version") of a collection. Only unique within one collection. | ||
/// </summary> | ||
public static readonly RevisionNumberAttribute RevisionNumber = new(Namespace, nameof(RevisionNumber)); | ||
|
||
/// <summary> | ||
/// The collection this revision belongs to. | ||
/// </summary> | ||
public static readonly ReferenceAttribute<CollectionMetadata> Collection = new(Namespace, nameof(Collection)); | ||
|
||
/// <summary> | ||
/// The number of downloads this revision has. | ||
/// </summary> | ||
public static readonly ULongAttribute Downloads = new(Namespace, nameof(Downloads)); | ||
|
||
/// <summary> | ||
/// Total download size of all files in this revision, including the size of the revision's files. | ||
/// </summary> | ||
public static readonly SizeAttribute TotalSize = new(Namespace, nameof(TotalSize)); | ||
|
||
/// <summary> | ||
/// The overall rating of this revision (often displayed as a percentage). | ||
/// </summary> | ||
public static readonly FloatAttribute OverallRating = new(Namespace, nameof(OverallRating)); | ||
|
||
/// <summary> | ||
/// The total number of ratings this revision has. | ||
/// </summary> | ||
public static readonly ULongAttribute TotalRatings = new(Namespace, nameof(TotalRatings)); | ||
|
||
/// <summary> | ||
/// The total number of mods in this revision. | ||
/// </summary> | ||
public static readonly ULongAttribute ModCount = new(Namespace, nameof(ModCount)); | ||
} |
34 changes: 34 additions & 0 deletions
34
src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/Models/User.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
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; | ||
|
||
/// <summary> | ||
/// A user on Nexus Mods. | ||
/// </summary> | ||
public partial class User : IModelDefinition | ||
{ | ||
private const string Namespace = "NexusMods.Abstractions.NexusModsLibrary.User"; | ||
|
||
/// <summary> | ||
/// The user's username. | ||
/// </summary> | ||
public static readonly StringAttribute Name = new(Namespace, nameof(Name)) { IsIndexed = true }; | ||
|
||
/// <summary> | ||
/// The nexus id of the user. | ||
/// </summary> | ||
public static readonly ULongAttribute NexusId = new(Namespace, nameof(NexusId)) { IsIndexed = true }; | ||
|
||
/// <summary> | ||
/// The user's avatar URL. | ||
/// </summary> | ||
public static readonly UriAttribute Avatar = new(Namespace, nameof(Avatar)); | ||
|
||
/// <summary> | ||
/// The user's avatar image. | ||
/// </summary> | ||
public static readonly MemoryAttribute AvatarImage = new(Namespace, nameof(AvatarImage)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
28 changes: 0 additions & 28 deletions
28
src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/NexusModsCollectionMetadata.cs
This file was deleted.
Oops, something went wrong.
28 changes: 0 additions & 28 deletions
28
src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/NexusModsCollectionRevision.cs
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.