Skip to content

Commit 93175be

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 93175be

1 file changed

Lines changed: 179 additions & 128 deletions

File tree

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

Lines changed: 179 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -384,146 +384,197 @@ 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+
row.appendChild(col)
400+
401+
const card = document.createElement("a")
402+
card.className = "card h-100 text-decoration-none shadow-sm border-0 rounded-0"
403+
card.href = `${base_path}/browse/games/?id=${id}`
404+
col.appendChild(card)
405+
406+
// Cover image or placeholder
407+
if (game.cover && game.cover.url) {
408+
const coverImg = document.createElement("img")
409+
coverImg.className = "card-img-top rounded-top-0"
410+
// Convert IGDB URL properly
411+
let coverUrl = game.cover.url
412+
if (!coverUrl.startsWith('http')) {
413+
coverUrl = 'https://images.igdb.com/igdb/image/upload/t_cover_big/' + coverUrl.split('/').pop()
414+
} else {
415+
coverUrl = coverUrl.replace("t_thumb", "t_cover_big")
416+
}
417+
coverImg.src = coverUrl
418+
coverImg.alt = game.name
419+
coverImg.loading = "lazy"
420+
coverImg.style.width = "100%"
421+
coverImg.style.maxWidth = "180px"
422+
coverImg.style.aspectRatio = "3 / 4"
423+
coverImg.style.objectFit = "cover"
424+
card.appendChild(coverImg)
425+
} else {
426+
const placeholder = document.createElement("div")
427+
placeholder.className = "card-img-top bg-secondary d-flex align-items-center justify-content-center"
428+
placeholder.style.width = "100%"
429+
placeholder.style.maxWidth = "180px"
430+
placeholder.style.aspectRatio = "3 / 4"
431+
const icon = document.createElement("span")
432+
icon.className = "material-symbols-outlined text-white"
433+
icon.style.fontSize = "3rem"
434+
icon.textContent = "sports_esports"
435+
placeholder.appendChild(icon)
436+
card.appendChild(placeholder)
437+
}
418438

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
439+
const cardBody = document.createElement("div")
440+
cardBody.className = "card-body p-2"
441+
card.appendChild(cardBody)
442+
443+
// Game name
444+
const nameEl = document.createElement("h6")
445+
nameEl.className = "card-title small mb-2 fw-bold"
446+
nameEl.textContent = game.name
447+
nameEl.title = game.name
448+
nameEl.style.overflow = "hidden"
449+
nameEl.style.display = "-webkit-box"
450+
nameEl.style.webkitLineClamp = "2"
451+
nameEl.style.webkitBoxOrient = "vertical"
452+
cardBody.appendChild(nameEl)
453+
454+
// Platforms with release years
455+
if (game.platforms && game.platforms.length > 0) {
456+
const platformsDiv = document.createElement("div")
457+
platformsDiv.className = "mb-2"
458+
459+
// Group release dates by platform
460+
const platformYears = {}
461+
if (game.release_dates && game.release_dates.length > 0) {
462+
game.release_dates.forEach(rd => {
463+
if (rd.platform && rd.y) {
464+
if (!platformYears[rd.platform] || rd.y < platformYears[rd.platform]) {
465+
platformYears[rd.platform] = rd.y
466+
}
442467
}
443-
}
468+
})
469+
}
470+
471+
// Show first 3 platforms
472+
game.platforms.slice(0, 3).forEach(platformId => {
473+
const platform = allPlatforms[String(platformId)]
474+
const platformName = platform ? platform.name : `Platform ${platformId}`
475+
const year = platformYears[platformId] ? ` (${platformYears[platformId]})` : ""
476+
477+
const badge = document.createElement("span")
478+
badge.className = "badge bg-secondary me-1 mb-1 small"
479+
badge.style.fontSize = "0.7rem"
480+
badge.textContent = platformName + year
481+
platformsDiv.appendChild(badge)
444482
})
445-
}
446483

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)
484+
if (game.platforms.length > 3) {
485+
const moreBadge = document.createElement("span")
486+
moreBadge.className = "badge bg-secondary me-1 mb-1 small"
487+
moreBadge.style.fontSize = "0.7rem"
488+
moreBadge.textContent = `+${game.platforms.length - 3} more`
489+
platformsDiv.appendChild(moreBadge)
490+
}
491+
492+
cardBody.appendChild(platformsDiv)
466493
}
494+
})
467495

468-
cardBody.appendChild(platformsDiv)
496+
if (matches.length > 60) {
497+
const moreNote = document.createElement("p")
498+
moreNote.className = "text-muted mt-3 small"
499+
moreNote.textContent = `Showing first 60 of ${matches.length} results. Try a more specific search term.`
500+
search_container.appendChild(moreNote)
469501
}
470502
})
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-
}
478503
})
479504
.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)
505+
// Fallback if platforms can't be loaded - still fetch game data
506+
const gamePromises = matches.slice(0, 60).map(([id, _game]) =>
507+
fetch(`${base_url}/games/${id}.json`)
508+
.then(r => r.ok ? r.json() : null)
509+
.then(fullGame => ({ id, game: fullGame || { name: _game.name } }))
510+
.catch(() => ({ id, game: { name: _game.name } }))
511+
)
512+
513+
Promise.all(gamePromises).then(results => {
514+
results.forEach(({ id, game }) => {
515+
const col = document.createElement("div")
516+
col.className = "col"
517+
row.appendChild(col)
518+
519+
const card = document.createElement("a")
520+
card.className = "card h-100 text-decoration-none shadow-sm border-0 rounded-0"
521+
card.href = `${base_path}/browse/games/?id=${id}`
522+
col.appendChild(card)
523+
524+
if (game.cover && game.cover.url) {
525+
const coverImg = document.createElement("img")
526+
coverImg.className = "card-img-top rounded-top-0"
527+
// Convert IGDB URL properly
528+
let coverUrl = game.cover.url
529+
if (!coverUrl.startsWith('http')) {
530+
coverUrl = 'https://images.igdb.com/igdb/image/upload/t_cover_big/' + coverUrl.split('/').pop()
531+
} else {
532+
coverUrl = coverUrl.replace("t_thumb", "t_cover_big")
533+
}
534+
coverImg.src = coverUrl
535+
coverImg.alt = game.name
536+
coverImg.loading = "lazy"
537+
coverImg.style.width = "100%"
538+
coverImg.style.maxWidth = "180px"
539+
coverImg.style.aspectRatio = "3 / 4"
540+
coverImg.style.objectFit = "cover"
541+
card.appendChild(coverImg)
542+
} else {
543+
const placeholder = document.createElement("div")
544+
placeholder.className = "card-img-top bg-secondary d-flex align-items-center justify-content-center"
545+
placeholder.style.width = "100%"
546+
placeholder.style.maxWidth = "180px"
547+
placeholder.style.aspectRatio = "3 / 4"
548+
const icon = document.createElement("span")
549+
icon.className = "material-symbols-outlined text-white"
550+
icon.style.fontSize = "3rem"
551+
icon.textContent = "sports_esports"
552+
placeholder.appendChild(icon)
553+
card.appendChild(placeholder)
554+
}
513555

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)
556+
const cardBody = document.createElement("div")
557+
cardBody.className = "card-body p-2"
558+
card.appendChild(cardBody)
559+
560+
const nameEl = document.createElement("p")
561+
nameEl.className = "card-text small mb-0 fw-bold"
562+
nameEl.textContent = game.name
563+
nameEl.title = game.name
564+
nameEl.style.overflow = "hidden"
565+
nameEl.style.display = "-webkit-box"
566+
nameEl.style.webkitLineClamp = "2"
567+
nameEl.style.webkitBoxOrient = "vertical"
568+
cardBody.appendChild(nameEl)
569+
})
570+
571+
if (matches.length > 60) {
572+
const moreNote = document.createElement("p")
573+
moreNote.className = "text-muted mt-3 small"
574+
moreNote.textContent = `Showing first 60 of ${matches.length} results. Try a more specific search term.`
575+
search_container.appendChild(moreNote)
576+
}
519577
})
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-
}
527578
})
528579
})
529580
.catch(err => {

0 commit comments

Comments
 (0)