import type { Attachment } from 'stream-chat'; import { buildThumbnail } from './buildThumbnail'; import type { GallerySizeAndThumbnailGrid, GallerySizeConfig, ThumbnailGrid } from './types'; import { ChatConfigContextValue } from '../../../../contexts/chatConfigContext/ChatConfigContext'; /** * Builds a grid of thumbnail images from image attachments. * This function take a object parameter with following properties: * * @params * * - {number[][]} grid - Grid pattern of the gallery. Each numeric value in the array represents the flex value of corresponding image in grid. * - {Attachment[]} images - Array of image attachments. * - {GallerySizeConfig} sizeConfig - Theme config for the gallery. * - {boolean} invertedDirections - Whether to invert the direction of the grid. By default grid is rendered with column as primary direction and row as secondary direction. * * @usage * * ``` * const { thumbnailGrid, invertedDirection } = buildThumbnailGrid({ * grid: [[1], [1]], * images: [image1, image2], * sizeConfig: { * gridHeight: 200, * gridWidth: 200, * maxHeight: 200, * maxWidth: 200, * minHeight: 200, * minWidth: 200, * }, * }) * * Rendering logic on UI: * * ``` * * { * thumbnailGrid.forEach(rows => { * return ( * * { * rows.forEach(thumbnail => ( * * ))} * * )}); * } * * ``` * * Lets look at different examples of grid and invertedDirections param: * * EXAMPLE 1: * * ``` * { * grid: [[2, 1], [2, 1]] * invertedDirections: false * } * ``` * * Resulting thumbnail grid on rendered UI: * * __________________ * | | | * | | | * |------------------| * | | | * | | | * ------------------ * * EXAMPLE 2: * * ``` * { * grid: [[2, 1], [2, 1]] * invertedDirections: true * } * ``` * Resulting thumbnail grid on rendered UI: * __________________ * | | | * | | | * | | | * | | | * |------------------| * | | | * | | | * ------------------ * * EXAMPLE 3: * * ``` * { * grid: [[2, 1]] * invertedDirections: false * } * ``` * Resulting thumbnail grid on rendered UI: * __________________ * | | * | | * | | * | | * |------------------| * | | * | | * ------------------ * * EXAMPLE 4: * * ``` * { * grid: [[2, 1]] * invertedDirections: true * } * ``` * Resulting thumbnail grid on rendered UI: * __________________ * | | | * | | | * | | | * | | | * | | | * ------------------ * * @return {GallerySizeAndThumbnailGrid} */ export function buildThumbnailGrid({ grid, images, invertedDirections = false, resizableCDNHosts, sizeConfig, }: Pick & { grid: number[][]; images: Attachment[]; invertedDirections: boolean; sizeConfig: GallerySizeConfig; }): GallerySizeAndThumbnailGrid { const { gridHeight, gridWidth } = sizeConfig; let imageIndex = 0; const thumbnailGrid: ThumbnailGrid = []; const numOfColumns = grid.length; grid.forEach((rows, colIndex) => { const totalFlexValue = rows.reduce((acc, curr) => acc + curr, 0); rows.forEach((flexValue) => { const tHeight = invertedDirections ? gridHeight / numOfColumns : gridHeight * (flexValue / totalFlexValue); const tWidth = invertedDirections ? gridWidth * (flexValue / totalFlexValue) : gridWidth / numOfColumns; const currentImage = images[imageIndex]; const thumbnail = buildThumbnail({ flex: flexValue, height: tHeight, image: currentImage, resizableCDNHosts, resizeMode: 'cover', width: tWidth, }); if (!thumbnailGrid[colIndex]) { thumbnailGrid[colIndex] = []; } thumbnailGrid[colIndex].push(thumbnail); imageIndex++; }); }); return { height: gridHeight, invertedDirections, thumbnailGrid, width: gridWidth, }; }