Game profile: IGDB platforms, IGDB link, sparse-profile fix
Build & Push / Lint & Build (push) Successful in 1m32s
Build & Push / Build & Push Image (push) Successful in 48s
Build & Push / Trigger Deploy (push) Successful in 2s

- Source platforms from IGDB first, fall back to Steam and
  detectables only when IGDB has none
- Add IGDB page button next to Steam, SteamDB, Discord and ITAD
- Hide the details box when a profile has no details instead
  of rendering it empty
- ITAD lookup matches titles ignoring punctuation and marks
This commit is contained in:
fristy committed 2026-09-11 06:21:54 +03:00
1 parent 66be7a71a7
commit cbbbc3effa
5 files changed
+25 -6

No files matched your search

+10
View File
@@ -322,6 +322,16 @@ export function GameProfileModal({
{dict.openOnSteamDb} ↗
</a>
) : null}
{profile?.igdbUrl ? (
<a
href={profile.igdbUrl}
target="_blank"
rel="noopener noreferrer"
className="rounded-full border border-white/15 px-4 py-1.5 text-xs text-zinc-300 transition-colors hover:border-blurple hover:text-white"
>
{dict.openOnIgdb} ↗
</a>
) : null}
<a
href={gameUrl}
target="_blank"
+12 -6
View File
@@ -59,6 +59,7 @@ export interface GameProfile {
screenshots: string[];
steamId: string | null;
steamUrl: string | null;
igdbUrl: string | null;
steamReviews: GameReviewSummary | null;
itad: {
prices: GamePricePoint | null;
@@ -197,6 +198,7 @@ async function getSteamReviewSummary(steamId: string): Promise<GameReviewSummary
interface IgdbGame {
name?: string;
slug?: string;
genres?: Array<{ name?: string }>;
summary?: string;
storyline?: string;
@@ -275,7 +277,7 @@ async function igdbQuery<T>(token: string, endpoint: string, body: string): Prom
}
const IGDB_GAME_FIELDS =
"name,genres.name,summary,storyline,cover.url,artworks.url,screenshots.url," +
"name,slug,genres.name,summary,storyline,cover.url,artworks.url,screenshots.url," +
"websites.url,websites.category,involved_companies.developer," +
"involved_companies.publisher,involved_companies.company.name," +
"platforms.abbreviation,platforms.name,first_release_date;";
@@ -491,19 +493,21 @@ export async function getGameProfile(
: (steam?.publishers ??
(itadInfo?.publishers?.map((d) => d.name).filter((n): n is string => !!n) || []));
const platforms = new Set<string>();
const igdbPlatforms = new Set<string>();
for (const p of igdb?.platforms ?? []) {
const label = `${p.abbreviation ?? ""} ${p.name ?? ""}`.toUpperCase();
if (/PS|PLAYSTATION/.test(label)) {
platforms.add("PlayStation");
igdbPlatforms.add("PlayStation");
} else if (/XBOX|XONE|XSX/.test(label)) {
platforms.add("Xbox");
igdbPlatforms.add("Xbox");
} else if (/PC|WIN|MAC|LIN/.test(label)) {
platforms.add("PC");
igdbPlatforms.add("PC");
} else if (/SWITCH/.test(label)) {
platforms.add("Switch");
igdbPlatforms.add("Switch");
}
}
const platforms = new Set<string>(igdbPlatforms);
if (platforms.size === 0) {
if (
steam?.platforms &&
(steam.platforms.windows || steam.platforms.mac || steam.platforms.linux)
@@ -516,6 +520,7 @@ export async function getGameProfile(
platforms.add(mapped);
}
}
}
const links: GameExternalLink[] = [];
for (const site of igdb?.websites ?? []) {
@@ -588,6 +593,7 @@ export async function getGameProfile(
screenshots,
steamId,
steamUrl: steamId ? `https://store.steampowered.com/app/${steamId}/` : null,
igdbUrl: igdb?.slug ? `https://www.igdb.com/games/${igdb.slug}` : null,
steamReviews,
itad:
process.env.ITAD_API_KEY && (itadInfo || priceEntry)
+1
View File
@@ -43,6 +43,7 @@
"openOnDiscord": "Discord-Profil",
"openOnSteam": "Steam",
"openOnSteamDb": "SteamDB",
"openOnIgdb": "IGDB",
"loading": "Spieldaten werden geladen...",
"loadError": "Spieldaten konnten nicht geladen werden.",
"screenshots": "Screenshots",
+1
View File
@@ -43,6 +43,7 @@
"openOnDiscord": "Discord Profile",
"openOnSteam": "Steam",
"openOnSteamDb": "SteamDB",
"openOnIgdb": "IGDB",
"loading": "Loading game info...",
"loadError": "Couldn't load game info.",
"screenshots": "Screenshots",
+1
View File
@@ -43,6 +43,7 @@
"openOnDiscord": "Discord Profili",
"openOnSteam": "Steam",
"openOnSteamDb": "SteamDB",
"openOnIgdb": "IGDB",
"loading": "Oyun bilgileri yükleniyor...",
"loadError": "Oyun bilgileri yüklenemedi.",
"screenshots": "Görseller",