import { createEffect, createSignal, For, Show, on } from 'solid-js' import { MediaItem, UploadedFile } from '../../../pages/types' import { Icon } from '../Icon' import { Popover } from '../Popover' import { useLocalize } from '../../../context/localize' import { register } from 'swiper/element/bundle' import { DropArea } from '../DropArea' import { createFileUploader } from '@solid-primitives/upload' import SwiperCore, { Manipulation, Navigation, Pagination } from 'swiper' import { SwiperRef } from './swiper' import { validateFiles } from '../../../utils/validateFile' import { handleFileUpload } from '../../../utils/handleFileUpload' import { useSnackbar } from '../../../context/snackbar' import { Loading } from '../Loading' import { imageProxy } from '../../../utils/imageProxy' import { clsx } from 'clsx' import styles from './Swiper.module.scss' import { composeMediaItems } from '../../../utils/composeMediaItems' import SimplifiedEditor from '../../Editor/SimplifiedEditor' type Props = { images: MediaItem[] editorMode?: boolean onImagesAdd?: (value: MediaItem[]) => void onImagesSorted?: (value: MediaItem[]) => void onImageDelete?: (mediaItemIndex: number) => void onImageChange?: (index: number, value: MediaItem) => void } register() SwiperCore.use([Pagination, Navigation, Manipulation]) export const SolidSwiper = (props: Props) => { const { t } = useLocalize() const [loading, setLoading] = createSignal(false) const [slideIndex, setSlideIndex] = createSignal(0) const mainSwipeRef: { current: SwiperRef } = { current: null } const thumbSwipeRef: { current: SwiperRef } = { current: null } const { actions: { showSnackbar } } = useSnackbar() const handleSlideDescriptionChange = (index: number, field: string, value) => { props.onImageChange(index, { ...props.images[index], [field]: value }) } const swipeToUploaded = () => { setTimeout(() => { mainSwipeRef.current.swiper.slideTo(props.images.length - 1) }, 0) } const handleSlideChange = () => { thumbSwipeRef.current.swiper.slideTo(mainSwipeRef.current.swiper.activeIndex) setSlideIndex(mainSwipeRef.current.swiper.activeIndex) } createEffect( on( () => props.images.length, () => { mainSwipeRef.current?.swiper.update() thumbSwipeRef.current?.swiper.update() } ) ) const handleDropAreaUpload = (value: UploadedFile[]) => { props.onImagesAdd(composeMediaItems(value)) swipeToUploaded() } const handleDelete = (index: number) => { props.onImageDelete(index) if (index === 0) { mainSwipeRef.current.swiper.update() } else { mainSwipeRef.current.swiper.slideTo(index - 1) } } const { selectFiles } = createFileUploader({ multiple: true, accept: `image/*` }) const initUpload = async (selectedFiles) => { const isValid = validateFiles('image', selectedFiles) if (isValid) { try { setLoading(true) const results: UploadedFile[] = [] for (const file of selectedFiles) { const result = await handleFileUpload(file) results.push(result.url) } props.onImagesAdd(composeMediaItems(results)) setLoading(false) swipeToUploaded() } catch (error) { await showSnackbar({ type: 'error', body: t('Error') }) console.error('[runUpload]', error) setLoading(false) } } else { await showSnackbar({ type: 'error', body: t('Invalid file type') }) setLoading(false) return false } } const handleUploadThumb = async () => { selectFiles((selectedFiles) => { initUpload(selectedFiles) }) } const handleChangeIndex = (direction: 'left' | 'right', index: number) => { const images = [...props.images] if (direction === 'left' && index > 0) { const copy = images.splice(index, 1)[0] images.splice(index - 1, 0, copy) } else if (direction === 'right' && index < images.length - 1) { const copy = images.splice(index, 1)[0] images.splice(index + 1, 0, copy) } props.onImagesSorted(images) setTimeout(() => { mainSwipeRef.current.swiper.slideTo(direction === 'left' ? index - 1 : index + 1) }, 0) } return (