@@ -297,135 +297,101 @@ <h2 class="text-2xl font-light text-gray-800 mb-2">${collection.title}</h2>
297297 ]
298298 } ;
299299
300- // Robust API fetching with rate limiting and retry logic
300+ // Simple, reliable API fetching with aggressive caching
301301 async function getCuratedArtworks ( collectionKey ) {
302- // Check cache first
302+ // Check cache first - more aggressive caching
303303 const cacheKey = `collection_${ collectionKey } ` ;
304304 const cachedData = artworkCache . get ( cacheKey ) ;
305305
306306 if ( cachedData && ( Date . now ( ) - cachedData . timestamp ) < CACHE_DURATION ) {
307- console . log ( `Loading ${ collectionKey } from cache...` ) ;
308-
309- // Show quick cache indicator
310- gallery . innerHTML = `
311- <div class="col-span-full mb-6">
312- <div class="bg-green-50 border border-green-200 rounded-lg p-2 text-center">
313- <i class="fas fa-check-circle text-green-500 mr-2"></i>
314- <span class="text-green-700 text-xs">Loaded from cache (${ cachedData . artworks . length } artworks)</span>
315- </div>
316- </div>
317- ` ;
318-
319- // Small delay to show the cache message, then display artworks
320- setTimeout ( ( ) => {
321- displayArtworks ( cachedData . artworks ) ;
322- } , 500 ) ;
323-
307+ console . log ( `✓ Loading ${ collectionKey } from cache (${ cachedData . artworks . length } artworks)` ) ;
308+ displayArtworks ( cachedData . artworks ) ;
324309 return ;
325310 }
326311
312+ // If we have multiple pending requests, prevent them
313+ if ( window . pendingAPIRequest ) {
314+ console . log ( 'Another API request in progress, showing fallback...' ) ;
315+ showFallbackWithRetry ( collectionKey , 'Another request in progress' ) ;
316+ return ;
317+ }
318+
319+ window . pendingAPIRequest = true ;
320+
327321 try {
328322 // Show loading state
329323 loadingIndicator . style . display = 'block' ;
330324 gallery . innerHTML = '' ;
331325
332- console . log ( `Fetching fresh ${ collectionKey } artworks from Met Museum API...` ) ;
333-
334- // Fetch search results with timeout
335- const controller = new AbortController ( ) ;
336- const timeoutId = setTimeout ( ( ) => controller . abort ( ) , 10000 ) ;
326+ console . log ( `🔄 Fetching fresh ${ collectionKey } artworks from Met Museum API...` ) ;
337327
338- const response = await fetch ( 'https://collectionapi.metmuseum.org/public/collection/v1/search?isHighlight=true&hasImages=true&q=a' , {
339- signal : controller . signal ,
340- headers : {
341- 'Accept' : 'application/json'
342- }
328+ // Ultra-simple API call - no complex batching
329+ const searchResponse = await fetch ( 'https://collectionapi.metmuseum.org/public/collection/v1/search?isHighlight=true&hasImages=true&q=painting' , {
330+ headers : { 'Accept' : 'application/json' }
343331 } ) ;
344332
345- clearTimeout ( timeoutId ) ;
346- console . log ( 'Response status:' , response . status , response . statusText ) ;
347-
348- if ( ! response . ok ) {
349- throw new Error ( `API returned ${ response . status } : ${ response . statusText } ` ) ;
333+ if ( ! searchResponse . ok ) {
334+ throw new Error ( `Search failed: ${ searchResponse . status } ` ) ;
350335 }
351336
352- const data = await response . json ( ) ;
353- console . log ( 'Search data received:' , data ) ;
337+ const searchData = await searchResponse . json ( ) ;
338+ console . log ( `📦 Got ${ searchData . total } search results` ) ;
354339
355- const objectIDs = data . objectIDs ;
356-
357- if ( ! objectIDs || objectIDs . length === 0 ) {
358- throw new Error ( 'No artworks found in search results' ) ;
340+ if ( ! searchData . objectIDs || searchData . objectIDs . length === 0 ) {
341+ throw new Error ( 'No artworks found' ) ;
359342 }
360-
361- console . log ( `Found ${ objectIDs . length } artworks, fetching first 15 details...` ) ;
362-
363- // Fetch artwork details with rate limiting (staggered requests)
343+
344+ // Fetch just 8 artworks sequentially (no parallel requests)
364345 const artworks = [ ] ;
365- const batchSize = 5 ; // Smaller batches to respect rate limits
366- const delay = ms => new Promise ( resolve => setTimeout ( resolve , ms ) ) ;
346+ const maxArtworks = 8 ;
367347
368- for ( let i = 0 ; i < Math . min ( 15 , objectIDs . length ) ; i += batchSize ) {
369- const batch = objectIDs . slice ( i , i + batchSize ) ;
370- console . log ( `Fetching batch ${ Math . floor ( i / batchSize ) + 1 } :` , batch ) ;
371-
372- const batchPromises = batch . map ( async ( id ) => {
373- try {
374- const res = await fetch ( `https://collectionapi.metmuseum.org/public/collection/v1/objects/${ id } ` , {
375- headers : { 'Accept' : 'application/json' }
376- } ) ;
377- if ( ! res . ok ) {
378- console . warn ( `Failed to fetch artwork ${ id } : ${ res . status } ` ) ;
379- return null ;
348+ console . log ( `🎨 Loading ${ maxArtworks } artwork details...` ) ;
349+
350+ for ( let i = 0 ; i < Math . min ( maxArtworks , searchData . objectIDs . length ) ; i ++ ) {
351+ try {
352+ const objectId = searchData . objectIDs [ i ] ;
353+
354+ const artworkResponse = await fetch ( `https://collectionapi.metmuseum.org/public/collection/v1/objects/${ objectId } ` , {
355+ headers : { 'Accept' : 'application/json' }
356+ } ) ;
357+
358+ if ( artworkResponse . ok ) {
359+ const artwork = await artworkResponse . json ( ) ;
360+ if ( artwork && artwork . primaryImageSmall ) {
361+ artworks . push ( artwork ) ;
362+ console . log ( `✓ Loaded: ${ artwork . title } ` ) ;
380363 }
381- return await res . json ( ) ;
382- } catch ( err ) {
383- console . warn ( `Network error fetching artwork ${ id } :` , err . message ) ;
384- return null ;
385364 }
386- } ) ;
387-
388- const batchResults = await Promise . all ( batchPromises ) ;
389- artworks . push ( ...batchResults . filter ( artwork => artwork !== null ) ) ;
390-
391- // Small delay between batches to respect rate limits
392- if ( i + batchSize < Math . min ( 15 , objectIDs . length ) ) {
393- await delay ( 100 ) ;
365+
366+ // Small delay between requests
367+ await new Promise ( resolve => setTimeout ( resolve , 200 ) ) ;
368+
369+ } catch ( err ) {
370+ console . warn ( `⚠️ Failed to load artwork ${ i } :` , err . message ) ;
394371 }
395372 }
396-
397- // Filter and display only artworks with images
398- const validArtworks = artworks . filter ( artwork => artwork && artwork . primaryImageSmall ) ;
399- console . log ( `Successfully loaded ${ validArtworks . length } artworks with images` ) ;
400373
401- if ( validArtworks . length === 0 ) {
402- throw new Error ( 'No artworks with images found in current batch' ) ;
374+ console . log ( `✅ Successfully loaded ${ artworks . length } artworks with images` ) ;
375+
376+ if ( artworks . length === 0 ) {
377+ throw new Error ( 'No artworks with images found' ) ;
403378 }
404379
405- // Cache the successful results
380+ // Cache the results
406381 artworkCache . set ( cacheKey , {
407- artworks : validArtworks ,
382+ artworks : artworks ,
408383 timestamp : Date . now ( )
409384 } ) ;
410- console . log ( `Cached ${ validArtworks . length } artworks for ${ collectionKey } ` ) ;
411385
412- displayArtworks ( validArtworks ) ;
386+ displayArtworks ( artworks ) ;
413387
414388 } catch ( error ) {
415- console . error ( 'Met Museum API Error:' , error ) ;
416-
417- // Only show fallback for actual API failures, not rate limiting issues
418- if ( error . name === 'AbortError' ) {
419- console . log ( 'Request timed out, showing fallback...' ) ;
420- } else if ( error . message . includes ( 'Failed to fetch' ) ) {
421- console . log ( 'Network error, showing fallback...' ) ;
422- } else {
423- console . log ( 'API error, showing fallback...' ) ;
424- }
425-
389+ console . error ( '🚨 API Error:' , error . message ) ;
426390 showFallbackWithRetry ( collectionKey , error . message ) ;
391+
427392 } finally {
428393 loadingIndicator . style . display = 'none' ;
394+ window . pendingAPIRequest = false ;
429395 }
430396 }
431397
0 commit comments