import * as React from 'react'; import { useEffect, useRef, useState, useContext, Fragment, CSSProperties } from 'react'; import { Thumbnail } from '../../Thumbnail'; import { Helpers } from '../../../services/helpers'; import { StoreContext } from '../../../services/store'; import { IMedia } from '../../../types'; interface Props { forceColumns?: number; } const Wall = ({ forceColumns }: Props) => { const context = useContext(StoreContext); const containerRef = useRef(null); const defaultColumnsNumber = context.isMobile ? 2 : 3; // Function to calculate dynamically the number of media per row, depending on screen size const columnsNumber = (): number => { const settings = context?.data?.settings; const contentSize = Number(settings?.content_size) ?? undefined; const contentsPerRow = forceColumns || contentSize || defaultColumnsNumber; const minWidth = 125; if (forceColumns) { return forceColumns; } if (!context?.isMobile) { return contentsPerRow; } if (!containerRef.current) { return defaultColumnsNumber; } const calculatedColumns = Math.floor(containerRef.current.clientWidth / minWidth) || 1; const isWideEnough = containerRef.current.clientWidth / contentsPerRow > minWidth; return isWideEnough ? contentsPerRow : calculatedColumns; }; const [numberOfColumns, setNumberOfColumns] = useState(columnsNumber()); // Call columnsNumber and change numberOfColumns // accordingly at each re-render, included screen resize useEffect(() => { setNumberOfColumns(columnsNumber()); }); const [medias, setMedias] = useState(context?.data?.content?.medias ?? []); // Update media to show if medias array actually changes useEffect(() => { setMedias(context?.data?.content?.medias); }, [context?.data?.content?.medias]); const renderRows = () => { const thumbStyle = { ...thumbnailStyle }; const rStyle = { ...rowStyle }; thumbStyle.width = `${100 / numberOfColumns}%`; const numberOfRow: number = Math.ceil((medias?.length ?? 0) / numberOfColumns) ?? 1; const rows: JSX.Element[][] = Helpers.createArray(numberOfRow).map(() => []); medias.forEach((media, i: number) => { rows[Math.floor(i / numberOfColumns)].push(
, ); }); const lastRowContents = (medias?.length ?? 0) % numberOfColumns; let rest = -lastRowContents + numberOfColumns; if (!lastRowContents) { rest = 0; } while (rest > 0) { rows[rows && rows.length - 1].push(
, ); rest -= 1; } return rows.map((content, i) => (
{content}

)); }; return (
{renderRows()}
); }; const rowStyle: CSSProperties = { display: 'inline-block', marginTop: -4, width: '100%', }; const rowContainerStyle: CSSProperties = { textAlign: 'center', }; const emptyThumnailStyle: CSSProperties = { paddingBottom: '100%', }; const thumbnailStyle: CSSProperties = { display: 'inline-block', }; export default Wall;