remove two computer pics, improve debug view in gallery, bugfixes
This commit is contained in:
parent
3ed93b14ed
commit
303f20eb93
BIN
data/gallery/DSC09365.jpg
(Stored with Git LFS)
BIN
data/gallery/DSC09365.jpg
(Stored with Git LFS)
Binary file not shown.
BIN
data/gallery/DSC09455.jpg
(Stored with Git LFS)
BIN
data/gallery/DSC09455.jpg
(Stored with Git LFS)
Binary file not shown.
@ -230,7 +230,7 @@ export const onCreateNode: GatsbyNode["onCreateNode"] = async function ({
|
||||
node.absolutePath as string,
|
||||
dominant,
|
||||
// if datePublished is empty, image has not been committed to git yet and is thus brand new
|
||||
datePublished.length ? datePublished : new Date().toISOString()
|
||||
datePublished.length ? datePublished.replace("\n", "") : new Date().toISOString()
|
||||
),
|
||||
});
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ const KeywordsPicker = ({ keywords, value, onChange }: KeywordsPickerProps) => {
|
||||
<li key={keyword}>
|
||||
<Link
|
||||
className={classNames(
|
||||
`py-[5px] px-3 rounded-full text-sm`,
|
||||
`py-[5px] px-3 rounded-full text-sm block`,
|
||||
`text-black border border-gray-400`,
|
||||
selected
|
||||
? "bg-black/10 font-bold"
|
||||
|
@ -23,7 +23,7 @@ interface MasonryGalleryProps {
|
||||
[breakpoint: string]: number;
|
||||
};
|
||||
debugHue?: boolean;
|
||||
debugRating?: boolean;
|
||||
dataFn?: (image: GalleryImage) => (string | null);
|
||||
linkState?: object;
|
||||
showPalette?: boolean;
|
||||
singleRow?: boolean;
|
||||
@ -33,7 +33,7 @@ const MasonryGallery = ({
|
||||
images: _images,
|
||||
aspectsByBreakpoint: aspectTargetsByBreakpoint,
|
||||
debugHue,
|
||||
debugRating,
|
||||
dataFn,
|
||||
linkState,
|
||||
showPalette,
|
||||
singleRow,
|
||||
@ -52,6 +52,7 @@ const MasonryGallery = ({
|
||||
// });
|
||||
|
||||
const { breakpoint } = useBreakpoint(breakpoints, "xs");
|
||||
console.log("🚀 ~ file: MasonryGallery.tsx:55 ~ breakpoint:", breakpoint)
|
||||
|
||||
// const breakpoint = currentBreakpoint.length ? currentBreakpoint : "xs";
|
||||
const galleryWidth = `calc(100vw - ${
|
||||
@ -64,48 +65,39 @@ const MasonryGallery = ({
|
||||
) 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 [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, singleRow]
|
||||
);
|
||||
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]);
|
||||
console.log("🚀 ~ file: MasonryGallery.tsx:109 ~ rows:", rows);
|
||||
|
||||
const sortedImageList = React.useMemo(
|
||||
() => _images.map((image) => image.base),
|
||||
@ -113,7 +105,7 @@ const MasonryGallery = ({
|
||||
);
|
||||
|
||||
const images = singleRow ? _images.slice(0, rows[0].images) : _images;
|
||||
|
||||
|
||||
let cursor = 0;
|
||||
return (
|
||||
<div
|
||||
@ -135,8 +127,10 @@ const MasonryGallery = ({
|
||||
const rowAspectRatioSum = currentRow.aspect;
|
||||
const ar = getAspectRatio(image);
|
||||
let width;
|
||||
let height = `calc(${galleryWidth} / ${rowAspectRatioSum} ${showPalette ? "+ 10px" : "- 10px"})`;
|
||||
if (rowAspectRatioSum < targetAspect * 0.66) {
|
||||
let height = `calc(${galleryWidth} / ${rowAspectRatioSum} ${
|
||||
showPalette ? "+ 10px" : "- 10px"
|
||||
})`;
|
||||
if (rowAspectRatioSum < targetAspect * 0.66 && !singleRow) {
|
||||
// incomplete row, render stuff at "ideal" sizes instead of filling width
|
||||
width = `calc(calc(100vw - 160px) / ${targetAspect / ar})`;
|
||||
height = "unset";
|
||||
@ -147,6 +141,8 @@ const MasonryGallery = ({
|
||||
const vibrant = getVibrant(image);
|
||||
// @ts-ignore
|
||||
const img = getImage(image);
|
||||
|
||||
const data = dataFn ? dataFn(image) : null;
|
||||
return (
|
||||
<Link
|
||||
className={classNames("border-8 border-white overflow-hidden")}
|
||||
@ -170,47 +166,53 @@ const MasonryGallery = ({
|
||||
}}
|
||||
to={`/photogallery/${image.base}/`}
|
||||
>
|
||||
{debugRating && (
|
||||
<span className="text-white z-20 absolute bg-black">
|
||||
rating: {image.fields?.imageMeta?.meta?.Rating}
|
||||
</span>
|
||||
)}
|
||||
{data && <span className="text-white z-20 absolute bg-black">
|
||||
{data}
|
||||
</span>}
|
||||
{img && (
|
||||
<div className={`h-full ${showPalette && "grid grid-rows-[1fr_20px]"}`}>
|
||||
<div
|
||||
className={`h-full ${
|
||||
showPalette && "grid grid-rows-[1fr_20px]"
|
||||
}`}
|
||||
>
|
||||
<GatsbyImage
|
||||
alt={getName(image)}
|
||||
className="w-full"
|
||||
image={img}
|
||||
objectFit="cover"
|
||||
/>
|
||||
{ showPalette && vibrant && <div className="grid grid-cols-6 flex-shrink-0 h-[20px] w-full">
|
||||
<div
|
||||
style={{ background: `rgba(${vibrant.Vibrant?.join(",")})` }}
|
||||
></div>
|
||||
<div
|
||||
style={{
|
||||
background: `rgb(${vibrant.LightVibrant?.join(",")})`,
|
||||
}}
|
||||
></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>}
|
||||
{showPalette && vibrant && (
|
||||
<div className="grid grid-cols-6 flex-shrink-0 h-[20px] w-full">
|
||||
<div
|
||||
style={{
|
||||
background: `rgba(${vibrant.Vibrant?.join(",")})`,
|
||||
}}
|
||||
></div>
|
||||
<div
|
||||
style={{
|
||||
background: `rgb(${vibrant.LightVibrant?.join(",")})`,
|
||||
}}
|
||||
></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>
|
||||
)}
|
||||
</Link>
|
||||
|
@ -4,7 +4,7 @@ import { Link } from "gatsby";
|
||||
import { Popover } from "react-tiny-popover";
|
||||
import { StaticImage } from "gatsby-plugin-image";
|
||||
|
||||
const navClasses = "hover:underline hover:bg-black/10 block p-3 text-black";
|
||||
const navClasses = "hover:underline hover:bg-black/10 block p-3 text-black flex-shrink-0 whitespace-nowrap";
|
||||
|
||||
const ExternalLinks = () => (
|
||||
<ul
|
||||
@ -100,7 +100,7 @@ const Nav = ({ internalLinks, className }: NavProps) => {
|
||||
<div className="flex flex-auto items-center">
|
||||
<div
|
||||
className={classnames(
|
||||
"h-[150px] w-[150px] mr-4 my-6",
|
||||
"h-[120px] w-[120px] mr-4 my-5 flex-shrink-0",
|
||||
// "ml-[-130px]",
|
||||
// "rounded-full overflow-hidden relative"
|
||||
)}
|
||||
@ -109,6 +109,7 @@ const Nav = ({ internalLinks, className }: NavProps) => {
|
||||
alt="A picture of me"
|
||||
className="relative"
|
||||
src="../images/circle-profile.png"
|
||||
placeholder="tracedSVG"
|
||||
style={{
|
||||
// top: "-70%",
|
||||
// left: "-50%",
|
||||
|
12
src/gatsby-types.d.ts
vendored
12
src/gatsby-types.d.ts
vendored
@ -571,7 +571,7 @@ type FileFieldsFilterInput = {
|
||||
};
|
||||
|
||||
type FileFieldsImageMeta = {
|
||||
readonly datePublished: Maybe<Scalars['String']>;
|
||||
readonly datePublished: Maybe<Scalars['Date']>;
|
||||
readonly dateTaken: Maybe<Scalars['Date']>;
|
||||
readonly dominantHue: Maybe<ReadonlyArray<Maybe<Scalars['Float']>>>;
|
||||
readonly meta: Maybe<FileFieldsImageMetaMeta>;
|
||||
@ -580,6 +580,14 @@ type FileFieldsImageMeta = {
|
||||
};
|
||||
|
||||
|
||||
type FileFieldsImageMeta_datePublishedArgs = {
|
||||
difference: InputMaybe<Scalars['String']>;
|
||||
formatString: InputMaybe<Scalars['String']>;
|
||||
fromNow: InputMaybe<Scalars['Boolean']>;
|
||||
locale: InputMaybe<Scalars['String']>;
|
||||
};
|
||||
|
||||
|
||||
type FileFieldsImageMeta_dateTakenArgs = {
|
||||
difference: InputMaybe<Scalars['String']>;
|
||||
formatString: InputMaybe<Scalars['String']>;
|
||||
@ -597,7 +605,7 @@ type FileFieldsImageMetaFieldSelector = {
|
||||
};
|
||||
|
||||
type FileFieldsImageMetaFilterInput = {
|
||||
readonly datePublished: InputMaybe<StringQueryOperatorInput>;
|
||||
readonly datePublished: InputMaybe<DateQueryOperatorInput>;
|
||||
readonly dateTaken: InputMaybe<DateQueryOperatorInput>;
|
||||
readonly dominantHue: InputMaybe<FloatQueryOperatorInput>;
|
||||
readonly meta: InputMaybe<FileFieldsImageMetaMetaFilterInput>;
|
||||
|
@ -102,8 +102,8 @@ const IndexPage = ({
|
||||
objectFit={browserIsLandscape ? "cover" : "contain"}
|
||||
style={{
|
||||
height: screenHeight
|
||||
? `${screenHeight - 360}px`
|
||||
: "calc(100vh-360px)",
|
||||
? `${screenHeight - 268}px`
|
||||
: "calc(100vh-268px)",
|
||||
}}
|
||||
/>
|
||||
</Link>
|
||||
|
@ -41,22 +41,23 @@ function smartCompareDates(
|
||||
return compareDates(SORT_KEYS.date, left, right);
|
||||
}
|
||||
|
||||
const GalleryPage = ({ data, location }: PageProps<Queries.GalleryPageQueryQuery>) => {
|
||||
const GalleryPage = ({
|
||||
data,
|
||||
location,
|
||||
}: PageProps<Queries.GalleryPageQueryQuery>) => {
|
||||
// const hash =
|
||||
// typeof window !== "undefined" ? window.location.hash.replace("#", "") : "";
|
||||
// typeof window !== "undefined" ? window.location.hash.replace("#", "") : "";
|
||||
|
||||
const hash = location.hash ? location.hash.replace("#", "") : "";
|
||||
|
||||
const params = new URLSearchParams(location.search);
|
||||
const filterKeyword = params.get('filter')
|
||||
const sortKey = params.get('sort') ?? "rating"
|
||||
console.log("🚀 ~ file: photogallery.tsx:51 ~ GalleryPage ~ params:", params)
|
||||
const filterKeyword = params.get("filter");
|
||||
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 =
|
||||
typeof window !== "undefined" &&
|
||||
window.location.search.includes("debug=true");
|
||||
const showDebug = Boolean(params.get("debug")?.length);
|
||||
const [showPalette, setShowPalette] = React.useState(false);
|
||||
|
||||
const setKeyword = React.useCallback(
|
||||
@ -70,15 +71,11 @@ const GalleryPage = ({ data, location }: PageProps<Queries.GalleryPageQueryQuery
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
// _setKeyword(newKeyword);
|
||||
// window.history.replaceState(
|
||||
// null,
|
||||
// "",
|
||||
// getGalleryPageUrl({ keyword: newKeyword, sortKey }, hash)
|
||||
// );
|
||||
navigate(getGalleryPageUrl({ keyword: newKeyword, sortKey }, hash))
|
||||
navigate(
|
||||
getGalleryPageUrl({ keyword: newKeyword, sortKey, showDebug }, hash)
|
||||
);
|
||||
},
|
||||
[sortKey, hash]
|
||||
[sortKey, hash, showDebug]
|
||||
);
|
||||
|
||||
const setSortKey = React.useCallback(
|
||||
@ -90,15 +87,15 @@ const GalleryPage = ({ data, location }: PageProps<Queries.GalleryPageQueryQuery
|
||||
} catch (e) {
|
||||
// do nothing
|
||||
}
|
||||
// _setSortKey(newSortKey);
|
||||
// window.history.pushState(
|
||||
// null,
|
||||
// "",
|
||||
// getGalleryPageUrl({ sortKey: newSortKey, keyword: filterKeyword }, hash)
|
||||
// );
|
||||
navigate(getGalleryPageUrl({ sortKey: newSortKey, keyword: filterKeyword }, hash), { replace: true })
|
||||
navigate(
|
||||
getGalleryPageUrl(
|
||||
{ sortKey: newSortKey, keyword: filterKeyword, showDebug },
|
||||
hash
|
||||
),
|
||||
{ replace: true }
|
||||
);
|
||||
},
|
||||
[filterKeyword, hash]
|
||||
[filterKeyword, hash, showDebug]
|
||||
);
|
||||
|
||||
const removeHash = React.useCallback(() => {
|
||||
@ -128,25 +125,11 @@ const GalleryPage = ({ data, location }: PageProps<Queries.GalleryPageQueryQuery
|
||||
return;
|
||||
}
|
||||
el.scrollIntoView({
|
||||
block: hash.startsWith('all') ? "start" : "center",
|
||||
block: hash.startsWith("all") ? "start" : "center",
|
||||
});
|
||||
}, [hash, removeHash]);
|
||||
}, [hash]);
|
||||
|
||||
React.useEffect(() => {
|
||||
// const url = new URL(window.location.toString());
|
||||
|
||||
// const sortKeyFromUrl = url.searchParams.get("sort");
|
||||
// if (sortKeyFromUrl) {
|
||||
// _setSortKey(sortKeyFromUrl);
|
||||
// } else {
|
||||
// _setSortKey('rating')
|
||||
// }
|
||||
|
||||
// const filterKeyFromUrl = url.searchParams.get("filter");
|
||||
// if (filterKeyFromUrl) {
|
||||
// // _setKeyword(filterKeyFromUrl);
|
||||
// }
|
||||
|
||||
// hacky but it works for now
|
||||
setTimeout(() => {
|
||||
// don't scroll into view if user got here with back button
|
||||
@ -192,7 +175,27 @@ const GalleryPage = ({ data, location }: PageProps<Queries.GalleryPageQueryQuery
|
||||
(left, right) => smartCompareDates("datePublished", left, right),
|
||||
data.recents.nodes
|
||||
);
|
||||
}, [data, "hi"]);
|
||||
}, [data]);
|
||||
|
||||
const dataFn = React.useCallback(
|
||||
(image: GalleryImage): string | null => {
|
||||
if (!showDebug) {
|
||||
return null;
|
||||
}
|
||||
if (sortKey === "rating") {
|
||||
return R.pathOr(null, SORT_KEYS.rating, image);
|
||||
}
|
||||
if (sortKey === "datePublished") {
|
||||
const date = R.pathOr(null, SORT_KEYS.datePublished, image);
|
||||
if(!date) {
|
||||
return null;
|
||||
}
|
||||
return new Date(date).toLocaleString();
|
||||
}
|
||||
return null;
|
||||
},
|
||||
[showDebug, sortKey]
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -245,12 +248,12 @@ const GalleryPage = ({ data, location }: PageProps<Queries.GalleryPageQueryQuery
|
||||
</div>
|
||||
<MasonryGallery
|
||||
aspectsByBreakpoint={{
|
||||
xs: 2,
|
||||
sm: 2,
|
||||
md: 3,
|
||||
xs: 3,
|
||||
sm: 3,
|
||||
md: 4,
|
||||
lg: 4,
|
||||
xl: 5,
|
||||
"2xl": 6.1,
|
||||
"2xl": 6,
|
||||
"3xl": 8,
|
||||
}}
|
||||
images={recents}
|
||||
@ -322,7 +325,9 @@ const GalleryPage = ({ data, location }: PageProps<Queries.GalleryPageQueryQuery
|
||||
"3xl": 8,
|
||||
}}
|
||||
debugHue={sortKey === "hue_debug"}
|
||||
debugRating={sortKey === "rating" && showDebug}
|
||||
// debugRating={sortKey === "rating" && showDebug}
|
||||
// debugPublished={showDebug}
|
||||
dataFn={dataFn}
|
||||
images={images}
|
||||
linkState={{
|
||||
sortKey,
|
||||
@ -339,7 +344,7 @@ export const query = graphql`
|
||||
recents: allFile(
|
||||
filter: { sourceInstanceName: { eq: "gallery" } }
|
||||
sort: { fields: { imageMeta: { datePublished: DESC } } }
|
||||
limit: 7
|
||||
limit: 10
|
||||
) {
|
||||
...GalleryImageFile
|
||||
}
|
||||
|
10
src/utils.ts
10
src/utils.ts
@ -102,10 +102,11 @@ export const getShutterFractionFromExposureTime = (exposureTime: number) => {
|
||||
interface galleryPageUrlProps {
|
||||
keyword: string | null;
|
||||
sortKey: string | null;
|
||||
showDebug: boolean;
|
||||
}
|
||||
|
||||
export const getGalleryPageUrl = (
|
||||
{ keyword, sortKey }: galleryPageUrlProps,
|
||||
{ keyword, sortKey, showDebug }: galleryPageUrlProps,
|
||||
hash: string
|
||||
) => {
|
||||
const url = new URL(
|
||||
@ -129,6 +130,9 @@ export const getGalleryPageUrl = (
|
||||
url.searchParams.set("sort", sortKey);
|
||||
}
|
||||
}
|
||||
if (showDebug) {
|
||||
url.searchParams.set("debug", "true");
|
||||
}
|
||||
if (hash) {
|
||||
url.hash = hash;
|
||||
}
|
||||
@ -141,8 +145,8 @@ export function compareDates<T>(
|
||||
right: T
|
||||
): number {
|
||||
// why tf do my dates have newlines in them?!?!
|
||||
const date1 = new Date(pathOr("", date_path, left).replace(/\s/g, ''));
|
||||
const date2 = new Date(pathOr("", date_path, right).replace(/\s/g, ''));
|
||||
const date1 = new Date(pathOr("", date_path, left).replace(/\s/g, ""));
|
||||
const date2 = new Date(pathOr("", date_path, right).replace(/\s/g, ""));
|
||||
const diff = -1 * (date1.getTime() - date2.getTime());
|
||||
return diff;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user