/** * @prettier */ import React, { useCallback, useEffect, useState } from 'react'; import * as MIME from '../types/MIME'; import { Lightbox } from './Lightbox'; import { AttachmentTypeWithPath } from '../types/Attachment'; // tslint:disable-next-line: no-submodule-imports import useKey from 'react-use/lib/useKey'; import { showLightBox } from '../state/ducks/conversations'; import { useDispatch } from 'react-redux'; export interface MediaItemType { objectURL?: string; thumbnailObjectUrl?: string; contentType: MIME.MIMEType; index: number; attachment: AttachmentTypeWithPath; messageTimestamp: number; messageSender: string; messageId: string; } type Props = { media: Array; onSave?: (saveData: MediaItemType) => void; selectedIndex: number; }; export const LightboxGallery = (props: Props) => { const { media, onSave } = props; const [currentIndex, setCurrentIndex] = useState(-1); const dispatch = useDispatch(); // just run once, when the component is mounted. It's to show the lightbox on the specified index at start. useEffect(() => { setCurrentIndex(props.selectedIndex); }, []); const selectedMedia = media[currentIndex]; const firstIndex = 0; const lastIndex = media.length - 1; const hasPrevious = currentIndex > firstIndex; const hasNext = currentIndex < lastIndex; const onPrevious = useCallback(() => { setCurrentIndex(Math.max(currentIndex - 1, 0)); }, [currentIndex]); const onNext = useCallback(() => { setCurrentIndex(Math.min(currentIndex + 1, lastIndex)); }, [currentIndex, lastIndex]); const handleSave = useCallback(() => { if (!onSave) { return; } const mediaItem = media[currentIndex]; onSave(mediaItem); }, [currentIndex, media]); useKey( 'ArrowRight', () => { onNext?.(); }, undefined, [currentIndex] ); useKey( 'ArrowLeft', () => { onPrevious?.(); }, undefined, [currentIndex] ); useKey( 'Escape', () => { dispatch(showLightBox(undefined)); }, undefined, [currentIndex] ); // just to avoid to render the first element during the first render when the user selected another item if (currentIndex === -1) { return null; } const objectURL = selectedMedia?.objectURL || 'images/alert-outline.svg'; const { attachment } = selectedMedia; const saveCallback = onSave ? handleSave : undefined; const caption = attachment?.caption; return ( // tslint:disable: use-simple-attributes ); };