Merge branch 'remove-dynamic-colors' into main

This commit is contained in:
Chuck Dries 2023-01-07 13:25:08 -08:00
commit 7ffb2e31c1
No known key found for this signature in database
GPG Key ID: A00B7AEAE1DC5BE6
11 changed files with 261 additions and 119 deletions

View File

@ -40,41 +40,41 @@ function processColors(vibrantData: Palette, imagePath: string) {
let DarkMuted = chroma(vibrantData.DarkMuted!.getRgb()); let DarkMuted = chroma(vibrantData.DarkMuted!.getRgb());
let LightMuted = chroma(vibrantData.LightMuted!.getRgb()); let LightMuted = chroma(vibrantData.LightMuted!.getRgb());
// first pass - darken bg and lighten relevant fg colors // // first pass - darken bg and lighten relevant fg colors
if ( // if (
badContrast(DarkVibrant, Vibrant) || // badContrast(DarkVibrant, Vibrant) ||
badContrast(DarkVibrant, LightMuted) // badContrast(DarkVibrant, LightMuted)
) { // ) {
DarkVibrant = DarkVibrant.darken(); // DarkVibrant = DarkVibrant.darken();
} // }
if (badContrast(DarkVibrant, Vibrant)) { // if (badContrast(DarkVibrant, Vibrant)) {
Vibrant = Vibrant.brighten(); // Vibrant = Vibrant.brighten();
} // }
if (badContrast(DarkVibrant, Vibrant)) { // if (badContrast(DarkVibrant, Vibrant)) {
Vibrant = Vibrant.brighten(); // Vibrant = Vibrant.brighten();
} // }
// second pass - first doesn't always do enough // // second pass - first doesn't always do enough
if (badContrast(DarkVibrant, Vibrant)) { // if (badContrast(DarkVibrant, Vibrant)) {
Vibrant = Vibrant.brighten(2); // Vibrant = Vibrant.brighten(2);
} // }
if (badContrast(DarkVibrant, LightMuted)) { // if (badContrast(DarkVibrant, LightMuted)) {
LightMuted = LightMuted.brighten(2); // LightMuted = LightMuted.brighten(2);
} // }
// only used for hover styles, so we should give it a shot but it's not a huge deal if it's not very legible // // only used for hover styles, so we should give it a shot but it's not a huge deal if it's not very legible
if (badContrast(Muted, LightMuted)) { // if (badContrast(Muted, LightMuted)) {
Muted = Muted.darken(); // Muted = Muted.darken();
} // }
if (badContrast(DarkVibrant, Vibrant)) { // if (badContrast(DarkVibrant, Vibrant)) {
console.warn("contrast still too low", imagePath); // console.warn("contrast still too low", imagePath);
logColorsWithContrast(Vibrant, DarkVibrant, "V-DV"); // logColorsWithContrast(Vibrant, DarkVibrant, "V-DV");
} // }
if (badContrast(DarkVibrant, LightMuted)) { // if (badContrast(DarkVibrant, LightMuted)) {
console.warn("contrast still too low", imagePath); // console.warn("contrast still too low", imagePath);
logColorsWithContrast(LightMuted, DarkVibrant, "LM-DV"); // logColorsWithContrast(LightMuted, DarkVibrant, "LM-DV");
} // }
return { return {
Vibrant: Vibrant.rgb(), Vibrant: Vibrant.rgb(),

View File

@ -51,7 +51,7 @@
"react-cool-dimensions": "^2.0.7", "react-cool-dimensions": "^2.0.7",
"react-div-100vh": "^0.7.0", "react-div-100vh": "^0.7.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-helmet": "^6.1.0", "react-helmet": "latest",
"react-stately": "^3.19.0", "react-stately": "^3.19.0",
"react-tiny-popover": "^7.2.0", "react-tiny-popover": "^7.2.0",
"sass": "^1.34.0", "sass": "^1.34.0",

View File

@ -3,6 +3,7 @@ import { graphql, navigate, Link } from "gatsby";
import { GatsbyImage, getImage } from "gatsby-plugin-image"; import { GatsbyImage, getImage } from "gatsby-plugin-image";
import { Helmet } from "react-helmet"; import { Helmet } from "react-helmet";
import classnames from "classnames"; import classnames from "classnames";
import chroma, { Color } from "chroma-js";
import ChevronLeft from "@spectrum-icons/workflow/ChevronLeft"; import ChevronLeft from "@spectrum-icons/workflow/ChevronLeft";
import ChevronRight from "@spectrum-icons/workflow/ChevronRight"; import ChevronRight from "@spectrum-icons/workflow/ChevronRight";
@ -25,6 +26,7 @@ import {
hasName, hasName,
getCanonicalSize, getCanonicalSize,
getGalleryPageUrl, getGalleryPageUrl,
getVibrantStyle,
} from "../../utils"; } from "../../utils";
import MetadataItem from "./MetadataItem"; import MetadataItem from "./MetadataItem";
import Nav from "../Nav"; import Nav from "../Nav";
@ -41,11 +43,11 @@ const logKeyShortcut = (keyCode) => {
}; };
const IconStyle = { const IconStyle = {
width: '24px', width: "24px",
margin: '0 4px' margin: "0 4px",
} };
const ArrowLinkClasses = `hover:underline text-vibrant-light hover:text-muted-light const ArrowLinkClasses = `hover:underline text-black
lg:px-4 self-stretch flex items-center hover:bg-black/50 max-h-screen sticky top-0 lg:px-4 self-stretch flex items-center hover:bg-black/50 max-h-screen sticky top-0
`; `;
@ -133,6 +135,10 @@ const GalleryImage = ({ data, location: { state } }) => {
locationString = location.join(", "); locationString = location.join(", ");
} }
const vibrant = getVibrant(image, true); const vibrant = getVibrant(image, true);
const BLEND = 'hsl'
const darkAccent = chroma
.mix(vibrant.Vibrant, "hsla(216, 0%, 90%, 1)", 0.6, BLEND)
.hex();
const canonicalSize = getCanonicalSize(image); const canonicalSize = getCanonicalSize(image);
const orientationClasses = const orientationClasses =
@ -142,7 +148,10 @@ const GalleryImage = ({ data, location: { state } }) => {
const verticalPad = ar > 1 ? "250px" : "100px"; const verticalPad = ar > 1 ? "250px" : "100px";
const shutterSpeed = React.useMemo( const shutterSpeed = React.useMemo(
() => meta.ExposureTime ? getShutterFractionFromExposureTime(meta.ExposureTime) : null, () =>
meta.ExposureTime
? getShutterFractionFromExposureTime(meta.ExposureTime)
: null,
[meta] [meta]
); );
const dateTaken = React.useMemo(() => new Date(dt), [dt]); const dateTaken = React.useMemo(() => new Date(dt), [dt]);
@ -151,8 +160,11 @@ const GalleryImage = ({ data, location: { state } }) => {
<Helmet> <Helmet>
<title>{name} - Gallery | Chuck Dries</title> <title>{name} - Gallery | Chuck Dries</title>
<body <body
className="text-vibrant-light bg-vibrant-dark transition-colors" className="text-black transition-colors"
style={getHelmetSafeBodyStyle(vibrant)} // style={getHelmetSafeBodyStyle(vibrant)}
style={getHelmetSafeBodyStyle({
background: chroma.mix(vibrant.Vibrant, "white", 0.7, BLEND).hex(),
})}
/> />
</Helmet> </Helmet>
<div className="min-h-screen flex flex-col justify-between overflow-x-hidden"> <div className="min-h-screen flex flex-col justify-between overflow-x-hidden">
@ -167,7 +179,13 @@ const GalleryImage = ({ data, location: { state } }) => {
), ),
label: ( label: (
<> <>
Gallery <kbd className="font-normal">esc</kbd> Gallery{" "}
<kbd
className="font-normal"
style={{ background: darkAccent }}
>
esc
</kbd>
</> </>
), ),
}, },
@ -186,7 +204,12 @@ const GalleryImage = ({ data, location: { state } }) => {
}} }}
to={`/photogallery/${prevImage}/`} to={`/photogallery/${prevImage}/`}
> >
<span className="p-1 lg:p-4 bg-muted-light/25 rounded-full"> <span
className="p-1 lg:p-4 rounded-full"
style={{
background: darkAccent,
}}
>
<ChevronLeft UNSAFE_style={IconStyle} /> <ChevronLeft UNSAFE_style={IconStyle} />
</span> </span>
</Link> </Link>
@ -216,7 +239,7 @@ const GalleryImage = ({ data, location: { state } }) => {
) : ( ) : (
<GatsbyImage <GatsbyImage
alt={name} alt={name}
className="border-4 border-vibrant" className="border-4 border-black"
image={getImage(image)} image={getImage(image)}
key={image.base} key={image.base}
loading="eager" loading="eager"
@ -232,39 +255,68 @@ const GalleryImage = ({ data, location: { state } }) => {
: "flex-row landscape:container portrait:pt-5 portrait:flex-col portrait:text-right portrait:items-end" : "flex-row landscape:container portrait:pt-5 portrait:flex-col portrait:text-right portrait:items-end"
)} )}
> >
<div className="mr-2"> <div className="mr-2 flex flex-col">
<p className="text-muted-light font-mono text-sm m-0 mt-1"> <p className="font-mono text-sm m-0 mt-1">{image.base}</p>
{image.base}
</p>
{hasName(image) && ( {hasName(image) && (
<h1 className="text-4xl mt-0 font-sans">{name}</h1> <h1 className="text-4xl mt-0 font-sans">{name}</h1>
)} )}
<p className="landscape:mr-2">{meta.Caption}</p> <p className="landscape:mr-2">{meta.Caption}</p>
<a <div
className="cursor-pointer inline-block bg-muted-light text-vibrant-dark font-sans p-1 my-1 rounded" className={classnames(
download "grid grid-cols-6 h-[40px] w-[240px]",
href={image.publicURL} ar <= 1 ? "self-end" : "portrait:self-end"
onClick={() => { )}
try {
window.plausible("Download Wallpaper", {
props: { image: image.base },
});
} catch {
// do nothing
}
}}
> >
Download wallpaper <div
</a> style={{ background: `rgba(${vibrant.Vibrant.join(",")})` }}
<div className="grid grid-cols-6 w-full h-[30px]"> ></div>
<div className="bg-vibrant"></div> <div
<div className="bg-vibrant-light"></div> style={{
<div className="bg-vibrant-dark"></div> background: `rgb(${vibrant.LightVibrant.join(",")})`,
<div className="bg-muted"></div> }}
<div className="bg-muted-light"></div> ></div>
<div className="bg-muted-dark"></div> <div
style={{
background: `rgb(${vibrant.DarkVibrant.join(",")})`,
}}
></div>
<div
style={{ background: `rgb(${vibrant.Muted.join(",")})` }}
></div>
<div
style={{
background: `rgb(${vibrant.LightMuted.join(",")})`,
}}
></div>
<div
style={{
background: `rgb(${vibrant.DarkMuted.join(",")})`,
}}
></div>
</div> </div>
</div><div className="flex-auto"></div> <div className="my-2">
<a
className="cursor-pointer text-black font-sans p-1 rounded"
download
href={image.publicURL}
onClick={() => {
try {
window.plausible("Download Wallpaper", {
props: { image: image.base },
});
} catch {
// do nothing
}
}}
style={{
background: darkAccent,
}}
>
Download wallpaper
</a>
</div>
</div>
<div className="flex-auto"></div>
{ {
<div <div
className="portrait:border-t-2 border-muted-light portrait:mt-2 mr-2 portrait:mb-1" className="portrait:border-t-2 border-muted-light portrait:mt-2 mr-2 portrait:mb-1"
@ -277,7 +329,7 @@ const GalleryImage = ({ data, location: { state } }) => {
icon={<Calendar UNSAFE_style={IconStyle} />} icon={<Calendar UNSAFE_style={IconStyle} />}
title="date taken" title="date taken"
/> />
<div className="sm:flex justify-end gap-2 border border-vibrant-light pl-2 rounded"> <div className="sm:flex justify-end gap-2 border border-gray-500 pl-2 rounded">
<MetadataItem <MetadataItem
data={shutterSpeed} data={shutterSpeed}
icon={<Stopwatch UNSAFE_style={IconStyle} />} icon={<Stopwatch UNSAFE_style={IconStyle} />}
@ -315,7 +367,7 @@ const GalleryImage = ({ data, location: { state } }) => {
)} )}
{(meta.LensModel || meta.FocalLength) && ( {(meta.LensModel || meta.FocalLength) && (
<MetadataItem <MetadataItem
data={ meta.LensModel === "----" ? null : meta.LensModel} data={meta.LensModel === "----" ? null : meta.LensModel}
icon={<Circle UNSAFE_style={IconStyle} />} icon={<Circle UNSAFE_style={IconStyle} />}
title="lens" title="lens"
/> />
@ -334,7 +386,12 @@ const GalleryImage = ({ data, location: { state } }) => {
}} }}
to={`/photogallery/${nextImage}/`} to={`/photogallery/${nextImage}/`}
> >
<span className="p-1 lg:p-4 bg-muted-light/25 rounded-full"> <span
className="p-1 lg:p-4 rounded-full"
style={{
background: darkAccent,
}}
>
<ChevronRight UNSAFE_style={IconStyle} /> <ChevronRight UNSAFE_style={IconStyle} />
</span> </span>
</Link> </Link>

View File

@ -25,6 +25,7 @@ interface MasonryGalleryProps {
debugHue?: boolean; debugHue?: boolean;
debugRating?: boolean; debugRating?: boolean;
linkState?: object; linkState?: object;
showPalette?: boolean;
} }
const MasonryGallery = ({ const MasonryGallery = ({
@ -33,6 +34,7 @@ const MasonryGallery = ({
debugHue, debugHue,
debugRating, debugRating,
linkState, linkState,
showPalette,
}: MasonryGalleryProps) => { }: MasonryGalleryProps) => {
const [isClient, setIsClient] = React.useState(false); const [isClient, setIsClient] = React.useState(false);
React.useEffect(() => { React.useEffect(() => {
@ -124,7 +126,7 @@ const MasonryGallery = ({
const rowAspectRatioSum = currentRow.aspect; const rowAspectRatioSum = currentRow.aspect;
const ar = getAspectRatio(image); const ar = getAspectRatio(image);
let width; let width;
let height = `calc(${galleryWidth} / ${rowAspectRatioSum} + 10px)`; let height = `calc(${galleryWidth} / ${rowAspectRatioSum} ${showPalette ? "+ 10px" : "- 10px"})`;
if (rowAspectRatioSum < targetAspect * 0.66) { if (rowAspectRatioSum < targetAspect * 0.66) {
// incomplete row, render stuff at "ideal" sizes instead of filling width // incomplete row, render stuff at "ideal" sizes instead of filling width
width = `calc(calc(100vw - 160px) / ${targetAspect / ar})`; width = `calc(calc(100vw - 160px) / ${targetAspect / ar})`;
@ -137,9 +139,7 @@ const MasonryGallery = ({
const img = getImage(image); const img = getImage(image);
return ( return (
<Link <Link
className={classNames( className={classNames("border-8 border-white overflow-hidden")}
"border-8 border-white overflow-hidden"
)}
id={image.base} id={image.base}
key={`${image.base}`} key={`${image.base}`}
state={{ state={{
@ -166,13 +166,22 @@ const MasonryGallery = ({
</span> </span>
)} )}
{img && ( {img && (
<div className={`h-full ${showPalette && "grid grid-rows-[1fr_20px]"}`}>
<GatsbyImage <GatsbyImage
alt={getName(image)} alt={getName(image)}
className="w-full h-full" className="w-full"
image={img} image={img}
objectFit="cover" objectFit="cover"
/> />
{ showPalette && <div className="grid grid-cols-6 flex-shrink-0 h-[20px] w-full" style={getVibrantStyle(getVibrant(image))}>
<div className="bg-vibrant"></div>
<div className="bg-vibrant-light"></div>
<div className="bg-vibrant-dark"></div>
<div className="bg-muted"></div>
<div className="bg-muted-light"></div>
<div className="bg-muted-dark"></div>
</div>}
</div>
)} )}
</Link> </Link>
); );

View File

@ -4,7 +4,7 @@ import { Link } from "gatsby";
import { Popover } from "react-tiny-popover"; import { Popover } from "react-tiny-popover";
const navClasses = const navClasses =
"hover:underline hover:bg-transparentblack block p-3 text-vibrant-light"; "hover:underline hover:bg-transparentblack block p-3 text-black";
const ExternalLinks = () => ( const ExternalLinks = () => (
<ul <ul

60
src/components/Switch.tsx Normal file
View File

@ -0,0 +1,60 @@
import * as React from "react";
import { useToggleState } from "react-stately";
import {
AriaSwitchProps,
useFocusRing,
useSwitch,
VisuallyHidden,
} from "react-aria";
export function Switch(props: AriaSwitchProps) {
let state = useToggleState(props);
let ref = React.useRef<HTMLInputElement>(null);
let { inputProps } = useSwitch(props, state, ref);
let { isFocusVisible, focusProps } = useFocusRing();
return (
<label
className="text-sm p-2"
style={{
display: "flex",
alignItems: "center",
opacity: props.isDisabled ? 0.4 : 1,
}}
>
<VisuallyHidden>
<input {...inputProps} {...focusProps} ref={ref} />
</VisuallyHidden>
<svg
className="flex-shrink-0"
width={40}
height={24}
aria-hidden="true"
style={{ marginRight: 4 }}
>
<rect
x={4}
y={4}
width={32}
height={16}
rx={8}
fill={state.isSelected ? "orange" : "gray"}
/>
<circle cx={state.isSelected ? 28 : 12} cy={12} r={5} fill="white" />
{isFocusVisible && (
<rect
x={1}
y={1}
width={38}
height={22}
rx={11}
fill="none"
stroke="orange"
strokeWidth={2}
/>
)}
</svg>
{props.children}
</label>
);
}

View File

@ -2550,7 +2550,7 @@ type GalleryImageQuery = { readonly file: { readonly base: string, readonly publ
type GalleryPageQueryQueryVariables = Exact<{ [key: string]: never; }>; type GalleryPageQueryQueryVariables = Exact<{ [key: string]: never; }>;
type GalleryPageQueryQuery = { readonly allFile: { readonly nodes: ReadonlyArray<{ readonly relativePath: string, readonly base: string, readonly childImageSharp: { readonly gatsbyImageData: import('gatsby-plugin-image').IGatsbyImageData, readonly fluid: { readonly aspectRatio: number } | null } | null, readonly fields: { readonly imageMeta: { readonly vibrantHue: number | null, readonly dominantHue: ReadonlyArray<number | null> | null, readonly dateTaken: string | null, readonly meta: { readonly Keywords: ReadonlyArray<string | null> | null, readonly Rating: number | null, readonly ObjectName: string | null } | null, readonly vibrant: { readonly Vibrant: ReadonlyArray<number | null> | null } | null } | null } | null }> } }; type GalleryPageQueryQuery = { readonly allFile: { readonly nodes: ReadonlyArray<{ readonly relativePath: string, readonly base: string, readonly childImageSharp: { readonly gatsbyImageData: import('gatsby-plugin-image').IGatsbyImageData, readonly fluid: { readonly aspectRatio: number } | null } | null, readonly fields: { readonly imageMeta: { readonly vibrantHue: number | null, readonly dominantHue: ReadonlyArray<number | null> | null, readonly dateTaken: string | null, readonly meta: { readonly Keywords: ReadonlyArray<string | null> | null, readonly Rating: number | null, readonly ObjectName: string | null } | null, readonly vibrant: { readonly DarkMuted: ReadonlyArray<number | null> | null, readonly DarkVibrant: ReadonlyArray<number | null> | null, readonly LightMuted: ReadonlyArray<number | null> | null, readonly LightVibrant: ReadonlyArray<number | null> | null, readonly Vibrant: ReadonlyArray<number | null> | null, readonly Muted: ReadonlyArray<number | null> | null } | null } | null } | null }> } };
type GatsbyImageSharpFixedFragment = { readonly base64: string | null, readonly width: number, readonly height: number, readonly src: string, readonly srcSet: string }; type GatsbyImageSharpFixedFragment = { readonly base64: string | null, readonly width: number, readonly height: number, readonly src: string, readonly srcSet: string };

View File

@ -5,7 +5,7 @@ import { Helmet } from "react-helmet";
// import { take } from "ramda"; // import { take } from "ramda";
import classnames from "classnames"; import classnames from "classnames";
import { getHelmetSafeBodyStyle, getAspectRatio } from "../utils"; import { getHelmetSafeBodyStyle, getAspectRatio, getVibrantStyle } from "../utils";
import Nav from "../components/Nav"; import Nav from "../components/Nav";
// import ActionButtons from "../components/index/ActionButtons"; // import ActionButtons from "../components/index/ActionButtons";
import { use100vh } from "react-div-100vh"; import { use100vh } from "react-div-100vh";
@ -73,14 +73,14 @@ const IndexPage = ({
<body <body
className="bg-white transition-colors" className="bg-white transition-colors"
// @ts-ignore // @ts-ignore
style={getHelmetSafeBodyStyle({ style={getHelmetSafeBodyStyle(getVibrantStyle({
Muted: [0, 0, 0], Muted: [0, 0, 0],
LightMuted: [0, 0, 0], LightMuted: [0, 0, 0],
Vibrant: [0, 0, 0], Vibrant: [0, 0, 0],
LightVibrant: [0, 0, 0], LightVibrant: [0, 0, 0],
DarkMuted: [238, 238, 238], DarkMuted: [238, 238, 238],
DarkVibrant: [238, 238, 238], DarkVibrant: [238, 238, 238],
})} }))}
/> />
</Helmet> </Helmet>
<main className="font-sans flex flex-col h-screen"> <main className="font-sans flex flex-col h-screen">

View File

@ -6,9 +6,10 @@ import { Helmet } from "react-helmet";
import MasonryGallery from "../components/MasonryGallery"; import MasonryGallery from "../components/MasonryGallery";
import KeywordsPicker from "../components/KeywordsPicker"; import KeywordsPicker from "../components/KeywordsPicker";
import { getGalleryPageUrl, getHelmetSafeBodyStyle } from "../utils"; import { getGalleryPageUrl, getHelmetSafeBodyStyle, getVibrantStyle } from "../utils";
import Nav from "../components/Nav"; import Nav from "../components/Nav";
import { Item, Select } from "../components/Select"; import { Item, Select } from "../components/Select";
import { Switch } from "../components/Switch";
const SORT_KEYS = { const SORT_KEYS = {
hue: ["fields", "imageMeta", "vibrantHue"], hue: ["fields", "imageMeta", "vibrantHue"],
@ -31,6 +32,7 @@ const GalleryPage = ({ data }: PageProps<Queries.GalleryPageQueryQuery>) => {
const showDebug = const showDebug =
typeof window !== "undefined" && typeof window !== "undefined" &&
window.location.search.includes("debug=true"); window.location.search.includes("debug=true");
const [showPalette, setShowPalette] = React.useState(false);
const setKeyword = React.useCallback( const setKeyword = React.useCallback(
(newKeyword: string | null) => { (newKeyword: string | null) => {
@ -166,14 +168,14 @@ const GalleryPage = ({ data }: PageProps<Queries.GalleryPageQueryQuery>) => {
<body <body
className="bg-white transition-color" className="bg-white transition-color"
// @ts-ignore // @ts-ignore
style={getHelmetSafeBodyStyle({ style={getHelmetSafeBodyStyle(getVibrantStyle({
Muted: [0, 0, 0], Muted: [0, 0, 0],
LightMuted: [0, 0, 0], LightMuted: [0, 0, 0],
Vibrant: [0, 0, 0], Vibrant: [0, 0, 0],
LightVibrant: [0, 0, 0], LightVibrant: [0, 0, 0],
DarkMuted: [238, 238, 238], DarkMuted: [238, 238, 238],
DarkVibrant: [238, 238, 238], DarkVibrant: [238, 238, 238],
})} }))}
/> />
</Helmet> </Helmet>
<div className="top-0 z-10"> <div className="top-0 z-10">
@ -186,7 +188,7 @@ const GalleryPage = ({ data }: PageProps<Queries.GalleryPageQueryQuery>) => {
]} ]}
/> />
</div> </div>
<div className="flex flex-col md:flex-row md:items-end justify-between px-4 md:px-8 sm:mx-auto"> <div className="flex flex-col lg:flex-row lg:items-end justify-between px-4 md:px-8 sm:mx-auto">
<KeywordsPicker <KeywordsPicker
keywords={[ keywords={[
"Boyce Thompson Arboretum", "Boyce Thompson Arboretum",
@ -207,7 +209,13 @@ const GalleryPage = ({ data }: PageProps<Queries.GalleryPageQueryQuery>) => {
onChange={setKeyword} onChange={setKeyword}
value={filterKeyword} value={filterKeyword}
/> />
<div className="m-2"> <div className="m-2 flex flex-row items-end">
<Switch
isSelected={showPalette}
onChange={(val) => setShowPalette(val)}
>
Show palettes
</Switch>
<Select <Select
label="Sort by..." label="Sort by..."
// @ts-ignore // @ts-ignore
@ -238,42 +246,50 @@ const GalleryPage = ({ data }: PageProps<Queries.GalleryPageQueryQuery>) => {
sortKey, sortKey,
filterKeyword, filterKeyword,
}} }}
showPalette={showPalette}
/> />
</> </>
); );
}; };
export const query = graphql`query GalleryPageQuery { export const query = graphql`
allFile( query GalleryPageQuery {
filter: {sourceInstanceName: {eq: "gallery"}} allFile(
sort: {fields: {imageMeta: {dateTaken: DESC}}} filter: { sourceInstanceName: { eq: "gallery" } }
) { sort: { fields: { imageMeta: { dateTaken: DESC } } }
nodes { ) {
relativePath nodes {
base relativePath
childImageSharp { base
fluid { childImageSharp {
aspectRatio fluid {
} aspectRatio
gatsbyImageData(layout: CONSTRAINED, height: 550, placeholder: DOMINANT_COLOR)
}
fields {
imageMeta {
vibrantHue
dominantHue
dateTaken
meta {
Keywords
Rating
ObjectName
} }
vibrant { gatsbyImageData(
Vibrant layout: CONSTRAINED
height: 550
placeholder: DOMINANT_COLOR
)
}
fields {
imageMeta {
vibrantHue
dominantHue
dateTaken
meta {
Keywords
Rating
ObjectName
}
vibrant {
# Vibrant
...VibrantColors
}
} }
} }
} }
} }
} }
}`; `;
export default GalleryPage; export default GalleryPage;

View File

@ -1,5 +1,6 @@
// import kebabCase from 'lodash/kebabCase'; // import kebabCase from 'lodash/kebabCase';
import React from "react";
import { HomepageImage } from "./pages"; import { HomepageImage } from "./pages";
import { GalleryImage } from "./pages/photogallery"; import { GalleryImage } from "./pages/photogallery";
@ -35,8 +36,7 @@ export const getVibrantStyle = (vibrant: Queries.FileFieldsImageMetaVibrant, scr
}); });
// work around SSR bug in react-helmet // work around SSR bug in react-helmet
export const getHelmetSafeBodyStyle = (vibrant: Queries.FileFieldsImageMetaVibrant, screenHeight?: number) => { export const getHelmetSafeBodyStyle = (style: React.CSSProperties) => {
const style = getVibrantStyle(vibrant, screenHeight);
if (typeof window === "undefined") { if (typeof window === "undefined") {
return style; return style;
} }

View File

@ -6506,7 +6506,7 @@ __metadata:
react-cool-dimensions: ^2.0.7 react-cool-dimensions: ^2.0.7
react-div-100vh: ^0.7.0 react-div-100vh: ^0.7.0
react-dom: ^18.2.0 react-dom: ^18.2.0
react-helmet: ^6.1.0 react-helmet: latest
react-stately: ^3.19.0 react-stately: ^3.19.0
react-tiny-popover: ^7.2.0 react-tiny-popover: ^7.2.0
sass: ^1.34.0 sass: ^1.34.0
@ -13794,7 +13794,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"react-helmet@npm:^6.1.0": "react-helmet@npm:latest":
version: 6.1.0 version: 6.1.0
resolution: "react-helmet@npm:6.1.0" resolution: "react-helmet@npm:6.1.0"
dependencies: dependencies: