@@ -125,7 +125,7 @@ function loadItemDetail(endpoint, renderFn) {
125125
126126/**
127127 * Render a list of game cards (compact) into a container element.
128- * Games are fetched from the buckets to resolve names .
128+ * Games are fetched from individual game files when needed to get cover art .
129129 * @param {HTMLElement } container
130130 * @param {Array<number|object> } games - array of game IDs or game objects with {id, name, cover}
131131 */
@@ -139,54 +139,92 @@ function renderGameList(container, games) {
139139 row . className = "row row-cols-2 row-cols-sm-3 row-cols-md-4 row-cols-lg-6 g-2" ;
140140 container . appendChild ( row ) ;
141141
142+ // Separate games into those with full data and those that need fetching
143+ const gamesToFetch = [ ] ;
144+ const gamesWithData = [ ] ;
145+
142146 games . forEach ( game => {
143147 const gameId = typeof game === "object" ? game . id : game ;
144- const gameName = typeof game === "object" && game . name ? game . name : null ;
145- const coverUrl = typeof game === "object" && game . cover ? igdbImageUrl ( game . cover . url , "t_cover_small" ) : null ;
146-
147- const col = document . createElement ( "div" ) ;
148- col . className = "col" ;
149- row . appendChild ( col ) ;
150-
151- const card = document . createElement ( "a" ) ;
152- card . className = "card h-100 text-decoration-none shadow-sm border-0 rounded-0 game-card" ;
153- card . href = `${ base_path } /browse/games/?id=${ gameId } ` ;
154- col . appendChild ( card ) ;
155-
156- if ( coverUrl ) {
157- const img = document . createElement ( "img" ) ;
158- img . className = "card-img-top rounded-0" ;
159- img . src = coverUrl ;
160- img . alt = gameName || "" ;
161- img . loading = "lazy" ;
162- card . appendChild ( img ) ;
163- } else {
164- const placeholder = document . createElement ( "div" ) ;
165- placeholder . className = "card-img-top bg-secondary d-flex align-items-center justify-content-center" ;
166- placeholder . style . height = "120px" ;
167- const icon = document . createElement ( "span" ) ;
168- icon . className = "material-symbols-outlined text-white" ;
169- icon . textContent = "sports_esports" ;
170- placeholder . appendChild ( icon ) ;
171- card . appendChild ( placeholder ) ;
172- }
148+ const hasFullData = typeof game === "object" && game . name && game . cover ;
173149
174- const cardBody = document . createElement ( "div" ) ;
175- cardBody . className = "card-body p-1" ;
176- card . appendChild ( cardBody ) ;
177-
178- if ( gameName ) {
179- const nameEl = document . createElement ( "p" ) ;
180- nameEl . className = "card-text small mb-0 text-truncate" ;
181- nameEl . textContent = gameName ;
182- nameEl . title = gameName ;
183- cardBody . appendChild ( nameEl ) ;
150+ if ( hasFullData ) {
151+ gamesWithData . push ( game ) ;
184152 } else {
185- // Fetch the name from the buckets lazily - just show ID for now
186- const nameEl = document . createElement ( "p" ) ;
187- nameEl . className = "card-text small mb-0 text-muted" ;
188- nameEl . textContent = `#${ gameId } ` ;
189- cardBody . appendChild ( nameEl ) ;
153+ gamesToFetch . push ( gameId ) ;
190154 }
191155 } ) ;
156+
157+ // Render games that already have full data
158+ gamesWithData . forEach ( game => {
159+ renderGameCard ( row , game . id , game . name , game . cover ? igdbImageUrl ( game . cover . url , "t_cover_small" ) : null ) ;
160+ } ) ;
161+
162+ // Fetch and render games that only have IDs
163+ if ( gamesToFetch . length > 0 ) {
164+ // Fetch each game's data
165+ const fetchPromises = gamesToFetch . map ( gameId => {
166+ return fetch ( `${ base_path } /games/${ gameId } .json` )
167+ . then ( r => r . ok ? r . json ( ) : null )
168+ . then ( gameData => ( { id : gameId , data : gameData } ) )
169+ . catch ( ( ) => ( { id : gameId , data : null } ) ) ;
170+ } ) ;
171+
172+ Promise . all ( fetchPromises ) . then ( results => {
173+ results . forEach ( ( { id, data } ) => {
174+ const name = data ? data . name : null ;
175+ const coverUrl = data && data . cover ? igdbImageUrl ( data . cover . url , "t_cover_small" ) : null ;
176+ renderGameCard ( row , id , name , coverUrl ) ;
177+ } ) ;
178+ } ) ;
179+ }
180+ }
181+
182+ /**
183+ * Helper function to render a single game card
184+ */
185+ function renderGameCard ( row , gameId , gameName , coverUrl ) {
186+ const col = document . createElement ( "div" ) ;
187+ col . className = "col" ;
188+ row . appendChild ( col ) ;
189+
190+ const card = document . createElement ( "a" ) ;
191+ card . className = "card h-100 text-decoration-none shadow-sm border-0 rounded-0 game-card" ;
192+ card . href = `${ base_path } /browse/games/?id=${ gameId } ` ;
193+ col . appendChild ( card ) ;
194+
195+ if ( coverUrl ) {
196+ const img = document . createElement ( "img" ) ;
197+ img . className = "card-img-top rounded-0" ;
198+ img . src = coverUrl ;
199+ img . alt = gameName || "" ;
200+ img . loading = "lazy" ;
201+ card . appendChild ( img ) ;
202+ } else {
203+ const placeholder = document . createElement ( "div" ) ;
204+ placeholder . className = "card-img-top bg-secondary d-flex align-items-center justify-content-center" ;
205+ placeholder . style . height = "120px" ;
206+ const icon = document . createElement ( "span" ) ;
207+ icon . className = "material-symbols-outlined text-white" ;
208+ icon . textContent = "sports_esports" ;
209+ placeholder . appendChild ( icon ) ;
210+ card . appendChild ( placeholder ) ;
211+ }
212+
213+ const cardBody = document . createElement ( "div" ) ;
214+ cardBody . className = "card-body p-1" ;
215+ card . appendChild ( cardBody ) ;
216+
217+ if ( gameName ) {
218+ const nameEl = document . createElement ( "p" ) ;
219+ nameEl . className = "card-text small mb-0 text-truncate" ;
220+ nameEl . textContent = gameName ;
221+ nameEl . title = gameName ;
222+ cardBody . appendChild ( nameEl ) ;
223+ } else {
224+ // Show game ID as fallback
225+ const nameEl = document . createElement ( "p" ) ;
226+ nameEl . className = "card-text small mb-0 text-muted" ;
227+ nameEl . textContent = `Game #${ gameId } ` ;
228+ cardBody . appendChild ( nameEl ) ;
229+ }
192230}
0 commit comments