diff --git a/src/components/Attachments/AttachmentCarousel/AttachmentCarouselCellRenderer.js b/src/components/Attachments/AttachmentCarousel/AttachmentCarouselCellRenderer.js new file mode 100644 index 000000000000..2c698d5c8a61 --- /dev/null +++ b/src/components/Attachments/AttachmentCarousel/AttachmentCarouselCellRenderer.js @@ -0,0 +1,34 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import {View, PixelRatio} from 'react-native'; +import useWindowDimensions from '../../../hooks/useWindowDimensions'; +import styles from '../../../styles/styles'; + +const propTypes = { + /** Cell Container styles */ + style: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.object), PropTypes.object]), +}; + +const defaultProps = { + style: [], +}; + +function AttachmentCarouselCellRenderer(props) { + const {windowWidth, isSmallScreenWidth} = useWindowDimensions(); + const modalStyles = styles.centeredModalStyles(isSmallScreenWidth, true); + const style = [props.style, styles.h100, {width: PixelRatio.roundToNearestPixel(windowWidth - (modalStyles.marginHorizontal + modalStyles.borderWidth) * 2)}]; + + return ( + + ); +} + +AttachmentCarouselCellRenderer.propTypes = propTypes; +AttachmentCarouselCellRenderer.defaultProps = defaultProps; +AttachmentCarouselCellRenderer.displayName = 'AttachmentCarouselCellRenderer'; + +export default React.memo(AttachmentCarouselCellRenderer); diff --git a/src/components/Attachments/AttachmentCarousel/index.js b/src/components/Attachments/AttachmentCarousel/index.js index 5c731a0ccfee..e97837437880 100644 --- a/src/components/Attachments/AttachmentCarousel/index.js +++ b/src/components/Attachments/AttachmentCarousel/index.js @@ -3,6 +3,7 @@ import {View, FlatList, PixelRatio, Keyboard} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; import styles from '../../../styles/styles'; +import AttachmentCarouselCellRenderer from './AttachmentCarouselCellRenderer'; import CarouselActions from './CarouselActions'; import withWindowDimensions from '../../withWindowDimensions'; import CarouselButtons from './CarouselButtons'; @@ -12,7 +13,6 @@ import ONYXKEYS from '../../../ONYXKEYS'; import withLocalize from '../../withLocalize'; import compose from '../../../libs/compose'; import useCarouselArrows from './useCarouselArrows'; -import useWindowDimensions from '../../../hooks/useWindowDimensions'; import CarouselItem from './CarouselItem'; import Navigation from '../../../libs/Navigation/Navigation'; import BlockingView from '../../BlockingViews/BlockingView'; @@ -29,7 +29,6 @@ const viewabilityConfig = { function AttachmentCarousel({report, reportActions, source, onNavigate, setDownloadButtonVisibility, translate}) { const scrollRef = useRef(null); - const {windowWidth, isSmallScreenWidth} = useWindowDimensions(); const canUseTouchScreen = DeviceCapabilities.canUseTouchScreen(); const [containerWidth, setContainerWidth] = useState(0); @@ -117,29 +116,6 @@ function AttachmentCarousel({report, reportActions, source, onNavigate, setDownl [containerWidth], ); - /** - * Defines how a container for a single attachment should be rendered - * @param {Object} cellRendererProps - * @returns {JSX.Element} - */ - const renderCell = useCallback( - (cellProps) => { - // Use window width instead of layout width to address the issue in https://github.com/Expensify/App/issues/17760 - // considering horizontal margin and border width in centered modal - const modalStyles = styles.centeredModalStyles(isSmallScreenWidth, true); - const style = [cellProps.style, styles.h100, {width: PixelRatio.roundToNearestPixel(windowWidth - (modalStyles.marginHorizontal + modalStyles.borderWidth) * 2)}]; - - return ( - - ); - }, - [isSmallScreenWidth, windowWidth], - ); - /** * Defines how a single attachment should be rendered * @param {Object} item @@ -211,7 +187,7 @@ function AttachmentCarousel({report, reportActions, source, onNavigate, setDownl windowSize={5} maxToRenderPerBatch={3} data={attachments} - CellRendererComponent={renderCell} + CellRendererComponent={AttachmentCarouselCellRenderer} renderItem={renderItem} getItemLayout={getItemLayout} keyExtractor={(item) => item.source} diff --git a/src/components/withWindowDimensions/index.js b/src/components/withWindowDimensions/index.js index a3836fa99e6b..37d5c94688a2 100644 --- a/src/components/withWindowDimensions/index.js +++ b/src/components/withWindowDimensions/index.js @@ -1,5 +1,6 @@ import React, {forwardRef, createContext, useState, useEffect} from 'react'; import PropTypes from 'prop-types'; +import lodashDebounce from 'lodash/debounce'; import {Dimensions} from 'react-native'; import {SafeAreaInsetsContext} from 'react-native-safe-area-context'; import getComponentDisplayName from '../../libs/getComponentDisplayName'; @@ -44,14 +45,15 @@ function WindowDimensionsProvider(props) { useEffect(() => { const onDimensionChange = (newDimensions) => { const {window} = newDimensions; - setWindowDimension({ windowHeight: window.height, windowWidth: window.width, }); }; - const dimensionsEventListener = Dimensions.addEventListener('change', onDimensionChange); + const onDimensionChangeDebounce = lodashDebounce(onDimensionChange, 300); + + const dimensionsEventListener = Dimensions.addEventListener('change', onDimensionChangeDebounce); return () => { if (!dimensionsEventListener) {