You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

117 lines
2.8 KiB

export default class QuizImagePreloader {
constructor() {
this.isPreloading = false
this.preloadedImages = new Map()
}
init() {
// Start preloading on initial page load
document.addEventListener('DOMContentLoaded', () => {
sessionStorage.removeItem('quiz_images_preloaded')
// this.startPreloadingFromHeader()
// console.info('startPreloadingFromHeader');
})
// Continue preloading on Turbo navigation
document.addEventListener('turbo:load', () => {
this.startPreloadingFromHeader()
console.info('startPreloadingFromHeader');
})
}
startPreloadingFromHeader() {
if (sessionStorage.getItem('quiz_images_preloaded') === 'true') {
return
}
// Skip if already preloading
if (this.isPreloading) {
return
}
const imageUrls = this.getImageUrlsFromHeader()
if (imageUrls.length > 0) {
this.preloadImages(imageUrls)
}
}
getImageUrlsFromHeader() {
const headerElement = document.querySelector('header[data-quiz-images]') ||
document.querySelector('[data-quiz-images]')
if (!headerElement) return []
try {
const urls = JSON.parse(headerElement.dataset.quizImages || '[]')
return urls.filter(url => url && url.trim())
} catch (e) {
console.warn('Failed to parse quiz image URLs from header:', e)
return []
}
}
preloadImages(imageUrls) {
this.isPreloading = true
let loadedCount = 0
const totalImages = imageUrls.length
imageUrls.forEach((url, index) => {
// Skip if already preloaded
if (this.preloadedImages.has(url)) {
loadedCount++
if (loadedCount === totalImages) {
this.onPreloadComplete()
}
return
}
const img = new Image()
img.onload = () => {
this.preloadedImages.set(url, img)
loadedCount++
if (loadedCount === totalImages) {
this.onPreloadComplete()
}
}
img.onerror = () => {
console.warn(`Failed to preload image: ${url}`)
loadedCount++
if (loadedCount === totalImages) {
this.onPreloadComplete()
}
}
// Stagger requests to avoid overwhelming server
setTimeout(() => {
img.src = url
}, index * 30)
})
}
onPreloadComplete() {
this.isPreloading = false
sessionStorage.setItem('quiz_images_preloaded', 'true')
console.info('PreloadComplete');
// Dispatch completion event for components that need to know
document.dispatchEvent(new CustomEvent('quiz:preload:complete', {
detail: { totalImages: this.preloadedImages.size }
}))
}
// Check if preloading is complete
isComplete() {
return sessionStorage.getItem('quiz_images_preloaded') === 'true'
}
}