|  |  |  | /** | 
					
						
							|  |  |  |  * @prettier | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | import React, { useEffect, useState } from 'react'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import * as MIME from '../types/MIME'; | 
					
						
							|  |  |  | import { Lightbox } from './Lightbox'; | 
					
						
							|  |  |  | import { Message } from './conversation/media-gallery/types/Message'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import { AttachmentType } from '../types/Attachment'; | 
					
						
							|  |  |  | // tslint:disable-next-line: no-submodule-imports
 | 
					
						
							|  |  |  | import useKey from 'react-use/lib/useKey'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export interface MediaItemType { | 
					
						
							|  |  |  |   objectURL?: string; | 
					
						
							|  |  |  |   thumbnailObjectUrl?: string; | 
					
						
							|  |  |  |   contentType: MIME.MIMEType; | 
					
						
							|  |  |  |   index: number; | 
					
						
							|  |  |  |   attachment: AttachmentType; | 
					
						
							|  |  |  |   message: Message; | 
					
						
							|  |  |  |   messageTimestamp: number; | 
					
						
							|  |  |  |   messageSender: string; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type Props = { | 
					
						
							|  |  |  |   close: () => void; | 
					
						
							|  |  |  |   media: Array<MediaItemType>; | 
					
						
							|  |  |  |   onSave?: (options: { | 
					
						
							|  |  |  |     attachment: AttachmentType; | 
					
						
							|  |  |  |     message: Message; | 
					
						
							|  |  |  |     index: number; | 
					
						
							|  |  |  |     messageTimestamp?: number; | 
					
						
							|  |  |  |     messageSender: string; | 
					
						
							|  |  |  |   }) => void; | 
					
						
							|  |  |  |   selectedIndex: number; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export const LightboxGallery = (props: Props) => { | 
					
						
							|  |  |  |   const { close, media, onSave } = props; | 
					
						
							|  |  |  |   const [currentIndex, setCurrentIndex] = useState(0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // 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 onPrevious = | 
					
						
							|  |  |  |     currentIndex > firstIndex | 
					
						
							|  |  |  |       ? () => { | 
					
						
							|  |  |  |           setCurrentIndex(Math.max(currentIndex - 1, 0)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       : undefined; | 
					
						
							|  |  |  |   const onNext = | 
					
						
							|  |  |  |     currentIndex < lastIndex | 
					
						
							|  |  |  |       ? () => { | 
					
						
							|  |  |  |           setCurrentIndex(Math.min(currentIndex + 1, lastIndex)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       : undefined; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const handleSave = () => { | 
					
						
							|  |  |  |     if (!onSave) { | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const mediaItem = media[currentIndex]; | 
					
						
							|  |  |  |     onSave({ | 
					
						
							|  |  |  |       attachment: mediaItem.attachment, | 
					
						
							|  |  |  |       message: mediaItem.message, | 
					
						
							|  |  |  |       index: mediaItem.index, | 
					
						
							|  |  |  |       messageTimestamp: mediaItem.messageTimestamp || mediaItem?.message?.sent_at, | 
					
						
							|  |  |  |       messageSender: mediaItem.messageSender || (mediaItem?.message as any)?.source, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const objectURL = selectedMedia.objectURL || 'images/alert-outline.svg'; | 
					
						
							|  |  |  |   const { attachment } = selectedMedia; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const saveCallback = onSave ? handleSave : undefined; | 
					
						
							|  |  |  |   const captionCallback = attachment ? attachment.caption : undefined; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   useKey( | 
					
						
							|  |  |  |     'ArrowRight', | 
					
						
							|  |  |  |     () => { | 
					
						
							|  |  |  |       onNext?.(); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     undefined, | 
					
						
							|  |  |  |     [currentIndex] | 
					
						
							|  |  |  |   ); | 
					
						
							|  |  |  |   useKey( | 
					
						
							|  |  |  |     'ArrowLeft', | 
					
						
							|  |  |  |     () => { | 
					
						
							|  |  |  |       onPrevious?.(); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     undefined, | 
					
						
							|  |  |  |     [currentIndex] | 
					
						
							|  |  |  |   ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   useKey('Escape', () => { | 
					
						
							|  |  |  |     props.close?.(); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return ( | 
					
						
							|  |  |  |     <Lightbox | 
					
						
							|  |  |  |       close={close} | 
					
						
							|  |  |  |       onPrevious={onPrevious} | 
					
						
							|  |  |  |       onNext={onNext} | 
					
						
							|  |  |  |       onSave={saveCallback} | 
					
						
							|  |  |  |       objectURL={objectURL} | 
					
						
							|  |  |  |       caption={captionCallback} | 
					
						
							|  |  |  |       contentType={selectedMedia.contentType} | 
					
						
							|  |  |  |     /> | 
					
						
							|  |  |  |   ); | 
					
						
							|  |  |  | }; |