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; debugRating?: boolean; linkState?: object; showPalette?: boolean; singleRow?: boolean; } const MasonryGallery = ({ images, aspectsByBreakpoint: aspectTargetsByBreakpoint, debugHue, debugRating, 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 { observe, currentBreakpoint } = useDimensions({ // breakpoints, // }); const { breakpoint } = useBreakpoint(breakpoints, "xs"); // const breakpoint = currentBreakpoint.length ? currentBreakpoint : "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( () => R.pipe( R.reduce( (acc, currentAspect: number): Row[] => { const currentRow = acc.pop()!; const currentDiff = Math.abs(targetAspect - currentRow.aspect); const diffIfImageIsAddedToCurrentRow = Math.abs( targetAspect - (currentRow.aspect + currentAspect) ); // add image to current row if it gets us closer to our target aspect ratio if (currentDiff > diffIfImageIsAddedToCurrentRow) { return [ ...acc, { aspect: currentRow.aspect + currentAspect, images: currentRow.images + 1, startIndex: currentRow.startIndex, }, ]; } // no-op instead of starting a new row if (singleRow) { return [ ...acc, currentRow, ] } // start a new row return [ ...acc, currentRow, { aspect: currentAspect, images: 1, startIndex: currentRow.startIndex + currentRow.images, } as Row, ]; }, [{ aspect: 0, startIndex: 0, images: 0 }] as Row[] ), R.indexBy(R.prop("startIndex")) )(aspectRatios), [aspectRatios, targetAspect] ); const sortedImageList = React.useMemo( () => images.map((image) => image.base), [images] ); let cursor = 0; return (