fix navigation behavior and homepage layout
This commit is contained in:
parent
5f7ceabf20
commit
5dcc5920c4
@ -63,6 +63,12 @@ const GalleryImage = ({ data, location: { state } }) => {
|
|||||||
setIsClient(true);
|
setIsClient(true);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
window.scrollTo(0, 180);
|
||||||
|
});
|
||||||
|
}, [image.base]);
|
||||||
|
|
||||||
const nextIndex =
|
const nextIndex =
|
||||||
sortedImageList && currentIndex < sortedImageList.length
|
sortedImageList && currentIndex < sortedImageList.length
|
||||||
? currentIndex + 1
|
? currentIndex + 1
|
||||||
@ -135,7 +141,7 @@ 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 BLEND = "hsl";
|
||||||
const darkAccent = chroma
|
const darkAccent = chroma
|
||||||
.mix(vibrant.Vibrant, "hsla(216, 0%, 90%, 1)", 0.6, BLEND)
|
.mix(vibrant.Vibrant, "hsla(216, 0%, 90%, 1)", 0.6, BLEND)
|
||||||
.hex();
|
.hex();
|
||||||
@ -145,7 +151,7 @@ const GalleryImage = ({ data, location: { state } }) => {
|
|||||||
ar > 1
|
ar > 1
|
||||||
? "flex-col"
|
? "flex-col"
|
||||||
: "portrait:mx-auto landscape:mx-5 landscape:flex-row-reverse portrait:flex-col";
|
: "portrait:mx-auto landscape:mx-5 landscape:flex-row-reverse portrait:flex-col";
|
||||||
const verticalPad = ar > 1 ? "250px" : "100px";
|
const verticalPad = ar > 1 ? "180px" : "20px";
|
||||||
|
|
||||||
const shutterSpeed = React.useMemo(
|
const shutterSpeed = React.useMemo(
|
||||||
() =>
|
() =>
|
||||||
|
@ -1,19 +1,17 @@
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import Checkmark from "@spectrum-icons/workflow/Checkmark";
|
|
||||||
import { Link } from "gatsby";
|
import { Link } from "gatsby";
|
||||||
|
|
||||||
interface KeywordsPickerProps {
|
interface KeywordsPickerProps {
|
||||||
keywords: string[];
|
keywords: string[];
|
||||||
value: string | null;
|
value: string | null;
|
||||||
onChange: (val: string | null) => void;
|
getHref: (value: string | null) => string;
|
||||||
|
onPick: (value: string | null) => void;
|
||||||
}
|
}
|
||||||
const KeywordsPicker = ({ keywords, value, onChange }: KeywordsPickerProps) => {
|
const KeywordsPicker = ({ keywords, value, getHref, onPick }: KeywordsPickerProps) => {
|
||||||
return (
|
return (
|
||||||
<div className="mx-2 mt-2">
|
<div className="mx-2 mt-2">
|
||||||
<span className="text-xs text-black">
|
<span className="text-xs text-black">Collections</span>
|
||||||
Collections
|
|
||||||
</span>
|
|
||||||
<ul className="flex gap-1 flex-wrap mt-1 mb-2">
|
<ul className="flex gap-1 flex-wrap mt-1 mb-2">
|
||||||
{keywords.map((keyword) => {
|
{keywords.map((keyword) => {
|
||||||
const selected = value === keyword;
|
const selected = value === keyword;
|
||||||
@ -28,17 +26,11 @@ const KeywordsPicker = ({ keywords, value, onChange }: KeywordsPickerProps) => {
|
|||||||
: `bg-white
|
: `bg-white
|
||||||
hover:bg-black/10`
|
hover:bg-black/10`
|
||||||
)}
|
)}
|
||||||
to={selected ? '/photogallery/' : `?filter=${encodeURIComponent(keyword)}`}
|
onClick={() => onPick(keyword)}
|
||||||
// onClick={() => (selected ? onChange(null) : onChange(keyword))}
|
replace={false}
|
||||||
|
to={getHref(keyword)}
|
||||||
>
|
>
|
||||||
{keyword}{" "}
|
{keyword}{" "}
|
||||||
{/* {selected && (
|
|
||||||
<Checkmark
|
|
||||||
UNSAFE_className="mx-1"
|
|
||||||
UNSAFE_style={{ width: "15px" }}
|
|
||||||
aria-hidden="true"
|
|
||||||
/>
|
|
||||||
)} */}
|
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
|
@ -97,7 +97,6 @@ const MasonryGallery = ({
|
|||||||
|
|
||||||
return R.indexBy(R.prop("startIndex"), _rows);
|
return R.indexBy(R.prop("startIndex"), _rows);
|
||||||
}, [aspectRatios, targetAspect, singleRow]);
|
}, [aspectRatios, targetAspect, singleRow]);
|
||||||
console.log("🚀 ~ file: MasonryGallery.tsx:109 ~ rows:", rows);
|
|
||||||
|
|
||||||
const sortedImageList = React.useMemo(
|
const sortedImageList = React.useMemo(
|
||||||
() => _images.map((image) => image.base),
|
() => _images.map((image) => image.base),
|
||||||
|
@ -108,8 +108,8 @@ const Nav = ({ internalLinks, className }: NavProps) => {
|
|||||||
<StaticImage
|
<StaticImage
|
||||||
alt="A picture of me"
|
alt="A picture of me"
|
||||||
className="relative"
|
className="relative"
|
||||||
src="../images/circle-profile.png"
|
|
||||||
placeholder="tracedSVG"
|
placeholder="tracedSVG"
|
||||||
|
src="../images/circle-profile.png"
|
||||||
style={{
|
style={{
|
||||||
// top: "-70%",
|
// top: "-70%",
|
||||||
// left: "-50%",
|
// left: "-50%",
|
||||||
|
@ -45,22 +45,16 @@ const GalleryPage = ({
|
|||||||
data,
|
data,
|
||||||
location,
|
location,
|
||||||
}: PageProps<Queries.GalleryPageQueryQuery>) => {
|
}: PageProps<Queries.GalleryPageQueryQuery>) => {
|
||||||
// const hash =
|
|
||||||
// typeof window !== "undefined" ? window.location.hash.replace("#", "") : "";
|
|
||||||
|
|
||||||
const hash = location.hash ? location.hash.replace("#", "") : "";
|
const hash = location.hash ? location.hash.replace("#", "") : "";
|
||||||
|
|
||||||
const params = new URLSearchParams(location.search);
|
const params = new URLSearchParams(location.search);
|
||||||
const filterKeyword = params.get("filter");
|
const filterKeyword = params.get("filter");
|
||||||
const sortKey = params.get("sort") ?? "rating";
|
const sortKey = params.get("sort") ?? "rating";
|
||||||
console.log("🚀 ~ file: photogallery.tsx:51 ~ GalleryPage ~ params:", params);
|
|
||||||
|
|
||||||
const [hashCleared, setHashCleared] = React.useState(false); // eslint-disable-line no-unused-vars
|
|
||||||
// ^ used just to force a re-render with the cleared hash value (I know, it's a smell for sure)
|
|
||||||
const showDebug = Boolean(params.get("debug")?.length);
|
const showDebug = Boolean(params.get("debug")?.length);
|
||||||
const [showPalette, setShowPalette] = React.useState(false);
|
const [showPalette, setShowPalette] = React.useState(false);
|
||||||
|
|
||||||
const setKeyword = React.useCallback(
|
const onKeywordPick = React.useCallback(
|
||||||
(newKeyword: string | null) => {
|
(newKeyword: string | null) => {
|
||||||
if (newKeyword) {
|
if (newKeyword) {
|
||||||
try {
|
try {
|
||||||
@ -71,11 +65,8 @@ const GalleryPage = ({
|
|||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
navigate(
|
|
||||||
getGalleryPageUrl({ keyword: newKeyword, sortKey, showDebug }, hash)
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
[sortKey, hash, showDebug]
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
const setSortKey = React.useCallback(
|
const setSortKey = React.useCallback(
|
||||||
@ -106,36 +97,32 @@ const GalleryPage = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
url.hash = "";
|
url.hash = "";
|
||||||
// window.history.pushState(null, "", url.href.toString());
|
|
||||||
navigate(url.href.toString());
|
navigate(url.href.toString());
|
||||||
window.removeEventListener("wheel", removeHash);
|
window.removeEventListener("wheel", removeHash);
|
||||||
setHashCleared(true);
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
window.addEventListener("wheel", removeHash);
|
window.addEventListener("wheel", removeHash);
|
||||||
|
return () => window.removeEventListener("wheel", removeHash);
|
||||||
}, [removeHash]);
|
}, [removeHash]);
|
||||||
|
|
||||||
const scrollIntoView = React.useCallback(() => {
|
|
||||||
if (!hash) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const el = document.getElementById(hash);
|
|
||||||
if (!el) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
el.scrollIntoView({
|
|
||||||
block: hash.startsWith("all") ? "start" : "center",
|
|
||||||
});
|
|
||||||
}, [hash]);
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
// hacky but it works for now
|
// hacky but it works for now
|
||||||
setTimeout(() => {
|
requestAnimationFrame(() => {
|
||||||
// don't scroll into view if user got here with back button
|
// don't scroll into view if user got here with back button
|
||||||
scrollIntoView();
|
if (!hash) {
|
||||||
}, 0);
|
return;
|
||||||
}, [setSortKey, setKeyword, scrollIntoView, location]);
|
}
|
||||||
|
const el = document.getElementById(hash);
|
||||||
|
if (!el) {
|
||||||
|
console.log("⚠️failed to find hash");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
el.scrollIntoView({
|
||||||
|
block: hash.startsWith("all") ? "start" : "center",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}, [hash]);
|
||||||
|
|
||||||
const images: GalleryImage[] = React.useMemo(() => {
|
const images: GalleryImage[] = React.useMemo(() => {
|
||||||
const sort =
|
const sort =
|
||||||
@ -183,11 +170,11 @@ const GalleryPage = ({
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (sortKey === "rating") {
|
if (sortKey === "rating") {
|
||||||
return R.pathOr(null, SORT_KEYS.rating, image);
|
return `[${R.pathOr(null, SORT_KEYS.rating, image)}] ${image.base}`;
|
||||||
}
|
}
|
||||||
if (sortKey === "datePublished") {
|
if (sortKey === "datePublished") {
|
||||||
const date = R.pathOr(null, SORT_KEYS.datePublished, image);
|
const date = R.pathOr(null, SORT_KEYS.datePublished, image);
|
||||||
if(!date) {
|
if (!date) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new Date(date).toLocaleString();
|
return new Date(date).toLocaleString();
|
||||||
@ -236,10 +223,6 @@ const GalleryPage = ({
|
|||||||
{sortKey !== "datePublished" && (
|
{sortKey !== "datePublished" && (
|
||||||
<Link
|
<Link
|
||||||
className="underline cursor-pointer text-gray-500"
|
className="underline cursor-pointer text-gray-500"
|
||||||
// onClick={(e) => {
|
|
||||||
// // e.preventDefault();
|
|
||||||
// // setSortKey("datePublished")
|
|
||||||
// }}
|
|
||||||
to="?sort=datePublished#all"
|
to="?sort=datePublished#all"
|
||||||
>
|
>
|
||||||
show more
|
show more
|
||||||
@ -267,6 +250,12 @@ const GalleryPage = ({
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col lg:flex-row lg: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
|
||||||
|
getHref={(val) =>
|
||||||
|
getGalleryPageUrl(
|
||||||
|
{ keyword: val, sortKey, showDebug },
|
||||||
|
hash
|
||||||
|
)
|
||||||
|
}
|
||||||
keywords={[
|
keywords={[
|
||||||
"Boyce Thompson Arboretum",
|
"Boyce Thompson Arboretum",
|
||||||
"winter",
|
"winter",
|
||||||
@ -283,7 +272,7 @@ const GalleryPage = ({
|
|||||||
// "shoot the light",
|
// "shoot the light",
|
||||||
// "sunset",
|
// "sunset",
|
||||||
]}
|
]}
|
||||||
onChange={setKeyword}
|
onPick={onKeywordPick}
|
||||||
value={filterKeyword}
|
value={filterKeyword}
|
||||||
/>
|
/>
|
||||||
<div className="my-2 mr-2 flex flex-row items-end">
|
<div className="my-2 mr-2 flex flex-row items-end">
|
||||||
@ -324,10 +313,8 @@ const GalleryPage = ({
|
|||||||
"2xl": 6.1,
|
"2xl": 6.1,
|
||||||
"3xl": 8,
|
"3xl": 8,
|
||||||
}}
|
}}
|
||||||
debugHue={sortKey === "hue_debug"}
|
|
||||||
// debugRating={sortKey === "rating" && showDebug}
|
|
||||||
// debugPublished={showDebug}
|
|
||||||
dataFn={dataFn}
|
dataFn={dataFn}
|
||||||
|
debugHue={sortKey === "hue_debug"}
|
||||||
images={images}
|
images={images}
|
||||||
linkState={{
|
linkState={{
|
||||||
sortKey,
|
sortKey,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user