import * as React from 'react'; import { FC, useCallback, CSSProperties, Fragment } from 'react'; import { IMedia } from '../../../types'; import { Helpers } from '../../../services/helpers'; import { Thumbnail } from '../../Thumbnail'; import { useStore } from '../../../services/store'; type Mapping = Array<{ x: number; y: number; size: number }>; const DESKTOP_NUMBER_OF_COLUMNS = 6; const DESKTOP_NUMBER_OF_ROW = 3; const MOBILE_NUMBER_OF_COLUMNS = 3; const MOBILE_NUMBER_OF_ROW = 6; const DESKTOP_MOSAIC_MAPPING: Mapping = [ { x: 0, y: 0, size: 2 }, { x: 2, y: 0, size: 1 }, { x: 2, y: 1, size: 1 }, { x: 0, y: 2, size: 1 }, { x: 1, y: 2, size: 1 }, { x: 2, y: 2, size: 1 }, { x: 3, y: 0, size: 1 }, { x: 4, y: 0, size: 1 }, { x: 5, y: 0, size: 1 }, { x: 3, y: 1, size: 2 }, { x: 5, y: 1, size: 1 }, { x: 5, y: 2, size: 1 }, ]; const MOBILE_MOSAIC_MAPPING: Mapping = [ { x: 0, y: 0, size: 2 }, { x: 2, y: 0, size: 1 }, { x: 2, y: 1, size: 1 }, { x: 0, y: 2, size: 1 }, { x: 1, y: 2, size: 1 }, { x: 2, y: 2, size: 1 }, { x: 0, y: 3, size: 1 }, { x: 0, y: 4, size: 1 }, { x: 0, y: 5, size: 1 }, { x: 1, y: 3, size: 2 }, { x: 1, y: 5, size: 1 }, { x: 2, y: 5, size: 1 }, ]; export const Mosaic: FC = () => { const store = useStore(); const generateGrid = useCallback( (medias: IMedia[], mapping: Mapping, columns: number, rows: number) => { const gridStyle = { ...gridStyleTemplate, gridTemplateColumns: Helpers.createArray(columns) .map(() => `${100 / columns}%`) .join(' '), gridTemplateRows: Helpers.createArray(rows) .map(() => 'auto') .join(' '), }; const thumbnails = medias.map((media, i) => { const { x, y, size } = mapping[i]; const style: CSSProperties = { gridColumn: `${x + 1} / span ${size}`, gridRow: `${y + 1} / span ${size}`, }; return (
); }); return (
{thumbnails}

); }, [store.config.classPrefix], ); const renderDesktop = useCallback(() => { const chunkSize = DESKTOP_MOSAIC_MAPPING.length; const mediaChunks = Helpers.chunkArray(store.data.content.medias, chunkSize); return mediaChunks.map((chunk, i) => ( {generateGrid( chunk, DESKTOP_MOSAIC_MAPPING, DESKTOP_NUMBER_OF_COLUMNS, DESKTOP_NUMBER_OF_ROW, )} )); }, [store.data.content.medias, generateGrid]); const renderMobile = useCallback(() => { const chunkSize = MOBILE_MOSAIC_MAPPING.length; const mediaChunks = Helpers.chunkArray(store.data.content.medias, chunkSize); return mediaChunks.map((chunk, i) => ( {generateGrid(chunk, MOBILE_MOSAIC_MAPPING, MOBILE_NUMBER_OF_COLUMNS, MOBILE_NUMBER_OF_ROW)} )); }, [store.data.content.medias, generateGrid]); if (!store.root) { return null; } return (
{!store.isMobile ? renderDesktop() : renderMobile()}
); }; export default Mosaic; const mosaicStyle: CSSProperties = { textAlign: 'center', }; const gridStyleTemplate: CSSProperties = { display: 'inline-grid', width: '100%', };