From 3f238124428371c1caa9b1de2d6d71a6a75321bf Mon Sep 17 00:00:00 2001
From: Al <26797547+Al12rs@users.noreply.github.com>
Date: Thu, 26 Sep 2024 16:23:19 +0200
Subject: [PATCH 1/5] Various FlexPanel related layout fixes (#2088)
---
.../Collections/CollectionCardView.axaml | 4 +-
.../CollectionCardStyles.axaml | 47 ++++++++++---------
2 files changed, 27 insertions(+), 24 deletions(-)
diff --git a/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardView.axaml b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardView.axaml
index c27f98567d..8a0d157560 100644
--- a/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardView.axaml
+++ b/src/NexusMods.App.UI/Pages/LibraryPage/Collections/CollectionCardView.axaml
@@ -28,9 +28,9 @@
-
+
-
+
diff --git a/src/Themes/NexusMods.Themes.NexusFluentDark/Styles/UserControls/CollectionCards/CollectionCardStyles.axaml b/src/Themes/NexusMods.Themes.NexusFluentDark/Styles/UserControls/CollectionCards/CollectionCardStyles.axaml
index f81bb93feb..2d32f2af4b 100644
--- a/src/Themes/NexusMods.Themes.NexusFluentDark/Styles/UserControls/CollectionCards/CollectionCardStyles.axaml
+++ b/src/Themes/NexusMods.Themes.NexusFluentDark/Styles/UserControls/CollectionCards/CollectionCardStyles.axaml
@@ -42,14 +42,14 @@
-
-
+
+
From dedc86e021a6d317b9a363008d5960373ff4773e Mon Sep 17 00:00:00 2001
From: erri120
Date: Sat, 28 Sep 2024 14:55:47 +0200
Subject: [PATCH 2/5] Find GOG games installed with the Heroic launcher
Part of #1695. This only finds the games, we still need a way to run
them through the launcher.
---
Directory.Packages.props | 3 +-
.../HeroicGogLocator.cs | 53 +++++++++++++++++++
.../NexusMods.StandardGameLocators.csproj | 1 +
.../Services.cs | 3 ++
4 files changed, 59 insertions(+), 1 deletion(-)
create mode 100644 src/NexusMods.StandardGameLocators/HeroicGogLocator.cs
diff --git a/Directory.Packages.props b/Directory.Packages.props
index a9c14aa18c..08d9f4499e 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -6,6 +6,7 @@
+
@@ -120,7 +121,7 @@
-
+
diff --git a/src/NexusMods.StandardGameLocators/HeroicGogLocator.cs b/src/NexusMods.StandardGameLocators/HeroicGogLocator.cs
new file mode 100644
index 0000000000..9a9f5abbcb
--- /dev/null
+++ b/src/NexusMods.StandardGameLocators/HeroicGogLocator.cs
@@ -0,0 +1,53 @@
+using GameFinder.Launcher.Heroic;
+using GameFinder.StoreHandlers.GOG;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using NexusMods.Abstractions.GameLocators;
+using NexusMods.Abstractions.GameLocators.Stores.GOG;
+using NexusMods.Abstractions.Games.Stores.GOG;
+
+namespace NexusMods.StandardGameLocators;
+
+///
+/// Find GOG games installed with the Heroic launcher.
+///
+public class HeroicGogLocator : IGameLocator
+{
+ private readonly ILogger _logger;
+
+ private readonly HeroicGOGHandler _handler;
+ private IReadOnlyDictionary? _cachedGames;
+
+ ///
+ /// Constructor.
+ ///
+ public HeroicGogLocator(IServiceProvider provider)
+ {
+ _logger = provider.GetRequiredService>();
+ _handler = provider.GetRequiredService();
+ }
+
+ public IEnumerable Find(ILocatableGame game)
+ {
+ if (game is not IGogGame tg) yield break;
+
+ if (_cachedGames is null)
+ {
+ _cachedGames = _handler.FindAllGamesById(out var errors);
+ if (errors.Any())
+ {
+ foreach (var error in errors)
+ _logger.LogError("While looking for games: {Error}", error);
+ }
+ }
+
+ foreach (var id in tg.GogIds)
+ {
+ if (!_cachedGames.TryGetValue(GOGGameId.From(id), out var found)) continue;
+ yield return new GameLocatorResult(found.Path, GameStore.GOG, new GOGLocatorResultMetadata
+ {
+ Id = id,
+ });
+ }
+ }
+}
diff --git a/src/NexusMods.StandardGameLocators/NexusMods.StandardGameLocators.csproj b/src/NexusMods.StandardGameLocators/NexusMods.StandardGameLocators.csproj
index 27a773f608..853d0bf61a 100644
--- a/src/NexusMods.StandardGameLocators/NexusMods.StandardGameLocators.csproj
+++ b/src/NexusMods.StandardGameLocators/NexusMods.StandardGameLocators.csproj
@@ -4,6 +4,7 @@
+
diff --git a/src/NexusMods.StandardGameLocators/Services.cs b/src/NexusMods.StandardGameLocators/Services.cs
index 9c50d35589..b93cd89377 100644
--- a/src/NexusMods.StandardGameLocators/Services.cs
+++ b/src/NexusMods.StandardGameLocators/Services.cs
@@ -1,5 +1,6 @@
using System.Text.Json.Serialization;
using GameFinder.Common;
+using GameFinder.Launcher.Heroic;
using GameFinder.RegistryUtils;
using GameFinder.StoreHandlers.EADesktop;
using GameFinder.StoreHandlers.EADesktop.Crypto;
@@ -61,6 +62,7 @@ public static IServiceCollection AddStandardGameLocators(
onLinux: () =>
{
services.AddSingleton();
+ services.AddSingleton();
services.AddSingleton();
services.AddSingleton();
@@ -92,6 +94,7 @@ public static IServiceCollection AddStandardGameLocators(
onLinux: () =>
{
services.AddSingleton>(provider => new SteamHandler(provider.GetRequiredService(), registry: null));
+ services.AddSingleton(provider => new HeroicGOGHandler(provider.GetRequiredService()));
services.AddSingleton>(provider => new DefaultWinePrefixManager(provider.GetRequiredService()));
services.AddSingleton>(provider => new BottlesWinePrefixManager(provider.GetRequiredService()));
From d56347fadac052142928c71db076989016522f90 Mon Sep 17 00:00:00 2001
From: erri120
Date: Sat, 28 Sep 2024 15:08:32 +0200
Subject: [PATCH 3/5] Fix tests
---
tests/NexusMods.StandardGameLocators.TestHelpers/Services.cs | 3 +++
1 file changed, 3 insertions(+)
diff --git a/tests/NexusMods.StandardGameLocators.TestHelpers/Services.cs b/tests/NexusMods.StandardGameLocators.TestHelpers/Services.cs
index 73d4e62872..5b970ad346 100644
--- a/tests/NexusMods.StandardGameLocators.TestHelpers/Services.cs
+++ b/tests/NexusMods.StandardGameLocators.TestHelpers/Services.cs
@@ -1,4 +1,5 @@
using GameFinder.Common;
+using GameFinder.Launcher.Heroic;
using GameFinder.StoreHandlers.EADesktop;
using GameFinder.StoreHandlers.EGS;
using GameFinder.StoreHandlers.GOG;
@@ -75,6 +76,8 @@ public static IServiceCollection AddStubbedGameLocators(this IServiceCollection
if (OSInformation.Shared.IsLinux)
{
+ coll.AddSingleton(s => new HeroicGOGHandler(s.GetRequiredService()));
+
coll.AddSingleton>(s =>
new StubbedWinePrefixManager(s.GetRequiredService(),
tfm => new WinePrefix
From 0b1255444cee25212014eda1a76d21df6ddf74d4 Mon Sep 17 00:00:00 2001
From: erri120
Date: Sun, 29 Sep 2024 17:56:32 +0200
Subject: [PATCH 4/5] Run through heroic
---
.../Stores/GOG/GOGLocatorResultMetadata.cs | 3 +++
.../RunGameTool.cs | 23 ++++++++++++++++---
.../HeroicGogLocator.cs | 2 +-
3 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/src/Abstractions/NexusMods.Abstractions.GameLocators/Stores/GOG/GOGLocatorResultMetadata.cs b/src/Abstractions/NexusMods.Abstractions.GameLocators/Stores/GOG/GOGLocatorResultMetadata.cs
index d5cba47d39..1c471ca5cb 100644
--- a/src/Abstractions/NexusMods.Abstractions.GameLocators/Stores/GOG/GOGLocatorResultMetadata.cs
+++ b/src/Abstractions/NexusMods.Abstractions.GameLocators/Stores/GOG/GOGLocatorResultMetadata.cs
@@ -14,3 +14,6 @@ public record GOGLocatorResultMetadata : IGameLocatorResultMetadata
///
public required long Id { get; init; }
}
+
+[PublicAPI]
+public record HeroicGOGLocatorResultMetadata : GOGLocatorResultMetadata;
diff --git a/src/Abstractions/NexusMods.Abstractions.Games/RunGameTool.cs b/src/Abstractions/NexusMods.Abstractions.Games/RunGameTool.cs
index 39c9851350..1748a1835a 100644
--- a/src/Abstractions/NexusMods.Abstractions.Games/RunGameTool.cs
+++ b/src/Abstractions/NexusMods.Abstractions.Games/RunGameTool.cs
@@ -5,6 +5,7 @@
using Microsoft.Extensions.Logging;
using NexusMods.Abstractions.GameLocators;
using NexusMods.Abstractions.Games.DTO;
+using NexusMods.Abstractions.Games.Stores.GOG;
using NexusMods.Abstractions.Games.Stores.Steam;
using NexusMods.Abstractions.Loadouts;
using NexusMods.CrossPlatform.Process;
@@ -60,10 +61,18 @@ public async Task Execute(Loadout.ReadOnly loadout, CancellationToken cancellati
var program = await GetGamePath(loadout);
var primaryFile = _game.GetPrimaryFile(loadout.InstallationInstance.Store).CombineChecked(loadout.InstallationInstance);
- if (OSInformation.Shared.IsLinux && program.Equals(primaryFile) && loadout.InstallationInstance.LocatorResultMetadata is SteamLocatorResultMetadata steamLocatorResultMetadata)
+ if (OSInformation.Shared.IsLinux && program.Equals(primaryFile))
{
- await RunThroughSteam(steamLocatorResultMetadata.AppId, cancellationToken);
- return;
+ var locator = loadout.InstallationInstance.LocatorResultMetadata;
+ switch (locator)
+ {
+ case SteamLocatorResultMetadata steamLocatorResultMetadata:
+ await RunThroughSteam(steamLocatorResultMetadata.AppId, cancellationToken);
+ return;
+ case HeroicGOGLocatorResultMetadata heroicGOGLocatorResultMetadata:
+ await RunThroughHeroic("gog", heroicGOGLocatorResultMetadata.Id, cancellationToken);
+ return;
+ }
}
var names = new HashSet
@@ -177,6 +186,14 @@ private async Task RunThroughSteam(uint appId, CancellationToken cancellationTok
await reaper.WaitForExitAsync(cancellationToken);
}
+ private async Task RunThroughHeroic(string type, long appId, CancellationToken cancellationToken)
+ {
+ Debug.Assert(OSInformation.Shared.IsLinux);
+
+ // TODO: track process
+ await _osInterop.OpenUrl(new Uri($"heroic://launch/{type}/{appId.ToString(CultureInfo.InvariantCulture)}"), fireAndForget: true, cancellationToken: cancellationToken);
+ }
+
private async ValueTask WaitForProcessToStart(
string processName,
TimeSpan timeout,
diff --git a/src/NexusMods.StandardGameLocators/HeroicGogLocator.cs b/src/NexusMods.StandardGameLocators/HeroicGogLocator.cs
index 9a9f5abbcb..e7e80b1947 100644
--- a/src/NexusMods.StandardGameLocators/HeroicGogLocator.cs
+++ b/src/NexusMods.StandardGameLocators/HeroicGogLocator.cs
@@ -44,7 +44,7 @@ public IEnumerable Find(ILocatableGame game)
foreach (var id in tg.GogIds)
{
if (!_cachedGames.TryGetValue(GOGGameId.From(id), out var found)) continue;
- yield return new GameLocatorResult(found.Path, GameStore.GOG, new GOGLocatorResultMetadata
+ yield return new GameLocatorResult(found.Path, GameStore.GOG, new HeroicGOGLocatorResultMetadata
{
Id = id,
});
From b7ab9933382b6a158b57331c9062dc643ee9071e Mon Sep 17 00:00:00 2001
From: Timothy Baldridge
Date: Mon, 30 Sep 2024 06:40:25 -0600
Subject: [PATCH 5/5] Switch GraphQL calls to fragments (#2102)
* Switch GraphQL calls to fragments
* Re-add missing GQL file
---
.../GraphQLResolver.cs | 6 +-
.../Extensions/FragmentExtensions.cs | 70 +++++++++++++++++++
.../GraphQL/CollectionRevisionInfo.graphql | 19 ++---
.../GraphQL/CommonFragments.graphql | 24 +++++++
.../GraphQL/ModInfo.graphql | 12 ++++
.../NexusModsLibrary.cs | 63 ++++-------------
6 files changed, 127 insertions(+), 67 deletions(-)
create mode 100644 src/Networking/NexusMods.Networking.NexusWebApi/Extensions/FragmentExtensions.cs
create mode 100644 src/Networking/NexusMods.Networking.NexusWebApi/GraphQL/CommonFragments.graphql
create mode 100644 src/Networking/NexusMods.Networking.NexusWebApi/GraphQL/ModInfo.graphql
diff --git a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/GraphQLResolver.cs b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/GraphQLResolver.cs
index 053b2cba0f..e278def657 100644
--- a/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/GraphQLResolver.cs
+++ b/src/Abstractions/NexusMods.Abstractions.NexusModsLibrary/GraphQLResolver.cs
@@ -20,14 +20,14 @@ 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
+ public static GraphQLResolver Create(IDb db, ITransaction tx, ScalarAttribute primaryKeyAttribute, THighLevel primaryKeyValue) where THighLevel : notnull
{
- var existing = referenceDb.Datoms(primaryKeyAttribute, primaryKeyValue);
+ var existing = db.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));
+ return new GraphQLResolver(tx, new ReadOnlyModel(db, id));
}
///
diff --git a/src/Networking/NexusMods.Networking.NexusWebApi/Extensions/FragmentExtensions.cs b/src/Networking/NexusMods.Networking.NexusWebApi/Extensions/FragmentExtensions.cs
new file mode 100644
index 0000000000..4151a111e1
--- /dev/null
+++ b/src/Networking/NexusMods.Networking.NexusWebApi/Extensions/FragmentExtensions.cs
@@ -0,0 +1,70 @@
+using NexusMods.Abstractions.Games.DTO;
+using NexusMods.Abstractions.NexusModsLibrary;
+using NexusMods.Abstractions.NexusModsLibrary.Models;
+using NexusMods.Abstractions.NexusWebApi.Types;
+using NexusMods.MnemonicDB.Abstractions;
+using NexusMods.Paths;
+
+namespace NexusMods.Networking.NexusWebApi.Extensions;
+
+///
+/// Extensions to GraphQL fragments.
+///
+public static class FragmentExtensions
+{
+ ///
+ /// Resolves the IUserFragment to an entity in the database, inserting or updating as necessary.
+ ///
+ public static async Task Resolve(this IUserFragment userFragment, IDb db, ITransaction tx, HttpClient client, CancellationToken token)
+ {
+ var userResolver = GraphQLResolver.Create(db, tx, User.NexusId, (ulong)userFragment.MemberId);
+ userResolver.Add(User.Name, userFragment.Name);
+ userResolver.Add(User.Avatar, new Uri(userFragment.Avatar));
+
+ var avatarImage = await DownloadImage(client, userFragment.Avatar, token);
+ userResolver.Add(User.AvatarImage,avatarImage);
+ return userResolver.Id;
+ }
+
+ ///
+ /// Resolves the IModFragment to an entity in the database, inserting or updating as necessary.
+ ///
+ public static EntityId Resolve(this IModFileFragment modFileFragment, IDb db, ITransaction tx, EntityId modEId)
+ {
+ var nexusFileResolver = GraphQLResolver.Create(db, tx, (NexusModsFileMetadata.FileId, FileId.From((ulong)modFileFragment.FileId)), (NexusModsFileMetadata.ModPageId, modEId));
+ nexusFileResolver.Add(NexusModsFileMetadata.ModPageId, modEId);
+ nexusFileResolver.Add(NexusModsFileMetadata.Name, modFileFragment.Name);
+ nexusFileResolver.Add(NexusModsFileMetadata.Version, modFileFragment.Version);
+ if (ulong.TryParse(modFileFragment.SizeInBytes, out var size))
+ nexusFileResolver.Add(NexusModsFileMetadata.Size, Size.From(size));
+ return nexusFileResolver.Id;
+ }
+
+ ///
+ /// Resolves the IModFragment to an entity in the database, inserting or updating as necessary.
+ ///
+ public static EntityId Resolve(this IModFragment modFragment, IDb db, ITransaction tx)
+ {
+ var nexusModResolver = GraphQLResolver.Create(db, tx, NexusModsModPageMetadata.ModId,
+ ModId.From((ulong)modFragment.ModId));
+
+ nexusModResolver.Add(NexusModsModPageMetadata.Name, modFragment.Name);
+ nexusModResolver.Add(NexusModsModPageMetadata.GameDomain, GameDomain.From(modFragment.Game.DomainName));
+
+ if (Uri.TryCreate(modFragment.PictureUrl, UriKind.Absolute, out var fullSizedPictureUri))
+ nexusModResolver.Add(NexusModsModPageMetadata.FullSizedPictureUri, fullSizedPictureUri);
+
+ if (Uri.TryCreate(modFragment.ThumbnailUrl, UriKind.Absolute, out var thumbnailUri))
+ nexusModResolver.Add(NexusModsModPageMetadata.ThumbnailUri, thumbnailUri);
+ return nexusModResolver.Id;
+ }
+
+ private static async Task DownloadImage(HttpClient client, string? uri, CancellationToken token)
+ {
+ if (uri is null) return [];
+ if (!Uri.TryCreate(uri, UriKind.Absolute, out var imageUri)) return [];
+
+ return await client.GetByteArrayAsync(imageUri, token);
+ }
+
+}
diff --git a/src/Networking/NexusMods.Networking.NexusWebApi/GraphQL/CollectionRevisionInfo.graphql b/src/Networking/NexusMods.Networking.NexusWebApi/GraphQL/CollectionRevisionInfo.graphql
index 8473b39dda..efea25fd58 100644
--- a/src/Networking/NexusMods.Networking.NexusWebApi/GraphQL/CollectionRevisionInfo.graphql
+++ b/src/Networking/NexusMods.Networking.NexusWebApi/GraphQL/CollectionRevisionInfo.graphql
@@ -1,3 +1,4 @@
+#import { UserFragment, ModFragment, ModFileFragment } from './CommonFragments.graphql';
# Pulls all the information we need about a collection revision.
query CollectionRevisionInfo($slug: String!, $revisionNumber: Int!, $viewAdultContent: Boolean!)
@@ -20,18 +21,9 @@ query CollectionRevisionInfo($slug: String!, $revisionNumber: Int!, $viewAdultCo
gameId,
fileId,
file {
- name,
- modId,
- fileId,
- version,
- sizeInBytes,
+ ...ModFileFragment
mod {
- name
- game {
- domainName
- }
- thumbnailUrl
- pictureUrl
+ ...ModFragment
}
}
updatePolicy,
@@ -53,11 +45,8 @@ query CollectionRevisionInfo($slug: String!, $revisionNumber: Int!, $viewAdultCo
id
}
user {
- name
- avatar
- memberId
+ ...UserFragment
}
-
}
}
}
diff --git a/src/Networking/NexusMods.Networking.NexusWebApi/GraphQL/CommonFragments.graphql b/src/Networking/NexusMods.Networking.NexusWebApi/GraphQL/CommonFragments.graphql
new file mode 100644
index 0000000000..f27b5fada4
--- /dev/null
+++ b/src/Networking/NexusMods.Networking.NexusWebApi/GraphQL/CommonFragments.graphql
@@ -0,0 +1,24 @@
+
+fragment UserFragment on User {
+ name
+ avatar
+ memberId
+}
+
+fragment ModFileFragment on ModFile {
+ name,
+ modId,
+ fileId,
+ version,
+ sizeInBytes
+}
+
+fragment ModFragment on Mod {
+ modId
+ name
+ game {
+ domainName
+ }
+ thumbnailUrl
+ pictureUrl
+}
diff --git a/src/Networking/NexusMods.Networking.NexusWebApi/GraphQL/ModInfo.graphql b/src/Networking/NexusMods.Networking.NexusWebApi/GraphQL/ModInfo.graphql
new file mode 100644
index 0000000000..894a14b68c
--- /dev/null
+++ b/src/Networking/NexusMods.Networking.NexusWebApi/GraphQL/ModInfo.graphql
@@ -0,0 +1,12 @@
+#include { ModFragment } from './CommonFragments.graphql'
+
+query ModInfo($gameDomain: String!, $modId: Int!)
+{
+ legacyModsByDomain(ids: [{gameDomain: $gameDomain, modId: $modId}])
+ {
+ nodes
+ {
+ ...ModFragment
+ }
+ }
+}
diff --git a/src/Networking/NexusMods.Networking.NexusWebApi/NexusModsLibrary.cs b/src/Networking/NexusMods.Networking.NexusWebApi/NexusModsLibrary.cs
index 08880a2093..e378abe252 100644
--- a/src/Networking/NexusMods.Networking.NexusWebApi/NexusModsLibrary.cs
+++ b/src/Networking/NexusMods.Networking.NexusWebApi/NexusModsLibrary.cs
@@ -12,6 +12,7 @@
using NexusMods.Extensions.BCL;
using NexusMods.MnemonicDB.Abstractions;
using NexusMods.Networking.HttpDownloader;
+using NexusMods.Networking.NexusWebApi.Extensions;
using NexusMods.Paths;
using User = NexusMods.Abstractions.NexusModsLibrary.Models.User;
@@ -48,28 +49,15 @@ public NexusModsLibrary(IServiceProvider serviceProvider)
using var tx = _connection.BeginTransaction();
- var modInfo = await _apiClient.ModInfoAsync(gameDomain.ToString(), modId, cancellationToken);
-
- var newModPage = new NexusModsModPageMetadata.New(tx)
- {
- Name = modInfo.Data.Name,
- ModId = modId,
- GameDomain = gameDomain,
- };
-
- if (Uri.TryCreate(modInfo.Data.PictureUrl, UriKind.Absolute, out var fullSizedPictureUri))
+ var modInfo = await _gqlClient.ModInfo.ExecuteAsync(gameDomain.ToString(), (int)modId.Value, cancellationToken);
+ EntityId first = default;
+ foreach (var node in modInfo.Data!.LegacyModsByDomain.Nodes)
{
- newModPage.FullSizedPictureUri = fullSizedPictureUri;
-
- var thumbnailUrl = modInfo.Data.PictureUrl.Replace("/images/", "/images/thumbnails/", StringComparison.OrdinalIgnoreCase);
- if (Uri.TryCreate(thumbnailUrl, UriKind.Absolute, out var thumbnailUri))
- {
- newModPage.ThumbnailUri = thumbnailUri;
- }
+ first = node.Resolve(_connection.Db, tx);
}
-
+
var txResults = await tx.Commit();
- return txResults.Remap(newModPage);
+ return NexusModsModPageMetadata.Load(txResults.Db, txResults[first]);
}
///
@@ -88,7 +76,6 @@ public NexusModsLibrary(IServiceProvider serviceProvider)
var db = _connection.Db;
var collectionInfo = info.Data!.CollectionRevision.Collection;
var collectionTileImage = DownloadImage(collectionInfo.TileImage?.ThumbnailUrl, token);
- var avatarImage = DownloadImage(collectionInfo.User.Avatar, token);
var collectionBackgroundImage = DownloadImage(collectionInfo.HeaderImage?.Url, token);
// Remap the collection info
@@ -99,13 +86,8 @@ public NexusModsLibrary(IServiceProvider serviceProvider)
collectionResolver.Add(CollectionMetadata.TileImage, await collectionTileImage);
collectionResolver.Add(CollectionMetadata.BackgroundImage, await collectionBackgroundImage);
- // 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(CollectionMetadata.Author, userResolver.Id);
+ var user = await collectionInfo.User.Resolve(db, tx, _httpClient, token);
+ collectionResolver.Add(CollectionMetadata.Author, user);
// Remap the revision info
var revisionInfo = info.Data!.CollectionRevision;
@@ -121,38 +103,21 @@ public NexusModsLibrary(IServiceProvider serviceProvider)
foreach (var file in revisionInfo.ModFiles)
{
var fileInfo = file.File!;
- var modInfo = fileInfo.Mod;
- var nexusModResolver = GraphQLResolver.Create(db, tx, NexusModsModPageMetadata.ModId, ModId.From((ulong)fileInfo.ModId));
- nexusModResolver.Add(NexusModsModPageMetadata.Name, modInfo.Name);
- nexusModResolver.Add(NexusModsModPageMetadata.GameDomain, GameDomain.From(modInfo.Game.DomainName));
- if (Uri.TryCreate(modInfo.PictureUrl, UriKind.Absolute, out var fullSizedPictureUri))
- nexusModResolver.Add(NexusModsModPageMetadata.FullSizedPictureUri, fullSizedPictureUri);
-
- if (Uri.TryCreate(modInfo.ThumbnailUrl, UriKind.Absolute, out var thumbnailUri))
- nexusModResolver.Add(NexusModsModPageMetadata.ThumbnailUri, thumbnailUri);
-
-
- var nexusFileResolver = GraphQLResolver.Create(db, tx, (NexusModsFileMetadata.FileId, FileId.From((ulong)fileInfo.FileId)), (NexusModsFileMetadata.ModPageId, nexusModResolver.Id));
- nexusFileResolver.Add(NexusModsFileMetadata.ModPageId, nexusModResolver.Id);
- nexusFileResolver.Add(NexusModsFileMetadata.Name, fileInfo.Name);
- nexusFileResolver.Add(NexusModsFileMetadata.Version, fileInfo.Version);
- nexusFileResolver.Add(NexusModsFileMetadata.Size, Size.FromLong(long.Parse(fileInfo.SizeInBytes!)));
+ var modEId = fileInfo.Mod.Resolve(db, tx);
+ var modfile = fileInfo.Resolve(db, tx, modEId);
var revisionFileResolver = GraphQLResolver.Create(db, tx, CollectionRevisionModFile.FileId, ulong.Parse(file.Id));
revisionFileResolver.Add(CollectionRevisionModFile.CollectionRevision, revisionResolver.Id);
- revisionFileResolver.Add(CollectionRevisionModFile.NexusModFile, nexusFileResolver.Id);
+ revisionFileResolver.Add(CollectionRevisionModFile.NexusModFile, modfile);
revisionFileResolver.Add(CollectionRevisionModFile.IsOptional, file.Optional);
}
var txResults = await tx.Commit();
return CollectionRevisionMetadata.Load(txResults.Db, txResults[revisionResolver.Id]);
}
-
- ///
- /// Load an image from a URI
- ///
- public async Task DownloadImage(string? uri, CancellationToken token)
+
+ private async Task DownloadImage(string? uri, CancellationToken token)
{
if (uri is null) return [];
if (!Uri.TryCreate(uri, UriKind.Absolute, out var imageUri)) return [];