diff --git a/components/game-profile-modal.tsx b/components/game-profile-modal.tsx
index 7100f89..b7f7bd8 100644
--- a/components/game-profile-modal.tsx
+++ b/components/game-profile-modal.tsx
@@ -161,6 +161,7 @@ export function GameProfileModal({
const name = profile?.name ?? fallbackName;
const best = profile?.itad?.prices ?? null;
const low = profile?.itad?.historyLow ?? null;
+ const isFree = !!best && best.price === 0;
const hero = useMemo(() => {
if (bannerPick) {
return bannerPick;
@@ -539,38 +540,44 @@ export function GameProfileModal({
{dict.prices}
-
+ {isFree ? (
+
+ {dict.free}
+
+ ) : (
+
+ )}
) : null}
diff --git a/lib/game-profile.ts b/lib/game-profile.ts
index c39c25d..53b9ab3 100644
--- a/lib/game-profile.ts
+++ b/lib/game-profile.ts
@@ -88,9 +88,7 @@ async function getDetectables(): Promise {
return detectablesCache.data;
}
try {
- const response = await fetch("https://cdn.discordapp.com/detectables/games-v1.json", {
- next: { revalidate: 86_400 },
- });
+ const response = await fetch("https://cdn.discordapp.com/detectables/games-v1.json");
if (!response.ok) {
console.error(`detectables failed: ${response.status}`);
return detectablesCache?.data ?? [];
@@ -104,10 +102,6 @@ async function getDetectables(): Promise {
}
const DISTRIBUTOR_PLATFORM: Record = {
- steam: "PC",
- battlenet: "PC",
- gog: "PC",
- epic: "PC",
xbox: "Xbox",
xbox_title: "Xbox",
xbox_game_pass: "Xbox",
@@ -220,10 +214,16 @@ interface IgdbGame {
let igdbTokenCache: { token: string; expires: number } | null = null;
+let igdbKeyWarned = false;
+
async function getIgdbToken(): Promise {
const clientId = process.env.TWITCH_CLIENT_ID;
const clientSecret = process.env.TWITCH_CLIENT_SECRET;
if (!clientId || !clientSecret) {
+ if (!igdbKeyWarned) {
+ igdbKeyWarned = true;
+ console.error("igdb keys missing: set TWITCH_CLIENT_ID and TWITCH_CLIENT_SECRET");
+ }
return null;
}
if (igdbTokenCache && Date.now() < igdbTokenCache.expires) {
@@ -386,9 +386,15 @@ interface ItadOverviewPrice {
} | null;
}
+let itadKeyWarned = false;
+
async function itadFetch(path: string, init?: RequestInit): Promise {
const key = process.env.ITAD_API_KEY;
if (!key) {
+ if (!itadKeyWarned) {
+ itadKeyWarned = true;
+ console.error("itad key missing: set ITAD_API_KEY");
+ }
return null;
}
try {
@@ -499,24 +505,28 @@ export async function getGameProfile(
const igdbPlatforms = new Set();
for (const p of igdb?.platforms ?? []) {
- const label = `${p.abbreviation ?? ""} ${p.name ?? ""}`.toUpperCase();
- if (/PS|PLAYSTATION/.test(label)) {
- igdbPlatforms.add("PlayStation");
- } else if (/XBOX|XONE|XSX/.test(label)) {
- igdbPlatforms.add("Xbox");
- } else if (/PC|WIN|MAC|LIN/.test(label)) {
- igdbPlatforms.add("PC");
- } else if (/SWITCH/.test(label)) {
- igdbPlatforms.add("Switch");
+ const raw = (p.name ?? "").trim();
+ if (!raw) {
+ continue;
+ }
+ if (raw === "PC (Microsoft Windows)") {
+ igdbPlatforms.add("Windows");
+ } else if (raw === "Mac") {
+ igdbPlatforms.add("MacOS");
+ } else {
+ igdbPlatforms.add(raw);
}
}
const platforms = new Set(igdbPlatforms);
- if (platforms.size === 0) {
- if (
- steam?.platforms &&
- (steam.platforms.windows || steam.platforms.mac || steam.platforms.linux)
- ) {
- platforms.add("PC");
+ if (platforms.size === 0 && steam?.platforms) {
+ if (steam.platforms.windows) {
+ platforms.add("Windows");
+ }
+ if (steam.platforms.mac) {
+ platforms.add("MacOS");
+ }
+ if (steam.platforms.linux) {
+ platforms.add("Linux");
}
for (const sku of entry?.third_party_skus ?? []) {
const mapped = DISTRIBUTOR_PLATFORM[sku.distributor];
diff --git a/lib/i18n/dictionaries/de.json b/lib/i18n/dictionaries/de.json
index 74d9c50..c70cd21 100644
--- a/lib/i18n/dictionaries/de.json
+++ b/lib/i18n/dictionaries/de.json
@@ -37,6 +37,7 @@
"links": "Links",
"reviews": "Bewertungen",
"prices": "Preise",
+ "free": "Kostenlos",
"bestPrice": "Bester Preis",
"historyLow": "Historischer Tiefstpreis",
"allPrices": "ITAD",
diff --git a/lib/i18n/dictionaries/en.json b/lib/i18n/dictionaries/en.json
index c29bc89..906dff1 100644
--- a/lib/i18n/dictionaries/en.json
+++ b/lib/i18n/dictionaries/en.json
@@ -37,6 +37,7 @@
"links": "Links",
"reviews": "Reviews",
"prices": "Prices",
+ "free": "Free",
"bestPrice": "Best Price",
"historyLow": "All-Time Low",
"allPrices": "ITAD",
diff --git a/lib/i18n/dictionaries/tr.json b/lib/i18n/dictionaries/tr.json
index 7840c4e..0a4ec08 100644
--- a/lib/i18n/dictionaries/tr.json
+++ b/lib/i18n/dictionaries/tr.json
@@ -37,6 +37,7 @@
"links": "Bağlantılar",
"reviews": "İncelemeler",
"prices": "Fiyatlar",
+ "free": "Ücretsiz",
"bestPrice": "En İyi Fiyat",
"historyLow": "Tarihi En Düşük",
"allPrices": "ITAD",