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'
|
|
}
|
|
|
|
|
|
}
|