import React, { useState } from "react"; import { graphql, navigate, Link } from "gatsby"; import { GatsbyImage, getImage } from "gatsby-plugin-image"; import { Helmet } from "react-helmet"; import classnames from "classnames"; import ChevronLeft from '@spectrum-icons/workflow/ChevronLeft'; import ChevronRight from '@spectrum-icons/workflow/ChevronRight'; import Calendar from "@spectrum-icons/workflow/Calendar"; import Stopwatch from "@spectrum-icons/workflow/Stopwatch"; import Exposure from "@spectrum-icons/workflow/Exposure"; import Filmroll from "@spectrum-icons/workflow/Filmroll"; import Camera from "@spectrum-icons/workflow/Camera"; import Circle from "@spectrum-icons/workflow/Circle"; import Location from "@spectrum-icons/workflow/Location"; import { getAspectRatio, getMeta, getName, getShutterFractionFromExposureTime, getVibrant, getHelmetSafeBodyStyle, hasName, getCanonicalSize, getGalleryPageUrl, } from "../../utils"; import MetadataItem from "./MetadataItem"; const logKeyShortcut = (keyCode) => { try { // eslint-disable-next-line window.plausible("KeyShortcut", { props: { keyCode } }); // eslint-disable-next-line _paq.push(["trackEvent", "GalleryImage", "KeyShortcut", keyCode]); } catch (e) { /* do nothing */ } }; const ArrowLinkClasses = `hover:underline text-vibrant-light hover:text-muted-light lg:px-4 self-stretch flex items-center hover:bg-black/50 max-h-screen sticky top-0 `; const GalleryImage = ({ data, location: { state }, }) => { const { sortedImageList, currentIndex, filterKeyword, sortKey } = state ?? {}; const image = data.file; const ar = getAspectRatio(image); const [zoom, setZoom] = useState(false); const nextIndex = sortedImageList && currentIndex < sortedImageList.length ? currentIndex + 1 : null; const prevIndex = sortedImageList && currentIndex > 0 ? currentIndex - 1 : null; const nextImage = sortedImageList && sortedImageList[nextIndex]; const prevImage = sortedImageList && sortedImageList[prevIndex]; React.useEffect(() => { const keyListener = (e) => { switch (e.code) { case "ArrowRight": { logKeyShortcut(e.code); if (nextImage) { navigate(`/photogallery/${nextImage}/`, { state: { currentIndex: currentIndex + 1, sortedImageList, filterKeyword, sortKey, }, }); } return; } case "ArrowLeft": { logKeyShortcut(e.code); if (prevImage) { navigate(`/photogallery/${prevImage}/`, { state: { currentIndex: currentIndex - 1, sortedImageList, filterKeyword, sortKey, }, }); } return; } case "Escape": case "KeyG": { logKeyShortcut(e.code); navigate( getGalleryPageUrl({ keyword: filterKeyword, sortKey }, image.base) ); } } }; document.addEventListener("keydown", keyListener); return () => { document.removeEventListener("keydown", keyListener); }; }, [ nextImage, prevImage, image.base, currentIndex, sortedImageList, filterKeyword, sortKey, ]); const name = getName(image); const { meta, dateTaken: dt } = getMeta(image); let locationString; if (meta.City || meta.State || meta.Location) { const location = [meta.Location, meta.City, meta.State].filter(Boolean); locationString = location.join(", "); } const vibrant = getVibrant(image, true); const canonicalSize = getCanonicalSize(image); const orientationClasses = ar > 1 ? "flex-col mx-auto" : "portrait:mx-auto landscape:mx-5 landscape:flex-row-reverse portrait:flex-col"; const verticalPad = ar > 1 ? "170px" : "70px"; const shutterSpeed = React.useMemo( () => getShutterFractionFromExposureTime(meta.ExposureTime || 0), [meta] ); const dateTaken = React.useMemo(() => new Date(dt), [dt]); return ( <> {name} - Gallery | Chuck Dries
{prevImage && ( )}
setZoom((_zoom) => !_zoom)} style={{ maxWidth: `calc(max(calc(100vh - ${verticalPad}), 500px) * ${ar})`, }} > {zoom ? ( {name} ) : ( )}

{image.base}

{hasName(image) && (

{name}

)}

{meta.Caption}

{ try { window.plausible("Download Wallpaper", { props: { image: image.base }, }); } catch { // do nothing } }} > Download wallpaper
{
}
} title="date taken" />
} title="shutter speed" /> {meta.FNumber && ( } title="aperture" /> )} } title="ISO" />
} title="location" /> {(meta.Make || meta.Model) && ( } title="camera" /> )} {(meta.LensModel || meta.FocalLength) && ( } title="lens" /> )}
{nextImage && ( )}
); }; export const query = graphql` query GalleryImage($imageFilename: String) { file(base: { eq: $imageFilename }) { base publicURL childImageSharp { fluid { aspectRatio } gatsbyImageData( layout: CONSTRAINED placeholder: DOMINANT_COLOR quality: 90 ) } fields { imageMeta { dateTaken meta { Make Model ExposureTime FNumber ISO DateTimeOriginal CreateDate ShutterSpeedValue ApertureValue FocalLength LensModel ObjectName Caption Location City State } vibrant { ...VibrantColors } } } } } `; export default GalleryImage;