import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react' import classNames from 'classnames' import ArrowLeft from '@/svgs/arrow-left-line.svg' import ArrowRight from '@/svgs/arrow-right-line.svg' import styles from './carousel.module.css' import { useShowModal } from './modal' import { Dropdown } from 'react-bootstrap' function useSwiping ({ moveLeft, moveRight }) { const [touchStartX, setTouchStartX] = useState(null) const onTouchStart = useCallback((e) => { if (e.touches.length === 1) { setTouchStartX(e.touches[0].clientX) } }, []) const onTouchEnd = useCallback((e) => { if (touchStartX !== null) { const touchEndX = e.changedTouches[0].clientX const diff = touchEndX - touchStartX if (diff > 50) { moveLeft() } else if (diff < -50) { moveRight() } setTouchStartX(null) } }, [touchStartX, moveLeft, moveRight]) useEffect(() => { document.addEventListener('touchstart', onTouchStart) document.addEventListener('touchend', onTouchEnd) return () => { document.removeEventListener('touchstart', onTouchStart) document.removeEventListener('touchend', onTouchEnd) } }, [onTouchStart, onTouchEnd]) } function useArrowKeys ({ moveLeft, moveRight }) { const onKeyDown = useCallback((e) => { if (e.key === 'ArrowLeft') { moveLeft() } else if (e.key === 'ArrowRight') { moveRight() } }, [moveLeft, moveRight]) useEffect(() => { document.addEventListener('keydown', onKeyDown) return () => document.removeEventListener('keydown', onKeyDown) }, [onKeyDown]) } export default function Carousel ({ close, mediaArr, src, originalSrc, setOptions }) { const [index, setIndex] = useState(mediaArr.findIndex(([key]) => key === src)) const [currentSrc, canGoLeft, canGoRight] = useMemo(() => { return [mediaArr[index][0], index > 0, index < mediaArr.length - 1] }, [mediaArr, index]) const moveLeft = useCallback(() => { setIndex(i => Math.max(0, i - 1)) }, [setIndex]) const moveRight = useCallback(() => { setIndex(i => Math.min(mediaArr.length - 1, i + 1)) }, [setIndex, mediaArr.length]) useSwiping({ moveLeft, moveRight }) useArrowKeys({ moveLeft, moveRight }) return (
{ e.stopPropagation() moveLeft() }} >
{ e.stopPropagation() moveRight() }} >
) } const CarouselContext = createContext() function CarouselOverflow ({ originalSrc, rel }) { return view original } export function CarouselProvider ({ children }) { const media = useRef(new Map()) const showModal = useShowModal() const showCarousel = useCallback(({ src }) => { showModal((close, setOptions) => { return }, { fullScreen: true, overflow: }) }, [showModal, media.current]) const addMedia = useCallback(({ src, originalSrc, rel }) => { media.current.set(src, { src, originalSrc, rel }) }, [media.current]) const removeMedia = useCallback((src) => { media.current.delete(src) }, [media.current]) const value = useMemo(() => ({ showCarousel, addMedia, removeMedia }), [showCarousel, addMedia, removeMedia]) return {children} } export function useCarousel () { return useContext(CarouselContext) }