import * as React from "react"; import { Link } from "gatsby"; import { GatsbyImage, getImage } from "gatsby-plugin-image"; import * as R from "ramda"; import { getAspectRatio, getVibrantStyle, getName, getVibrant } from "../utils"; import useBreakpoint from "use-breakpoint"; // @ts-ignore import themeBreakpoints from "../breakpoints"; import classNames from "classnames"; // import useDimensions from "react-cool-dimensions"; import { GalleryImage } from "../pages/photogallery"; interface Row { aspect: number; images: number; startIndex: number; } interface MasonryGalleryProps { images: readonly GalleryImage[]; aspectsByBreakpoint: { [breakpoint: string]: number; }; debugHue?: boolean; dataFn?: (image: GalleryImage) => string[] | null; linkState?: object; showPalette?: boolean; singleRow?: boolean; } const MasonryGallery = ({ images: _images, aspectsByBreakpoint: aspectTargetsByBreakpoint, debugHue, dataFn, linkState, showPalette, singleRow, }: MasonryGalleryProps) => { const [isClient, setIsClient] = React.useState(false); React.useEffect(() => { setIsClient(true); }, []); const breakpoints = React.useMemo( () => R.pick(R.keys(aspectTargetsByBreakpoint), themeBreakpoints), [aspectTargetsByBreakpoint] ); const { breakpoint } = useBreakpoint(breakpoints, "xs"); const galleryWidth = `calc(100vw - ${ breakpoint === "xs" || breakpoint === "sm" ? "32" : "160" }px)`; const aspectRatios = React.useMemo( () => R.map(getAspectRatio, _images).filter(Boolean), [_images] ) as number[]; const targetAspect = aspectTargetsByBreakpoint[breakpoint]; const rows = React.useMemo(() => { const _rows: Row[] = [{ aspect: 0, startIndex: 0, images: 0 }]; for (const currentAspect of aspectRatios) { const currentRow = _rows[_rows.length - 1]; const currentDiff = Math.abs(targetAspect - currentRow.aspect); const diffIfImageIsAddedToCurrentRow = Math.abs( targetAspect - (currentRow.aspect + currentAspect) ); // does adding current image to our row get us closer to our target aspect ratio? if (currentDiff > diffIfImageIsAddedToCurrentRow) { currentRow.aspect += currentAspect; currentRow.images += 1; // _rows.push(currentRow); continue; } if (singleRow) { break; } // start a new row _rows.push({ aspect: currentAspect, images: 1, startIndex: currentRow.startIndex + currentRow.images, }); } return R.indexBy(R.prop("startIndex"), _rows); }, [aspectRatios, targetAspect, singleRow]); const sortedImageList = React.useMemo( () => _images.map((image) => image.base), [_images] ); const images = singleRow ? _images.slice(0, rows[0].images) : _images; let cursor = 0; return (