Skip to content

Commit 69a2c7a

Browse files
Fetch full game data and improve cards
For search results, fetch full game JSON for the first 60 matches (using Promise.all) and gracefully handle fetch failures by falling back to partial data. Normalize IGDB cover URLs to use a larger cover size (t_cover_big) and ensure absolute URLs, increase cover/placeholder height from 180px to 240px, and improve name layout with two-line clamping and bolder text. Also keep the same behavior when platform data can't be loaded by still fetching game details.
1 parent a6bdc51 commit 69a2c7a

1 file changed

Lines changed: 169 additions & 128 deletions

File tree

gh-pages-template/assets/js/item_loader.js

Lines changed: 169 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -384,146 +384,187 @@ function run_search() {
384384
fetch(`${base_url}/platforms/all.json`)
385385
.then(r => r.json())
386386
.then(allPlatforms => {
387-
matches.slice(0, 60).forEach(([id, game]) => {
388-
const col = document.createElement("div")
389-
col.className = "col"
390-
row.appendChild(col)
391-
392-
const card = document.createElement("a")
393-
card.className = "card h-100 text-decoration-none shadow-sm border-0 rounded-0"
394-
card.href = `${base_path}/browse/games/?id=${id}`
395-
col.appendChild(card)
396-
397-
// Cover image or placeholder
398-
if (game.cover && game.cover.url) {
399-
const coverImg = document.createElement("img")
400-
coverImg.className = "card-img-top rounded-top-0"
401-
coverImg.src = game.cover.url.replace("t_thumb", "t_cover_small")
402-
coverImg.alt = game.name
403-
coverImg.loading = "lazy"
404-
coverImg.style.height = "180px"
405-
coverImg.style.objectFit = "cover"
406-
card.appendChild(coverImg)
407-
} else {
408-
const placeholder = document.createElement("div")
409-
placeholder.className = "card-img-top bg-secondary d-flex align-items-center justify-content-center"
410-
placeholder.style.height = "180px"
411-
const icon = document.createElement("span")
412-
icon.className = "material-symbols-outlined text-white"
413-
icon.style.fontSize = "3rem"
414-
icon.textContent = "sports_esports"
415-
placeholder.appendChild(icon)
416-
card.appendChild(placeholder)
417-
}
387+
// Fetch full game data for each match
388+
const gamePromises = matches.slice(0, 60).map(([id, _game]) =>
389+
fetch(`${base_url}/games/${id}.json`)
390+
.then(r => r.ok ? r.json() : null)
391+
.then(fullGame => ({ id, game: fullGame || { name: _game.name } }))
392+
.catch(() => ({ id, game: { name: _game.name } }))
393+
)
394+
395+
Promise.all(gamePromises).then(results => {
396+
results.forEach(({ id, game }) => {
397+
const col = document.createElement("div")
398+
col.className = "col"
399+
col.style.maxWidth = "180px"
400+
row.appendChild(col)
401+
402+
const card = document.createElement("a")
403+
card.className = "card h-100 text-decoration-none shadow-sm border-0 rounded-0"
404+
card.href = `${base_path}/browse/games/?id=${id}`
405+
col.appendChild(card)
406+
407+
// Cover image or placeholder
408+
if (game.cover && game.cover.url) {
409+
const coverImg = document.createElement("img")
410+
coverImg.className = "card-img-top rounded-top-0"
411+
// Convert IGDB URL properly - URLs start with //
412+
let coverUrl = game.cover.url
413+
coverUrl = 'https:' + coverUrl.replace('t_thumb', 't_cover_big')
414+
coverImg.src = coverUrl
415+
coverImg.alt = game.name
416+
coverImg.loading = "lazy"
417+
coverImg.style.width = "100%"
418+
coverImg.style.aspectRatio = "3 / 4"
419+
coverImg.style.objectFit = "cover"
420+
card.appendChild(coverImg)
421+
} else {
422+
const placeholder = document.createElement("div")
423+
placeholder.className = "card-img-top bg-secondary d-flex align-items-center justify-content-center"
424+
placeholder.style.width = "100%"
425+
placeholder.style.aspectRatio = "3 / 4"
426+
const icon = document.createElement("span")
427+
icon.className = "material-symbols-outlined text-white"
428+
icon.style.fontSize = "3rem"
429+
icon.textContent = "sports_esports"
430+
placeholder.appendChild(icon)
431+
card.appendChild(placeholder)
432+
}
418433

419-
const cardBody = document.createElement("div")
420-
cardBody.className = "card-body p-2"
421-
card.appendChild(cardBody)
422-
423-
// Game name
424-
const nameEl = document.createElement("h6")
425-
nameEl.className = "card-title small mb-2 fw-bold text-truncate"
426-
nameEl.textContent = game.name
427-
nameEl.title = game.name
428-
cardBody.appendChild(nameEl)
429-
430-
// Platforms with release years
431-
if (game.platforms && game.platforms.length > 0) {
432-
const platformsDiv = document.createElement("div")
433-
platformsDiv.className = "mb-2"
434-
435-
// Group release dates by platform
436-
const platformYears = {}
437-
if (game.release_dates && game.release_dates.length > 0) {
438-
game.release_dates.forEach(rd => {
439-
if (rd.platform && rd.y) {
440-
if (!platformYears[rd.platform] || rd.y < platformYears[rd.platform]) {
441-
platformYears[rd.platform] = rd.y
434+
const cardBody = document.createElement("div")
435+
cardBody.className = "card-body p-2"
436+
card.appendChild(cardBody)
437+
438+
// Game name
439+
const nameEl = document.createElement("h6")
440+
nameEl.className = "card-title small mb-2 fw-bold"
441+
nameEl.textContent = game.name
442+
nameEl.title = game.name
443+
nameEl.style.overflow = "hidden"
444+
nameEl.style.display = "-webkit-box"
445+
nameEl.style.webkitLineClamp = "2"
446+
nameEl.style.webkitBoxOrient = "vertical"
447+
cardBody.appendChild(nameEl)
448+
449+
// Platforms with release years
450+
if (game.platforms && game.platforms.length > 0) {
451+
const platformsDiv = document.createElement("div")
452+
platformsDiv.className = "mb-2"
453+
454+
// Group release dates by platform
455+
const platformYears = {}
456+
if (game.release_dates && game.release_dates.length > 0) {
457+
game.release_dates.forEach(rd => {
458+
if (rd.platform && rd.y) {
459+
if (!platformYears[rd.platform] || rd.y < platformYears[rd.platform]) {
460+
platformYears[rd.platform] = rd.y
461+
}
442462
}
443-
}
463+
})
464+
}
465+
466+
// Show first 3 platforms
467+
game.platforms.slice(0, 3).forEach(platformId => {
468+
const platform = allPlatforms[String(platformId)]
469+
const platformName = platform ? platform.name : `Platform ${platformId}`
470+
const year = platformYears[platformId] ? ` (${platformYears[platformId]})` : ""
471+
472+
const badge = document.createElement("span")
473+
badge.className = "badge bg-secondary me-1 mb-1 small"
474+
badge.style.fontSize = "0.7rem"
475+
badge.textContent = platformName + year
476+
platformsDiv.appendChild(badge)
444477
})
445-
}
446478

447-
// Show first 3 platforms
448-
game.platforms.slice(0, 3).forEach(platformId => {
449-
const platform = allPlatforms[String(platformId)]
450-
const platformName = platform ? platform.name : `Platform ${platformId}`
451-
const year = platformYears[platformId] ? ` (${platformYears[platformId]})` : ""
452-
453-
const badge = document.createElement("span")
454-
badge.className = "badge bg-secondary me-1 mb-1 small"
455-
badge.style.fontSize = "0.7rem"
456-
badge.textContent = platformName + year
457-
platformsDiv.appendChild(badge)
458-
})
459-
460-
if (game.platforms.length > 3) {
461-
const moreBadge = document.createElement("span")
462-
moreBadge.className = "badge bg-secondary me-1 mb-1 small"
463-
moreBadge.style.fontSize = "0.7rem"
464-
moreBadge.textContent = `+${game.platforms.length - 3} more`
465-
platformsDiv.appendChild(moreBadge)
479+
if (game.platforms.length > 3) {
480+
const moreBadge = document.createElement("span")
481+
moreBadge.className = "badge bg-secondary me-1 mb-1 small"
482+
moreBadge.style.fontSize = "0.7rem"
483+
moreBadge.textContent = `+${game.platforms.length - 3} more`
484+
platformsDiv.appendChild(moreBadge)
485+
}
486+
487+
cardBody.appendChild(platformsDiv)
466488
}
489+
})
467490

468-
cardBody.appendChild(platformsDiv)
491+
if (matches.length > 60) {
492+
const moreNote = document.createElement("p")
493+
moreNote.className = "text-muted mt-3 small"
494+
moreNote.textContent = `Showing first 60 of ${matches.length} results. Try a more specific search term.`
495+
search_container.appendChild(moreNote)
469496
}
470497
})
471-
472-
if (matches.length > 60) {
473-
const moreNote = document.createElement("p")
474-
moreNote.className = "text-muted mt-3 small"
475-
moreNote.textContent = `Showing first 60 of ${matches.length} results. Try a more specific search term.`
476-
search_container.appendChild(moreNote)
477-
}
478498
})
479499
.catch(() => {
480-
// Fallback if platforms can't be loaded
481-
matches.slice(0, 60).forEach(([id, game]) => {
482-
const col = document.createElement("div")
483-
col.className = "col"
484-
row.appendChild(col)
485-
486-
const card = document.createElement("a")
487-
card.className = "card h-100 text-decoration-none shadow-sm border-0 rounded-0"
488-
card.href = `${base_path}/browse/games/?id=${id}`
489-
col.appendChild(card)
490-
491-
if (game.cover && game.cover.url) {
492-
const coverImg = document.createElement("img")
493-
coverImg.className = "card-img-top rounded-top-0"
494-
coverImg.src = game.cover.url.replace("t_thumb", "t_cover_small")
495-
coverImg.alt = game.name
496-
coverImg.loading = "lazy"
497-
card.appendChild(coverImg)
498-
} else {
499-
const placeholder = document.createElement("div")
500-
placeholder.className = "card-img-top bg-secondary d-flex align-items-center justify-content-center"
501-
placeholder.style.height = "180px"
502-
const icon = document.createElement("span")
503-
icon.className = "material-symbols-outlined text-white"
504-
icon.style.fontSize = "3rem"
505-
icon.textContent = "sports_esports"
506-
placeholder.appendChild(icon)
507-
card.appendChild(placeholder)
508-
}
509-
510-
const cardBody = document.createElement("div")
511-
cardBody.className = "card-body p-2"
512-
card.appendChild(cardBody)
500+
// Fallback if platforms can't be loaded - still fetch game data
501+
const gamePromises = matches.slice(0, 60).map(([id, _game]) =>
502+
fetch(`${base_url}/games/${id}.json`)
503+
.then(r => r.ok ? r.json() : null)
504+
.then(fullGame => ({ id, game: fullGame || { name: _game.name } }))
505+
.catch(() => ({ id, game: { name: _game.name } }))
506+
)
507+
508+
Promise.all(gamePromises).then(results => {
509+
results.forEach(({ id, game }) => {
510+
const col = document.createElement("div")
511+
col.className = "col"
512+
col.style.maxWidth = "180px"
513+
row.appendChild(col)
514+
515+
const card = document.createElement("a")
516+
card.className = "card h-100 text-decoration-none shadow-sm border-0 rounded-0"
517+
card.href = `${base_path}/browse/games/?id=${id}`
518+
col.appendChild(card)
519+
520+
if (game.cover && game.cover.url) {
521+
const coverImg = document.createElement("img")
522+
coverImg.className = "card-img-top rounded-top-0"
523+
// Convert IGDB URL properly - URLs start with //
524+
let coverUrl = game.cover.url
525+
coverUrl = 'https:' + coverUrl.replace('t_thumb', 't_cover_big')
526+
coverImg.src = coverUrl
527+
coverImg.alt = game.name
528+
coverImg.loading = "lazy"
529+
coverImg.style.width = "100%"
530+
coverImg.style.aspectRatio = "3 / 4"
531+
coverImg.style.objectFit = "cover"
532+
card.appendChild(coverImg)
533+
} else {
534+
const placeholder = document.createElement("div")
535+
placeholder.className = "card-img-top bg-secondary d-flex align-items-center justify-content-center"
536+
placeholder.style.width = "100%"
537+
placeholder.style.aspectRatio = "3 / 4"
538+
const icon = document.createElement("span")
539+
icon.className = "material-symbols-outlined text-white"
540+
icon.style.fontSize = "3rem"
541+
icon.textContent = "sports_esports"
542+
placeholder.appendChild(icon)
543+
card.appendChild(placeholder)
544+
}
513545

514-
const nameEl = document.createElement("p")
515-
nameEl.className = "card-text small mb-0"
516-
nameEl.textContent = game.name
517-
nameEl.title = game.name
518-
cardBody.appendChild(nameEl)
546+
const cardBody = document.createElement("div")
547+
cardBody.className = "card-body p-2"
548+
card.appendChild(cardBody)
549+
550+
const nameEl = document.createElement("p")
551+
nameEl.className = "card-text small mb-0 fw-bold"
552+
nameEl.textContent = game.name
553+
nameEl.title = game.name
554+
nameEl.style.overflow = "hidden"
555+
nameEl.style.display = "-webkit-box"
556+
nameEl.style.webkitLineClamp = "2"
557+
nameEl.style.webkitBoxOrient = "vertical"
558+
cardBody.appendChild(nameEl)
559+
})
560+
561+
if (matches.length > 60) {
562+
const moreNote = document.createElement("p")
563+
moreNote.className = "text-muted mt-3 small"
564+
moreNote.textContent = `Showing first 60 of ${matches.length} results. Try a more specific search term.`
565+
search_container.appendChild(moreNote)
566+
}
519567
})
520-
521-
if (matches.length > 60) {
522-
const moreNote = document.createElement("p")
523-
moreNote.className = "text-muted mt-3 small"
524-
moreNote.textContent = `Showing first 60 of ${matches.length} results. Try a more specific search term.`
525-
search_container.appendChild(moreNote)
526-
}
527568
})
528569
})
529570
.catch(err => {

0 commit comments

Comments
 (0)