Skip to content

Commit

Permalink
fix(plugin-photo-swipe): avoid loading multiple instances at startup (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
Mister-Hope authored Dec 21, 2024
1 parent f62a06b commit dae01ac
Showing 1 changed file with 64 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,71 +55,85 @@ export const usePhotoSwipe = ({
scrollToClose,
}))

let photoSwipeLoader: Promise<typeof PhotoSwipe> | null = null
let photoSwipeId = 0
let photoSwipe: PhotoSwipe | null = null

const handlePhotoSwipe = async (event: MouseEvent): Promise<void> => {
const initPhotoSwipe = async (event: MouseEvent): Promise<void> => {
const el = event.target as HTMLImageElement

if (imageSelector.value && el.matches(imageSelector.value)) {
photoSwipe?.destroy()

const { default: PhotoSwipe } = await import(
/* webpackChunkName: "photo-swipe" */ 'photoswipe'
)

const images = Array.from(
document.querySelectorAll<HTMLImageElement>(imageSelector.value),
)
const currentIndex = images.findIndex((image) => image === el)

const dataSource = images.map<SlideData>((image) => ({
html: LOADING_ICON,
element: image,
msrc: image.src,
}))

dataSource.splice(currentIndex, 1, await resolveImageInfoFromElement(el))

const id = Date.now()

photoSwipeId = id
photoSwipe = new PhotoSwipe({
preloaderDelay: 0,
showHideAnimationType: 'zoom',
...options,
dataSource,
index: currentIndex,
...(scrollToClose
? { closeOnVerticalDrag: true, wheelToZoom: false }
: {}),
})

setupPhotoSwipe(photoSwipe, { download, fullscreen })
if (
// not enabled
!imageSelector.value ||
// Photoswipe is not being loaded
!photoSwipeLoader ||
// not an matched element
!el.matches(imageSelector.value)
)
return

// there is an active instance
if (photoSwipeId !== 0) photoSwipe!.destroy()

const id = Date.now()
const PhotoSwipeConstructor = await photoSwipeLoader

const images = Array.from(
document.querySelectorAll<HTMLImageElement>(imageSelector.value),
)
const dataSource = images.map<SlideData>((image) => ({
html: LOADING_ICON,
element: image,
msrc: image.src,
}))

const index = images.findIndex((image) => image === el)

photoSwipe = new PhotoSwipeConstructor({
preloaderDelay: 0,
showHideAnimationType: 'zoom',
...options,
dataSource,
index,
...(scrollToClose
? { closeOnVerticalDrag: true, wheelToZoom: false }
: {}),
})
photoSwipeId = id

photoSwipe.init()
setupPhotoSwipe(photoSwipe, { download, fullscreen })

photoSwipe.on('destroy', () => {
photoSwipe = null
photoSwipeId = 0
})
photoSwipe.init()

images.forEach((image, index) => {
if (index === currentIndex || photoSwipeId !== id) return
photoSwipe.on('destroy', () => {
photoSwipe = null
photoSwipeId = 0
})

void resolveImageInfoFromElement(image).then((data) => {
dataSource.splice(index, 1, data)
photoSwipe?.refreshSlideContent(index)
})
})
}
void images.map((image, imageIndex) =>
resolveImageInfoFromElement(image).then((data) => {
if (photoSwipeId !== id) return
dataSource.splice(imageIndex, 1, data)
photoSwipe?.refreshSlideContent(imageIndex)
}),
)
}

onMounted(() => {
useEventListener('click', handlePhotoSwipe)
const rIC =
'requestIdleCallback' in window ? window.requestIdleCallback : setTimeout

useEventListener('click', initPhotoSwipe)
useEventListener('wheel', () => {
if (options.value.scrollToClose) photoSwipe?.close()
})
rIC(() => {
photoSwipeLoader = import(
/* webpackChunkName: "photo-swipe" */ 'photoswipe'
).then(({ default: _PhotoSwipe }) => {
return _PhotoSwipe
})
})
})

onUnmounted(() => {
Expand Down

0 comments on commit dae01ac

Please sign in to comment.