import React, { useEffect, useRef, useState, useCallback } from 'react'; import { Dimensions, FlatList, Image, Modal, StyleSheet, TouchableOpacity, View, } from 'react-native'; import { ImageObject, IProps, RenderImageProps } from './types'; import ImagePreview from './ImagePreview'; import SwipeContainer from './SwipeContainer'; const { height: deviceHeight, width: deviceWidth } = Dimensions.get('window'); const defaultProps = { hideThumbs: false, resizeMode: 'contain', thumbColor: '#d9b44a', thumbResizeMode: 'cover', thumbSize: 48, }; const ImageGallery = (props: IProps & typeof defaultProps) => { const { close, hideThumbs, images, initialIndex, isOpen, renderCustomImage, renderCustomThumb, renderFooterComponent, renderHeaderComponent, resizeMode, thumbColor, thumbResizeMode, thumbSize, disableSwipe, onRequestClose, onEndReached } = props; const [activeIndex, setActiveIndex] = useState(0); const [isDragging, setIsDragging] = useState(false); const topRef = useRef(null); const bottomRef = useRef(null); props.currentIndex(activeIndex); const keyExtractorThumb = (item: ImageObject, index: number) => item && item.id ? item.id.toString() : index.toString(); const keyExtractorImage = (item: ImageObject, index: number) => item && item.id ? item.id.toString() : index.toString(); const scrollToIndex = (i: number) => { setActiveIndex(i); if (topRef?.current) { topRef.current.scrollToIndex({ animated: true, index: i, }); } if (bottomRef?.current) { if (i * (thumbSize + 10) - thumbSize / 2 > deviceWidth / 2) { bottomRef?.current?.scrollToIndex({ animated: true, index: i, }); } else { bottomRef?.current?.scrollToIndex({ animated: true, index: 0, }); } } }; const renderItem = ({ item, index }: RenderImageProps) => { return ( ); }; const renderThumb = ({ item, index }: RenderImageProps) => { return ( scrollToIndex(index)} activeOpacity={0.8} > {renderCustomThumb ? ( renderCustomThumb(item, index, activeIndex === index) ) : ( )} ); }; const onMomentumEnd = (e: any) => { const { x } = e.nativeEvent.contentOffset; scrollToIndex(Math.round(x / deviceWidth)); }; useEffect(() => { if (isOpen && initialIndex) { setActiveIndex(initialIndex); } else if (!isOpen) { setActiveIndex(0); } }, [isOpen, initialIndex]); const getImageLayout = useCallback((_, index) => { return { index, length: deviceWidth, offset: deviceWidth * index, }; }, []); const getThumbLayout = useCallback( (_, index) => { return { index, length: thumbSize, offset: thumbSize * index, }; }, [thumbSize] ); return ( {hideThumbs ? null : ( )} {renderHeaderComponent ? ( {renderHeaderComponent(images[activeIndex], activeIndex)} ) : null} {renderFooterComponent ? ( {renderFooterComponent(images[activeIndex], activeIndex)} ) : null} ); }; const styles = StyleSheet.create({ container: { alignItems: 'center', backgroundColor: 'black', flex: 1, height: deviceHeight, justifyContent: 'center', width: deviceWidth, }, header: { position: 'absolute', top: 0, width: '100%', }, footer: { bottom: 0, position: 'absolute', width: '100%', }, activeThumb: { borderWidth: 3, }, thumb: { borderRadius: 12, marginRight: 10, }, thumbnailListContainer: { paddingHorizontal: 10, }, bottomFlatlist: { position: 'absolute', }, }); ImageGallery.defaultProps = defaultProps; export default ImageGallery;