diff --git a/src/renderer/components/grid-carousel/index.tsx b/src/renderer/components/grid-carousel/index.tsx index 2f31aae5..7e0d51cc 100644 --- a/src/renderer/components/grid-carousel/index.tsx +++ b/src/renderer/components/grid-carousel/index.tsx @@ -4,6 +4,7 @@ import { ReactNode, useCallback, useEffect, + useLayoutEffect, useMemo, useRef, useState, @@ -117,6 +118,7 @@ export const SwiperGridCarousel = ({ const swiperRef = useRef(null); const playButtonBehavior = usePlayButtonBehavior(); const handlePlayQueueAdd = usePlayQueueAdd(); + const [slideCount, setSlideCount] = useState(4); useEffect(() => { swiperRef.current?.slideTo(0, 0); @@ -191,23 +193,24 @@ export const SwiperGridCarousel = ({ const handleNext = useCallback(() => { const activeIndex = swiperRef?.current?.activeIndex || 0; - const slidesPerView = Math.round(Number(swiperProps?.slidesPerView || 4)); + const slidesPerView = Math.round(Number(swiperProps?.slidesPerView || slideCount)); swiperRef?.current?.slideTo(activeIndex + slidesPerView); - }, [swiperProps?.slidesPerView]); + }, [slideCount, swiperProps?.slidesPerView]); const handlePrev = useCallback(() => { const activeIndex = swiperRef?.current?.activeIndex || 0; - const slidesPerView = Math.round(Number(swiperProps?.slidesPerView || 4)); + const slidesPerView = Math.round(Number(swiperProps?.slidesPerView || slideCount)); swiperRef?.current?.slideTo(activeIndex - slidesPerView); - }, [swiperProps?.slidesPerView]); + }, [slideCount, swiperProps?.slidesPerView]); const handleOnSlideChange = useCallback((e: SwiperCore) => { const { slides, isEnd, isBeginning, params } = e; if (isEnd || isBeginning) return; + const slideCount = (params.slidesPerView as number | undefined) || 4; setPagination({ - hasNextPage: (params?.slidesPerView || 4) < slides.length, - hasPreviousPage: (params?.slidesPerView || 4) < slides.length, + hasNextPage: slideCount < slides.length, + hasPreviousPage: slideCount < slides.length, }); }, []); @@ -215,39 +218,61 @@ export const SwiperGridCarousel = ({ const { slides, isEnd, isBeginning, params } = e; if (isEnd || isBeginning) return; + const slideCount = (params.slidesPerView as number | undefined) || 4; setPagination({ - hasNextPage: (params.slidesPerView || 4) < slides.length, - hasPreviousPage: (params.slidesPerView || 4) < slides.length, + hasNextPage: slideCount < slides.length, + hasPreviousPage: slideCount < slides.length, }); }, []); const handleOnReachEnd = useCallback((e: SwiperCore) => { const { slides, params } = e; + const slideCount = (params.slidesPerView as number | undefined) || 4; setPagination({ hasNextPage: false, - hasPreviousPage: (params.slidesPerView || 4) < slides.length, + hasPreviousPage: slideCount < slides.length, }); }, []); const handleOnReachBeginning = useCallback((e: SwiperCore) => { const { slides, params } = e; + const slideCount = (params.slidesPerView as number | undefined) || 4; setPagination({ - hasNextPage: (params.slidesPerView || 4) < slides.length, + hasNextPage: slideCount < slides.length, hasPreviousPage: false, }); }, []); - const handleOnResize = useCallback((e: SwiperCore) => { - if (!e) return; - const { width } = e; - const slidesPerView = getSlidesPerView(width); - if (!e.params) return; - e.params.slidesPerView = slidesPerView; - }, []); + useLayoutEffect(() => { + const handleResize = () => { + const { activeIndex, params, slides, width } = + (swiperRef.current as SwiperCore | undefined) ?? {}; - const throttledOnResize = throttle(handleOnResize, 200); + if (width) { + const slidesPerView = getSlidesPerView(width); + setSlideCount(slidesPerView); + } + + if (activeIndex !== undefined && slides && params?.slidesPerView) { + const slideCount = (params.slidesPerView as number | undefined) || 4; + setPagination({ + hasNextPage: activeIndex + slideCount < slides.length, + hasPreviousPage: activeIndex > 0, + }); + } + }; + + handleResize(); + + const throttledResize = throttle(handleResize, 200); + window.addEventListener('resize', throttledResize); + + return () => { + window.removeEventListener('resize', throttledResize); + }; + }, []); return ( { swiperRef.current = swiper; }} - onBeforeResize={handleOnResize} onReachBeginning={handleOnReachBeginning} onReachEnd={handleOnReachEnd} - onResize={throttledOnResize} onSlideChange={handleOnSlideChange} onZoomChange={handleOnZoomChange} {...swiperProps}