Merge branch 'scrolling-stuff' into main
This commit is contained in:
commit
ea37aa680c
BIN
.yarn/cache/@types-lodash-npm-4.14.191-67a04a969b-ba0d5434e1.zip
vendored
Normal file
BIN
.yarn/cache/@types-lodash-npm-4.14.191-67a04a969b-ba0d5434e1.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@types-lodash.debounce-npm-4.0.7-efe92bf273-e873b2d77f.zip
vendored
Normal file
BIN
.yarn/cache/@types-lodash.debounce-npm-4.0.7-efe92bf273-e873b2d77f.zip
vendored
Normal file
Binary file not shown.
BIN
data/gallery/DSC00003.jpg
(Stored with Git LFS)
BIN
data/gallery/DSC00003.jpg
(Stored with Git LFS)
Binary file not shown.
BIN
data/gallery/DSC00015.jpg
(Stored with Git LFS)
BIN
data/gallery/DSC00015.jpg
(Stored with Git LFS)
Binary file not shown.
BIN
data/gallery/DSC00159-2.jpg
(Stored with Git LFS)
BIN
data/gallery/DSC00159-2.jpg
(Stored with Git LFS)
Binary file not shown.
BIN
data/gallery/DSC05702.jpg
(Stored with Git LFS)
BIN
data/gallery/DSC05702.jpg
(Stored with Git LFS)
Binary file not shown.
BIN
data/gallery/DSC06124.jpg
(Stored with Git LFS)
BIN
data/gallery/DSC06124.jpg
(Stored with Git LFS)
Binary file not shown.
BIN
data/gallery/DSC06719.jpg
(Stored with Git LFS)
BIN
data/gallery/DSC06719.jpg
(Stored with Git LFS)
Binary file not shown.
BIN
data/gallery/DSC06803.jpg
(Stored with Git LFS)
BIN
data/gallery/DSC06803.jpg
(Stored with Git LFS)
Binary file not shown.
BIN
data/gallery/DSC08086.jpg
(Stored with Git LFS)
BIN
data/gallery/DSC08086.jpg
(Stored with Git LFS)
Binary file not shown.
BIN
data/gallery/DSC08103.jpg
(Stored with Git LFS)
BIN
data/gallery/DSC08103.jpg
(Stored with Git LFS)
Binary file not shown.
BIN
data/gallery/DSC08222.jpg
(Stored with Git LFS)
BIN
data/gallery/DSC08222.jpg
(Stored with Git LFS)
Binary file not shown.
BIN
data/gallery/DSC08263.jpg
(Stored with Git LFS)
BIN
data/gallery/DSC08263.jpg
(Stored with Git LFS)
Binary file not shown.
BIN
data/gallery/DSC09447.jpg
(Stored with Git LFS)
BIN
data/gallery/DSC09447.jpg
(Stored with Git LFS)
Binary file not shown.
BIN
data/gallery/DSC09454.jpg
(Stored with Git LFS)
BIN
data/gallery/DSC09454.jpg
(Stored with Git LFS)
Binary file not shown.
@ -14,6 +14,41 @@ export const onRouteUpdate = function () {
|
|||||||
window.plausible("pageview");
|
window.plausible("pageview");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// docs say you can return a scroll position from this fn, but that's a bold-faced lie
|
||||||
|
export const shouldUpdateScroll = ({
|
||||||
|
prevRouterProps,
|
||||||
|
routerProps: { location },
|
||||||
|
pathname,
|
||||||
|
}) => {
|
||||||
|
if (pathname.startsWith('/photogallery/') && pathname !== '/photogallery/' ) {
|
||||||
|
// if (prevRouterProps?.location.pathname === '/photogallery/') {
|
||||||
|
// console.log('scroll to image from gallery')
|
||||||
|
// // setTimeout(() => {
|
||||||
|
|
||||||
|
// // window.scrollTo(0, 0);
|
||||||
|
// // }, 100)
|
||||||
|
// setTimeout(() => {
|
||||||
|
// window.scrollTo(0, 180);
|
||||||
|
// }, 10)
|
||||||
|
// } else {
|
||||||
|
// console.log('scroll to image from elsewhere')
|
||||||
|
// requestAnimationFrame(() => {
|
||||||
|
// window.scrollTo(0, 180);
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
console.log('gallery image, skipping')
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (prevRouterProps?.location.pathname === pathname) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (pathname === "/photogallery/" && location.hash.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// import * as React from 'react';
|
// import * as React from 'react';
|
||||||
// import { MDXProvider } from '@mdx-js/react';
|
// import { MDXProvider } from '@mdx-js/react';
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
"gatsby-source-filesystem": "^5.0.0",
|
"gatsby-source-filesystem": "^5.0.0",
|
||||||
"gatsby-transformer-sharp": "^5.0.0",
|
"gatsby-transformer-sharp": "^5.0.0",
|
||||||
"kebab-case": "^1.0.1",
|
"kebab-case": "^1.0.1",
|
||||||
|
"lodash.debounce": "^4.0.8",
|
||||||
"node-iptc": "^1.0.5",
|
"node-iptc": "^1.0.5",
|
||||||
"node-vibrant": "3.1.6",
|
"node-vibrant": "3.1.6",
|
||||||
"postcss": "^8.4.19",
|
"postcss": "^8.4.19",
|
||||||
@ -60,6 +61,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/chroma-js": "^2.1.4",
|
"@types/chroma-js": "^2.1.4",
|
||||||
|
"@types/lodash.debounce": "^4.0.7",
|
||||||
"@types/node": "^18.8.3",
|
"@types/node": "^18.8.3",
|
||||||
"@types/ramda": "^0.28.15",
|
"@types/ramda": "^0.28.15",
|
||||||
"@types/react": "^18.0.21",
|
"@types/react": "^18.0.21",
|
||||||
|
@ -65,7 +65,10 @@ const GalleryImage = ({ data, location: { state } }) => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
window.scrollTo(0, 180);
|
window.scrollTo({
|
||||||
|
top: 180,
|
||||||
|
behavior: 'smooth'
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}, [image.base]);
|
}, [image.base]);
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ interface MasonryGalleryProps {
|
|||||||
[breakpoint: string]: number;
|
[breakpoint: string]: number;
|
||||||
};
|
};
|
||||||
debugHue?: boolean;
|
debugHue?: boolean;
|
||||||
dataFn?: (image: GalleryImage) => (string | null);
|
dataFn?: (image: GalleryImage) => string[] | null;
|
||||||
linkState?: object;
|
linkState?: object;
|
||||||
showPalette?: boolean;
|
showPalette?: boolean;
|
||||||
singleRow?: boolean;
|
singleRow?: boolean;
|
||||||
@ -47,14 +47,8 @@ const MasonryGallery = ({
|
|||||||
[aspectTargetsByBreakpoint]
|
[aspectTargetsByBreakpoint]
|
||||||
);
|
);
|
||||||
|
|
||||||
// const { observe, currentBreakpoint } = useDimensions({
|
|
||||||
// breakpoints,
|
|
||||||
// });
|
|
||||||
|
|
||||||
const { breakpoint } = useBreakpoint(breakpoints, "xs");
|
const { breakpoint } = useBreakpoint(breakpoints, "xs");
|
||||||
console.log("🚀 ~ file: MasonryGallery.tsx:55 ~ breakpoint:", breakpoint)
|
|
||||||
|
|
||||||
// const breakpoint = currentBreakpoint.length ? currentBreakpoint : "xs";
|
|
||||||
const galleryWidth = `calc(100vw - ${
|
const galleryWidth = `calc(100vw - ${
|
||||||
breakpoint === "xs" || breakpoint === "sm" ? "32" : "160"
|
breakpoint === "xs" || breakpoint === "sm" ? "32" : "160"
|
||||||
}px)`;
|
}px)`;
|
||||||
@ -78,7 +72,7 @@ const MasonryGallery = ({
|
|||||||
// does adding current image to our row get us closer to our target aspect ratio?
|
// does adding current image to our row get us closer to our target aspect ratio?
|
||||||
if (currentDiff > diffIfImageIsAddedToCurrentRow) {
|
if (currentDiff > diffIfImageIsAddedToCurrentRow) {
|
||||||
currentRow.aspect += currentAspect;
|
currentRow.aspect += currentAspect;
|
||||||
currentRow.images += 1
|
currentRow.images += 1;
|
||||||
// _rows.push(currentRow);
|
// _rows.push(currentRow);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -91,8 +85,8 @@ const MasonryGallery = ({
|
|||||||
_rows.push({
|
_rows.push({
|
||||||
aspect: currentAspect,
|
aspect: currentAspect,
|
||||||
images: 1,
|
images: 1,
|
||||||
startIndex: currentRow.startIndex + currentRow.images
|
startIndex: currentRow.startIndex + currentRow.images,
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return R.indexBy(R.prop("startIndex"), _rows);
|
return R.indexBy(R.prop("startIndex"), _rows);
|
||||||
@ -125,7 +119,7 @@ const MasonryGallery = ({
|
|||||||
}
|
}
|
||||||
const rowAspectRatioSum = currentRow.aspect;
|
const rowAspectRatioSum = currentRow.aspect;
|
||||||
const ar = getAspectRatio(image);
|
const ar = getAspectRatio(image);
|
||||||
let width;
|
let width: string;
|
||||||
let height = `calc(${galleryWidth} / ${rowAspectRatioSum} ${
|
let height = `calc(${galleryWidth} / ${rowAspectRatioSum} ${
|
||||||
showPalette ? "+ 10px" : "- 10px"
|
showPalette ? "+ 10px" : "- 10px"
|
||||||
})`;
|
})`;
|
||||||
@ -144,7 +138,7 @@ const MasonryGallery = ({
|
|||||||
const data = dataFn ? dataFn(image) : null;
|
const data = dataFn ? dataFn(image) : null;
|
||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
className={classNames("border-8 border-white overflow-hidden")}
|
className={classNames("border-8 border-white overflow-hidden relative")}
|
||||||
id={image.base}
|
id={image.base}
|
||||||
key={`${image.base}`}
|
key={`${image.base}`}
|
||||||
state={{
|
state={{
|
||||||
@ -165,9 +159,18 @@ const MasonryGallery = ({
|
|||||||
}}
|
}}
|
||||||
to={`/photogallery/${image.base}/`}
|
to={`/photogallery/${image.base}/`}
|
||||||
>
|
>
|
||||||
{data && <span className="text-white z-20 absolute bg-black">
|
{data && (
|
||||||
{data}
|
<div className="text-white z-20 absolute flex flex-col items-start">
|
||||||
</span>}
|
{data.map((dataString, i) => (
|
||||||
|
<span
|
||||||
|
className="bg-black/30 backdrop-blur p-[2px] m-[2px] max-w-full"
|
||||||
|
key={i}
|
||||||
|
>
|
||||||
|
{dataString}
|
||||||
|
</span>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
{img && (
|
{img && (
|
||||||
<div
|
<div
|
||||||
className={`h-full ${
|
className={`h-full ${
|
||||||
|
33
src/components/ToggleButton.tsx
Normal file
33
src/components/ToggleButton.tsx
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
|
||||||
|
import {useToggleState} from 'react-stately';
|
||||||
|
import {AriaToggleButtonProps, useToggleButton} from 'react-aria';
|
||||||
|
import {useRef} from 'react';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
export function ToggleButton(props: AriaToggleButtonProps) {
|
||||||
|
let ref = useRef(null);
|
||||||
|
let state = useToggleState(props);
|
||||||
|
let { buttonProps, isPressed } = useToggleButton(props, state, ref);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
{...buttonProps}
|
||||||
|
className={classNames(buttonProps.className, "py-[3px] px-2 mx-1 rounded")}
|
||||||
|
ref={ref}
|
||||||
|
style={{
|
||||||
|
background: isPressed
|
||||||
|
? state.isSelected ? 'darkgreen' : 'gray'
|
||||||
|
: state.isSelected
|
||||||
|
? 'green'
|
||||||
|
: 'lightgray',
|
||||||
|
color: state.isSelected ? 'white' : 'black',
|
||||||
|
userSelect: 'none',
|
||||||
|
WebkitUserSelect: 'none',
|
||||||
|
border: 'none'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{props.children}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
356
src/gatsby-types.d.ts
vendored
356
src/gatsby-types.d.ts
vendored
@ -1532,7 +1532,6 @@ type Query = {
|
|||||||
readonly allSiteFunction: SiteFunctionConnection;
|
readonly allSiteFunction: SiteFunctionConnection;
|
||||||
readonly allSitePage: SitePageConnection;
|
readonly allSitePage: SitePageConnection;
|
||||||
readonly allSitePlugin: SitePluginConnection;
|
readonly allSitePlugin: SitePluginConnection;
|
||||||
readonly allStaticImage: StaticImageConnection;
|
|
||||||
readonly directory: Maybe<Directory>;
|
readonly directory: Maybe<Directory>;
|
||||||
readonly file: Maybe<File>;
|
readonly file: Maybe<File>;
|
||||||
readonly imageSharp: Maybe<ImageSharp>;
|
readonly imageSharp: Maybe<ImageSharp>;
|
||||||
@ -1541,7 +1540,6 @@ type Query = {
|
|||||||
readonly siteFunction: Maybe<SiteFunction>;
|
readonly siteFunction: Maybe<SiteFunction>;
|
||||||
readonly sitePage: Maybe<SitePage>;
|
readonly sitePage: Maybe<SitePage>;
|
||||||
readonly sitePlugin: Maybe<SitePlugin>;
|
readonly sitePlugin: Maybe<SitePlugin>;
|
||||||
readonly staticImage: Maybe<StaticImage>;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1609,14 +1607,6 @@ type Query_allSitePluginArgs = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
type Query_allStaticImageArgs = {
|
|
||||||
filter: InputMaybe<StaticImageFilterInput>;
|
|
||||||
limit: InputMaybe<Scalars['Int']>;
|
|
||||||
skip: InputMaybe<Scalars['Int']>;
|
|
||||||
sort: InputMaybe<ReadonlyArray<InputMaybe<StaticImageSortInput>>>;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
type Query_directoryArgs = {
|
type Query_directoryArgs = {
|
||||||
absolutePath: InputMaybe<StringQueryOperatorInput>;
|
absolutePath: InputMaybe<StringQueryOperatorInput>;
|
||||||
accessTime: InputMaybe<DateQueryOperatorInput>;
|
accessTime: InputMaybe<DateQueryOperatorInput>;
|
||||||
@ -1786,46 +1776,6 @@ type Query_sitePluginArgs = {
|
|||||||
version: InputMaybe<StringQueryOperatorInput>;
|
version: InputMaybe<StringQueryOperatorInput>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
type Query_staticImageArgs = {
|
|
||||||
absolutePath: InputMaybe<StringQueryOperatorInput>;
|
|
||||||
accessTime: InputMaybe<DateQueryOperatorInput>;
|
|
||||||
atime: InputMaybe<DateQueryOperatorInput>;
|
|
||||||
atimeMs: InputMaybe<FloatQueryOperatorInput>;
|
|
||||||
base: InputMaybe<StringQueryOperatorInput>;
|
|
||||||
birthTime: InputMaybe<DateQueryOperatorInput>;
|
|
||||||
birthtime: InputMaybe<DateQueryOperatorInput>;
|
|
||||||
birthtimeMs: InputMaybe<FloatQueryOperatorInput>;
|
|
||||||
blksize: InputMaybe<IntQueryOperatorInput>;
|
|
||||||
blocks: InputMaybe<IntQueryOperatorInput>;
|
|
||||||
changeTime: InputMaybe<DateQueryOperatorInput>;
|
|
||||||
children: InputMaybe<NodeFilterListInput>;
|
|
||||||
ctime: InputMaybe<DateQueryOperatorInput>;
|
|
||||||
ctimeMs: InputMaybe<FloatQueryOperatorInput>;
|
|
||||||
dev: InputMaybe<IntQueryOperatorInput>;
|
|
||||||
dir: InputMaybe<StringQueryOperatorInput>;
|
|
||||||
ext: InputMaybe<StringQueryOperatorInput>;
|
|
||||||
extension: InputMaybe<StringQueryOperatorInput>;
|
|
||||||
id: InputMaybe<StringQueryOperatorInput>;
|
|
||||||
ino: InputMaybe<IntQueryOperatorInput>;
|
|
||||||
internal: InputMaybe<InternalFilterInput>;
|
|
||||||
mode: InputMaybe<IntQueryOperatorInput>;
|
|
||||||
modifiedTime: InputMaybe<DateQueryOperatorInput>;
|
|
||||||
mtime: InputMaybe<DateQueryOperatorInput>;
|
|
||||||
mtimeMs: InputMaybe<FloatQueryOperatorInput>;
|
|
||||||
name: InputMaybe<StringQueryOperatorInput>;
|
|
||||||
nlink: InputMaybe<IntQueryOperatorInput>;
|
|
||||||
parent: InputMaybe<NodeFilterInput>;
|
|
||||||
prettySize: InputMaybe<StringQueryOperatorInput>;
|
|
||||||
rdev: InputMaybe<IntQueryOperatorInput>;
|
|
||||||
relativeDirectory: InputMaybe<StringQueryOperatorInput>;
|
|
||||||
relativePath: InputMaybe<StringQueryOperatorInput>;
|
|
||||||
root: InputMaybe<StringQueryOperatorInput>;
|
|
||||||
size: InputMaybe<IntQueryOperatorInput>;
|
|
||||||
sourceInstanceName: InputMaybe<StringQueryOperatorInput>;
|
|
||||||
uid: InputMaybe<IntQueryOperatorInput>;
|
|
||||||
};
|
|
||||||
|
|
||||||
type Site = Node & {
|
type Site = Node & {
|
||||||
readonly buildTime: Maybe<Scalars['Date']>;
|
readonly buildTime: Maybe<Scalars['Date']>;
|
||||||
readonly children: ReadonlyArray<Node>;
|
readonly children: ReadonlyArray<Node>;
|
||||||
@ -2592,312 +2542,6 @@ type SortOrderEnum =
|
|||||||
| 'ASC'
|
| 'ASC'
|
||||||
| 'DESC';
|
| 'DESC';
|
||||||
|
|
||||||
type StaticImage = Node & {
|
|
||||||
readonly absolutePath: Maybe<Scalars['String']>;
|
|
||||||
readonly accessTime: Maybe<Scalars['Date']>;
|
|
||||||
readonly atime: Maybe<Scalars['Date']>;
|
|
||||||
readonly atimeMs: Maybe<Scalars['Float']>;
|
|
||||||
readonly base: Maybe<Scalars['String']>;
|
|
||||||
readonly birthTime: Maybe<Scalars['Date']>;
|
|
||||||
readonly birthtime: Maybe<Scalars['Date']>;
|
|
||||||
readonly birthtimeMs: Maybe<Scalars['Float']>;
|
|
||||||
readonly blksize: Maybe<Scalars['Int']>;
|
|
||||||
readonly blocks: Maybe<Scalars['Int']>;
|
|
||||||
readonly changeTime: Maybe<Scalars['Date']>;
|
|
||||||
readonly children: ReadonlyArray<Node>;
|
|
||||||
readonly ctime: Maybe<Scalars['Date']>;
|
|
||||||
readonly ctimeMs: Maybe<Scalars['Float']>;
|
|
||||||
readonly dev: Maybe<Scalars['Int']>;
|
|
||||||
readonly dir: Maybe<Scalars['String']>;
|
|
||||||
readonly ext: Maybe<Scalars['String']>;
|
|
||||||
readonly extension: Maybe<Scalars['String']>;
|
|
||||||
readonly id: Scalars['ID'];
|
|
||||||
readonly ino: Maybe<Scalars['Int']>;
|
|
||||||
readonly internal: Internal;
|
|
||||||
readonly mode: Maybe<Scalars['Int']>;
|
|
||||||
readonly modifiedTime: Maybe<Scalars['Date']>;
|
|
||||||
readonly mtime: Maybe<Scalars['Date']>;
|
|
||||||
readonly mtimeMs: Maybe<Scalars['Float']>;
|
|
||||||
readonly name: Maybe<Scalars['String']>;
|
|
||||||
readonly nlink: Maybe<Scalars['Int']>;
|
|
||||||
readonly parent: Maybe<Node>;
|
|
||||||
readonly prettySize: Maybe<Scalars['String']>;
|
|
||||||
readonly rdev: Maybe<Scalars['Int']>;
|
|
||||||
readonly relativeDirectory: Maybe<Scalars['String']>;
|
|
||||||
readonly relativePath: Maybe<Scalars['String']>;
|
|
||||||
readonly root: Maybe<Scalars['String']>;
|
|
||||||
readonly size: Maybe<Scalars['Int']>;
|
|
||||||
readonly sourceInstanceName: Maybe<Scalars['String']>;
|
|
||||||
readonly uid: Maybe<Scalars['Int']>;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
type StaticImage_accessTimeArgs = {
|
|
||||||
difference: InputMaybe<Scalars['String']>;
|
|
||||||
formatString: InputMaybe<Scalars['String']>;
|
|
||||||
fromNow: InputMaybe<Scalars['Boolean']>;
|
|
||||||
locale: InputMaybe<Scalars['String']>;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
type StaticImage_atimeArgs = {
|
|
||||||
difference: InputMaybe<Scalars['String']>;
|
|
||||||
formatString: InputMaybe<Scalars['String']>;
|
|
||||||
fromNow: InputMaybe<Scalars['Boolean']>;
|
|
||||||
locale: InputMaybe<Scalars['String']>;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
type StaticImage_birthTimeArgs = {
|
|
||||||
difference: InputMaybe<Scalars['String']>;
|
|
||||||
formatString: InputMaybe<Scalars['String']>;
|
|
||||||
fromNow: InputMaybe<Scalars['Boolean']>;
|
|
||||||
locale: InputMaybe<Scalars['String']>;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
type StaticImage_birthtimeArgs = {
|
|
||||||
difference: InputMaybe<Scalars['String']>;
|
|
||||||
formatString: InputMaybe<Scalars['String']>;
|
|
||||||
fromNow: InputMaybe<Scalars['Boolean']>;
|
|
||||||
locale: InputMaybe<Scalars['String']>;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
type StaticImage_changeTimeArgs = {
|
|
||||||
difference: InputMaybe<Scalars['String']>;
|
|
||||||
formatString: InputMaybe<Scalars['String']>;
|
|
||||||
fromNow: InputMaybe<Scalars['Boolean']>;
|
|
||||||
locale: InputMaybe<Scalars['String']>;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
type StaticImage_ctimeArgs = {
|
|
||||||
difference: InputMaybe<Scalars['String']>;
|
|
||||||
formatString: InputMaybe<Scalars['String']>;
|
|
||||||
fromNow: InputMaybe<Scalars['Boolean']>;
|
|
||||||
locale: InputMaybe<Scalars['String']>;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
type StaticImage_modifiedTimeArgs = {
|
|
||||||
difference: InputMaybe<Scalars['String']>;
|
|
||||||
formatString: InputMaybe<Scalars['String']>;
|
|
||||||
fromNow: InputMaybe<Scalars['Boolean']>;
|
|
||||||
locale: InputMaybe<Scalars['String']>;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
type StaticImage_mtimeArgs = {
|
|
||||||
difference: InputMaybe<Scalars['String']>;
|
|
||||||
formatString: InputMaybe<Scalars['String']>;
|
|
||||||
fromNow: InputMaybe<Scalars['Boolean']>;
|
|
||||||
locale: InputMaybe<Scalars['String']>;
|
|
||||||
};
|
|
||||||
|
|
||||||
type StaticImageConnection = {
|
|
||||||
readonly distinct: ReadonlyArray<Scalars['String']>;
|
|
||||||
readonly edges: ReadonlyArray<StaticImageEdge>;
|
|
||||||
readonly group: ReadonlyArray<StaticImageGroupConnection>;
|
|
||||||
readonly max: Maybe<Scalars['Float']>;
|
|
||||||
readonly min: Maybe<Scalars['Float']>;
|
|
||||||
readonly nodes: ReadonlyArray<StaticImage>;
|
|
||||||
readonly pageInfo: PageInfo;
|
|
||||||
readonly sum: Maybe<Scalars['Float']>;
|
|
||||||
readonly totalCount: Scalars['Int'];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
type StaticImageConnection_distinctArgs = {
|
|
||||||
field: StaticImageFieldSelector;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
type StaticImageConnection_groupArgs = {
|
|
||||||
field: StaticImageFieldSelector;
|
|
||||||
limit: InputMaybe<Scalars['Int']>;
|
|
||||||
skip: InputMaybe<Scalars['Int']>;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
type StaticImageConnection_maxArgs = {
|
|
||||||
field: StaticImageFieldSelector;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
type StaticImageConnection_minArgs = {
|
|
||||||
field: StaticImageFieldSelector;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
type StaticImageConnection_sumArgs = {
|
|
||||||
field: StaticImageFieldSelector;
|
|
||||||
};
|
|
||||||
|
|
||||||
type StaticImageEdge = {
|
|
||||||
readonly next: Maybe<StaticImage>;
|
|
||||||
readonly node: StaticImage;
|
|
||||||
readonly previous: Maybe<StaticImage>;
|
|
||||||
};
|
|
||||||
|
|
||||||
type StaticImageFieldSelector = {
|
|
||||||
readonly absolutePath: InputMaybe<FieldSelectorEnum>;
|
|
||||||
readonly accessTime: InputMaybe<FieldSelectorEnum>;
|
|
||||||
readonly atime: InputMaybe<FieldSelectorEnum>;
|
|
||||||
readonly atimeMs: InputMaybe<FieldSelectorEnum>;
|
|
||||||
readonly base: InputMaybe<FieldSelectorEnum>;
|
|
||||||
readonly birthTime: InputMaybe<FieldSelectorEnum>;
|
|
||||||
readonly birthtime: InputMaybe<FieldSelectorEnum>;
|
|
||||||
readonly birthtimeMs: InputMaybe<FieldSelectorEnum>;
|
|
||||||
readonly blksize: InputMaybe<FieldSelectorEnum>;
|
|
||||||
readonly blocks: InputMaybe<FieldSelectorEnum>;
|
|
||||||
readonly changeTime: InputMaybe<FieldSelectorEnum>;
|
|
||||||
readonly children: InputMaybe<NodeFieldSelector>;
|
|
||||||
readonly ctime: InputMaybe<FieldSelectorEnum>;
|
|
||||||
readonly ctimeMs: InputMaybe<FieldSelectorEnum>;
|
|
||||||
readonly dev: InputMaybe<FieldSelectorEnum>;
|
|
||||||
readonly dir: InputMaybe<FieldSelectorEnum>;
|
|
||||||
readonly ext: InputMaybe<FieldSelectorEnum>;
|
|
||||||
readonly extension: InputMaybe<FieldSelectorEnum>;
|
|
||||||
readonly id: InputMaybe<FieldSelectorEnum>;
|
|
||||||
readonly ino: InputMaybe<FieldSelectorEnum>;
|
|
||||||
readonly internal: InputMaybe<InternalFieldSelector>;
|
|
||||||
readonly mode: InputMaybe<FieldSelectorEnum>;
|
|
||||||
readonly modifiedTime: InputMaybe<FieldSelectorEnum>;
|
|
||||||
readonly mtime: InputMaybe<FieldSelectorEnum>;
|
|
||||||
readonly mtimeMs: InputMaybe<FieldSelectorEnum>;
|
|
||||||
readonly name: InputMaybe<FieldSelectorEnum>;
|
|
||||||
readonly nlink: InputMaybe<FieldSelectorEnum>;
|
|
||||||
readonly parent: InputMaybe<NodeFieldSelector>;
|
|
||||||
readonly prettySize: InputMaybe<FieldSelectorEnum>;
|
|
||||||
readonly rdev: InputMaybe<FieldSelectorEnum>;
|
|
||||||
readonly relativeDirectory: InputMaybe<FieldSelectorEnum>;
|
|
||||||
readonly relativePath: InputMaybe<FieldSelectorEnum>;
|
|
||||||
readonly root: InputMaybe<FieldSelectorEnum>;
|
|
||||||
readonly size: InputMaybe<FieldSelectorEnum>;
|
|
||||||
readonly sourceInstanceName: InputMaybe<FieldSelectorEnum>;
|
|
||||||
readonly uid: InputMaybe<FieldSelectorEnum>;
|
|
||||||
};
|
|
||||||
|
|
||||||
type StaticImageFilterInput = {
|
|
||||||
readonly absolutePath: InputMaybe<StringQueryOperatorInput>;
|
|
||||||
readonly accessTime: InputMaybe<DateQueryOperatorInput>;
|
|
||||||
readonly atime: InputMaybe<DateQueryOperatorInput>;
|
|
||||||
readonly atimeMs: InputMaybe<FloatQueryOperatorInput>;
|
|
||||||
readonly base: InputMaybe<StringQueryOperatorInput>;
|
|
||||||
readonly birthTime: InputMaybe<DateQueryOperatorInput>;
|
|
||||||
readonly birthtime: InputMaybe<DateQueryOperatorInput>;
|
|
||||||
readonly birthtimeMs: InputMaybe<FloatQueryOperatorInput>;
|
|
||||||
readonly blksize: InputMaybe<IntQueryOperatorInput>;
|
|
||||||
readonly blocks: InputMaybe<IntQueryOperatorInput>;
|
|
||||||
readonly changeTime: InputMaybe<DateQueryOperatorInput>;
|
|
||||||
readonly children: InputMaybe<NodeFilterListInput>;
|
|
||||||
readonly ctime: InputMaybe<DateQueryOperatorInput>;
|
|
||||||
readonly ctimeMs: InputMaybe<FloatQueryOperatorInput>;
|
|
||||||
readonly dev: InputMaybe<IntQueryOperatorInput>;
|
|
||||||
readonly dir: InputMaybe<StringQueryOperatorInput>;
|
|
||||||
readonly ext: InputMaybe<StringQueryOperatorInput>;
|
|
||||||
readonly extension: InputMaybe<StringQueryOperatorInput>;
|
|
||||||
readonly id: InputMaybe<StringQueryOperatorInput>;
|
|
||||||
readonly ino: InputMaybe<IntQueryOperatorInput>;
|
|
||||||
readonly internal: InputMaybe<InternalFilterInput>;
|
|
||||||
readonly mode: InputMaybe<IntQueryOperatorInput>;
|
|
||||||
readonly modifiedTime: InputMaybe<DateQueryOperatorInput>;
|
|
||||||
readonly mtime: InputMaybe<DateQueryOperatorInput>;
|
|
||||||
readonly mtimeMs: InputMaybe<FloatQueryOperatorInput>;
|
|
||||||
readonly name: InputMaybe<StringQueryOperatorInput>;
|
|
||||||
readonly nlink: InputMaybe<IntQueryOperatorInput>;
|
|
||||||
readonly parent: InputMaybe<NodeFilterInput>;
|
|
||||||
readonly prettySize: InputMaybe<StringQueryOperatorInput>;
|
|
||||||
readonly rdev: InputMaybe<IntQueryOperatorInput>;
|
|
||||||
readonly relativeDirectory: InputMaybe<StringQueryOperatorInput>;
|
|
||||||
readonly relativePath: InputMaybe<StringQueryOperatorInput>;
|
|
||||||
readonly root: InputMaybe<StringQueryOperatorInput>;
|
|
||||||
readonly size: InputMaybe<IntQueryOperatorInput>;
|
|
||||||
readonly sourceInstanceName: InputMaybe<StringQueryOperatorInput>;
|
|
||||||
readonly uid: InputMaybe<IntQueryOperatorInput>;
|
|
||||||
};
|
|
||||||
|
|
||||||
type StaticImageGroupConnection = {
|
|
||||||
readonly distinct: ReadonlyArray<Scalars['String']>;
|
|
||||||
readonly edges: ReadonlyArray<StaticImageEdge>;
|
|
||||||
readonly field: Scalars['String'];
|
|
||||||
readonly fieldValue: Maybe<Scalars['String']>;
|
|
||||||
readonly group: ReadonlyArray<StaticImageGroupConnection>;
|
|
||||||
readonly max: Maybe<Scalars['Float']>;
|
|
||||||
readonly min: Maybe<Scalars['Float']>;
|
|
||||||
readonly nodes: ReadonlyArray<StaticImage>;
|
|
||||||
readonly pageInfo: PageInfo;
|
|
||||||
readonly sum: Maybe<Scalars['Float']>;
|
|
||||||
readonly totalCount: Scalars['Int'];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
type StaticImageGroupConnection_distinctArgs = {
|
|
||||||
field: StaticImageFieldSelector;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
type StaticImageGroupConnection_groupArgs = {
|
|
||||||
field: StaticImageFieldSelector;
|
|
||||||
limit: InputMaybe<Scalars['Int']>;
|
|
||||||
skip: InputMaybe<Scalars['Int']>;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
type StaticImageGroupConnection_maxArgs = {
|
|
||||||
field: StaticImageFieldSelector;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
type StaticImageGroupConnection_minArgs = {
|
|
||||||
field: StaticImageFieldSelector;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
type StaticImageGroupConnection_sumArgs = {
|
|
||||||
field: StaticImageFieldSelector;
|
|
||||||
};
|
|
||||||
|
|
||||||
type StaticImageSortInput = {
|
|
||||||
readonly absolutePath: InputMaybe<SortOrderEnum>;
|
|
||||||
readonly accessTime: InputMaybe<SortOrderEnum>;
|
|
||||||
readonly atime: InputMaybe<SortOrderEnum>;
|
|
||||||
readonly atimeMs: InputMaybe<SortOrderEnum>;
|
|
||||||
readonly base: InputMaybe<SortOrderEnum>;
|
|
||||||
readonly birthTime: InputMaybe<SortOrderEnum>;
|
|
||||||
readonly birthtime: InputMaybe<SortOrderEnum>;
|
|
||||||
readonly birthtimeMs: InputMaybe<SortOrderEnum>;
|
|
||||||
readonly blksize: InputMaybe<SortOrderEnum>;
|
|
||||||
readonly blocks: InputMaybe<SortOrderEnum>;
|
|
||||||
readonly changeTime: InputMaybe<SortOrderEnum>;
|
|
||||||
readonly children: InputMaybe<NodeSortInput>;
|
|
||||||
readonly ctime: InputMaybe<SortOrderEnum>;
|
|
||||||
readonly ctimeMs: InputMaybe<SortOrderEnum>;
|
|
||||||
readonly dev: InputMaybe<SortOrderEnum>;
|
|
||||||
readonly dir: InputMaybe<SortOrderEnum>;
|
|
||||||
readonly ext: InputMaybe<SortOrderEnum>;
|
|
||||||
readonly extension: InputMaybe<SortOrderEnum>;
|
|
||||||
readonly id: InputMaybe<SortOrderEnum>;
|
|
||||||
readonly ino: InputMaybe<SortOrderEnum>;
|
|
||||||
readonly internal: InputMaybe<InternalSortInput>;
|
|
||||||
readonly mode: InputMaybe<SortOrderEnum>;
|
|
||||||
readonly modifiedTime: InputMaybe<SortOrderEnum>;
|
|
||||||
readonly mtime: InputMaybe<SortOrderEnum>;
|
|
||||||
readonly mtimeMs: InputMaybe<SortOrderEnum>;
|
|
||||||
readonly name: InputMaybe<SortOrderEnum>;
|
|
||||||
readonly nlink: InputMaybe<SortOrderEnum>;
|
|
||||||
readonly parent: InputMaybe<NodeSortInput>;
|
|
||||||
readonly prettySize: InputMaybe<SortOrderEnum>;
|
|
||||||
readonly rdev: InputMaybe<SortOrderEnum>;
|
|
||||||
readonly relativeDirectory: InputMaybe<SortOrderEnum>;
|
|
||||||
readonly relativePath: InputMaybe<SortOrderEnum>;
|
|
||||||
readonly root: InputMaybe<SortOrderEnum>;
|
|
||||||
readonly size: InputMaybe<SortOrderEnum>;
|
|
||||||
readonly sourceInstanceName: InputMaybe<SortOrderEnum>;
|
|
||||||
readonly uid: InputMaybe<SortOrderEnum>;
|
|
||||||
};
|
|
||||||
|
|
||||||
type StringQueryOperatorInput = {
|
type StringQueryOperatorInput = {
|
||||||
readonly eq: InputMaybe<Scalars['String']>;
|
readonly eq: InputMaybe<Scalars['String']>;
|
||||||
readonly glob: InputMaybe<Scalars['String']>;
|
readonly glob: InputMaybe<Scalars['String']>;
|
||||||
|
@ -2,6 +2,7 @@ import * as React from "react";
|
|||||||
import * as R from "ramda";
|
import * as R from "ramda";
|
||||||
import { graphql, Link, navigate, PageProps } from "gatsby";
|
import { graphql, Link, navigate, PageProps } from "gatsby";
|
||||||
import { Helmet } from "react-helmet";
|
import { Helmet } from "react-helmet";
|
||||||
|
import debounce from "lodash.debounce";
|
||||||
// import { Picker, Item } from "@adobe/react-spectrum";
|
// import { Picker, Item } from "@adobe/react-spectrum";
|
||||||
|
|
||||||
import MasonryGallery from "../components/MasonryGallery";
|
import MasonryGallery from "../components/MasonryGallery";
|
||||||
@ -16,6 +17,7 @@ import Nav from "../components/Nav";
|
|||||||
import { Item, Select } from "../components/Select";
|
import { Item, Select } from "../components/Select";
|
||||||
import { Switch } from "../components/Switch";
|
import { Switch } from "../components/Switch";
|
||||||
import ColorPalette from "@spectrum-icons/workflow/ColorPalette";
|
import ColorPalette from "@spectrum-icons/workflow/ColorPalette";
|
||||||
|
import { ToggleButton } from "../components/ToggleButton";
|
||||||
|
|
||||||
const SORT_KEYS = {
|
const SORT_KEYS = {
|
||||||
hue: ["fields", "imageMeta", "vibrantHue"],
|
hue: ["fields", "imageMeta", "vibrantHue"],
|
||||||
@ -79,8 +81,8 @@ const GalleryPage = ({
|
|||||||
getGalleryPageUrl(
|
getGalleryPageUrl(
|
||||||
{ sortKey: newSortKey, keyword: filterKeyword, showDebug },
|
{ sortKey: newSortKey, keyword: filterKeyword, showDebug },
|
||||||
hash
|
hash
|
||||||
),
|
)
|
||||||
{ replace: true }
|
// { replace: true }
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
[filterKeyword, hash, showDebug]
|
[filterKeyword, hash, showDebug]
|
||||||
@ -90,21 +92,18 @@ const GalleryPage = ({
|
|||||||
if (!hash.length) {
|
if (!hash.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// const url = new URL(
|
navigate(
|
||||||
// typeof window !== "undefined"
|
getGalleryPageUrl({ sortKey, keyword: filterKeyword, showDebug }, ""),
|
||||||
// ? window.location.href.toString()
|
{ replace: true }
|
||||||
// : "https://chuckdries.com/photogallery/"
|
);
|
||||||
// );
|
window.removeEventListener("scroll", removeHash);
|
||||||
|
|
||||||
// url.hash = "";
|
|
||||||
// window.history.replaceState(null, "", url.href.toString());
|
|
||||||
navigate(getGalleryPageUrl({ sortKey, keyword: filterKeyword, showDebug}, ""), { replace: true })
|
|
||||||
window.removeEventListener("wheel", removeHash);
|
|
||||||
}, [hash, sortKey, filterKeyword, showDebug]);
|
}, [hash, sortKey, filterKeyword, showDebug]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
window.addEventListener("wheel", removeHash);
|
// window.addEventListener("scroll", removeHash);
|
||||||
return () => window.removeEventListener("wheel", removeHash);
|
return () => {
|
||||||
|
window.removeEventListener("scroll", removeHash);
|
||||||
|
};
|
||||||
}, [removeHash]);
|
}, [removeHash]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
@ -119,12 +118,16 @@ const GalleryPage = ({
|
|||||||
console.log("⚠️failed to find hash");
|
console.log("⚠️failed to find hash");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log("scrolling into view manually");
|
console.log("scrolling into view manually", el.offsetTop);
|
||||||
el.scrollIntoView({
|
el.scrollIntoView({
|
||||||
block: hash.startsWith("all") ? "start" : "center",
|
block: hash.startsWith("all") ? "start" : "center",
|
||||||
|
behavior: "smooth",
|
||||||
});
|
});
|
||||||
|
setTimeout(() => {
|
||||||
|
window.addEventListener("scroll", removeHash);
|
||||||
|
}, 100);
|
||||||
});
|
});
|
||||||
}, [hash]);
|
}, [hash, removeHash]);
|
||||||
|
|
||||||
const images: GalleryImage[] = React.useMemo(() => {
|
const images: GalleryImage[] = React.useMemo(() => {
|
||||||
const sort =
|
const sort =
|
||||||
@ -166,24 +169,43 @@ const GalleryPage = ({
|
|||||||
);
|
);
|
||||||
}, [data]);
|
}, [data]);
|
||||||
|
|
||||||
|
const [dbgTags, setDbgTags] = React.useState(false);
|
||||||
|
const [dbgSortKey, setDbgSortKey] = React.useState(false);
|
||||||
|
const [dbgName, setDbgName] = React.useState(false);
|
||||||
const dataFn = React.useCallback(
|
const dataFn = React.useCallback(
|
||||||
(image: GalleryImage): string | null => {
|
(image: GalleryImage): string[] | null => {
|
||||||
if (!showDebug) {
|
if (!showDebug) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (sortKey === "rating") {
|
let data: string[] = [];
|
||||||
return `[${R.pathOr(null, SORT_KEYS.rating, image)}] ${image.base}`;
|
if (dbgName) {
|
||||||
|
data.push(image.base);
|
||||||
}
|
}
|
||||||
if (sortKey === "datePublished") {
|
if (dbgSortKey) {
|
||||||
const date = R.pathOr(null, SORT_KEYS.datePublished, image);
|
switch (sortKey) {
|
||||||
if (!date) {
|
case "hue":
|
||||||
return null;
|
case "rating": {
|
||||||
|
data.push(R.pathOr("x", SORT_KEYS[sortKey], image));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "date":
|
||||||
|
case "datePublished": {
|
||||||
|
const date = R.pathOr(null, SORT_KEYS[sortKey], image);
|
||||||
|
if (date) {
|
||||||
|
data.push(new Date(date).toLocaleString());
|
||||||
|
} else {
|
||||||
|
data.push("x");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return new Date(date).toLocaleString();
|
|
||||||
}
|
}
|
||||||
return null;
|
if (dbgTags) {
|
||||||
|
data.push(image.fields?.imageMeta?.meta?.Keywords?.join(",") ?? "x");
|
||||||
|
}
|
||||||
|
return data;
|
||||||
},
|
},
|
||||||
[showDebug, sortKey]
|
[showDebug, sortKey, dbgName, dbgSortKey, dbgTags]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -276,7 +298,20 @@ const GalleryPage = ({
|
|||||||
onPick={onKeywordPick}
|
onPick={onKeywordPick}
|
||||||
value={filterKeyword}
|
value={filterKeyword}
|
||||||
/>
|
/>
|
||||||
<div className="my-2 mr-2 flex flex-row items-end">
|
<div className="my-2 mx-2 flex flex-row items-end">
|
||||||
|
{showDebug && (
|
||||||
|
<div className="mr-2">
|
||||||
|
<ToggleButton isSelected={dbgName} onChange={setDbgName}>
|
||||||
|
name
|
||||||
|
</ToggleButton>
|
||||||
|
<ToggleButton isSelected={dbgSortKey} onChange={setDbgSortKey}>
|
||||||
|
sort key
|
||||||
|
</ToggleButton>
|
||||||
|
<ToggleButton isSelected={dbgTags} onChange={setDbgTags}>
|
||||||
|
tags
|
||||||
|
</ToggleButton>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<div className="border border-gray-400 rounded mr-2">
|
<div className="border border-gray-400 rounded mr-2">
|
||||||
<Switch
|
<Switch
|
||||||
isSelected={showPalette}
|
isSelected={showPalette}
|
||||||
@ -292,7 +327,7 @@ const GalleryPage = ({
|
|||||||
</div>
|
</div>
|
||||||
<Select
|
<Select
|
||||||
label="Sort by..."
|
label="Sort by..."
|
||||||
// @ts-ignore
|
// @ts-expect-error React.key, but string is more convenient for the state
|
||||||
onSelectionChange={setSortKey}
|
onSelectionChange={setSortKey}
|
||||||
selectedKey={sortKey}
|
selectedKey={sortKey}
|
||||||
>
|
>
|
||||||
|
@ -8,7 +8,9 @@
|
|||||||
|
|
||||||
* {
|
* {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
scroll-behavior: smooth;
|
}
|
||||||
|
:root {
|
||||||
|
/* scroll-behavior: smooth; */
|
||||||
}
|
}
|
||||||
/* .hero * {
|
/* .hero * {
|
||||||
transition: color .2s, background-color .2s;
|
transition: color .2s, background-color .2s;
|
||||||
@ -92,6 +94,7 @@
|
|||||||
|
|
||||||
body {
|
body {
|
||||||
@apply bg-gray-100;
|
@apply bg-gray-100;
|
||||||
|
overflow: auto;
|
||||||
/* @apply bg-black; */
|
/* @apply bg-black; */
|
||||||
/* @apply text-white; */
|
/* @apply text-white; */
|
||||||
}
|
}
|
||||||
|
28
src/utils.ts
28
src/utils.ts
@ -1,4 +1,4 @@
|
|||||||
import React from "react";
|
import React, { useCallback, useRef } from "react";
|
||||||
|
|
||||||
import { pathOr } from "ramda";
|
import { pathOr } from "ramda";
|
||||||
// import kebabCase from 'lodash/kebabCase';
|
// import kebabCase from 'lodash/kebabCase';
|
||||||
@ -150,3 +150,29 @@ export function compareDates<T>(
|
|||||||
const diff = -1 * (date1.getTime() - date2.getTime());
|
const diff = -1 * (date1.getTime() - date2.getTime());
|
||||||
return diff;
|
return diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a memoized function that will only call the passed function when it hasn't been called for the wait period
|
||||||
|
* @param func The function to be called
|
||||||
|
* @param wait Wait period after function hasn't been called for
|
||||||
|
* @returns A memoized function that is debounced
|
||||||
|
*/
|
||||||
|
export const useDebouncedCallback = (func: Function, wait: number) => {
|
||||||
|
// Use a ref to store the timeout between renders
|
||||||
|
// and prevent changes to it from causing re-renders
|
||||||
|
const timeout = useRef<ReturnType<typeof setTimeout>>();
|
||||||
|
|
||||||
|
return useCallback(
|
||||||
|
(...args: any) => {
|
||||||
|
const later = () => {
|
||||||
|
clearTimeout(timeout.current!);
|
||||||
|
func(...args);
|
||||||
|
};
|
||||||
|
|
||||||
|
clearTimeout(timeout.current ?? undefined);
|
||||||
|
timeout.current = setTimeout(later, wait);
|
||||||
|
},
|
||||||
|
[func, wait]
|
||||||
|
);
|
||||||
|
};
|
18
yarn.lock
18
yarn.lock
@ -4560,6 +4560,22 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@types/lodash.debounce@npm:^4.0.7":
|
||||||
|
version: 4.0.7
|
||||||
|
resolution: "@types/lodash.debounce@npm:4.0.7"
|
||||||
|
dependencies:
|
||||||
|
"@types/lodash": "*"
|
||||||
|
checksum: e873b2d77f89010876baba3437ef826b17221b98948e00b5590828334a481dea1c8f9d28543210e564adc53199584f42c3cb171f8b6c3614fefc0b4e0888679c
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@types/lodash@npm:*":
|
||||||
|
version: 4.14.191
|
||||||
|
resolution: "@types/lodash@npm:4.14.191"
|
||||||
|
checksum: ba0d5434e10690869f32d5ea49095250157cae502f10d57de0a723fd72229ce6c6a4979576f0f13e0aa9fbe3ce2457bfb9fa7d4ec3d6daba56730a51906d1491
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@types/lodash@npm:^4.14.53":
|
"@types/lodash@npm:^4.14.53":
|
||||||
version: 4.14.170
|
version: 4.14.170
|
||||||
resolution: "@types/lodash@npm:4.14.170"
|
resolution: "@types/lodash@npm:4.14.170"
|
||||||
@ -6464,6 +6480,7 @@ __metadata:
|
|||||||
"@react-spectrum/provider": ^3.6.0
|
"@react-spectrum/provider": ^3.6.0
|
||||||
"@spectrum-icons/workflow": ^4.0.4
|
"@spectrum-icons/workflow": ^4.0.4
|
||||||
"@types/chroma-js": ^2.1.4
|
"@types/chroma-js": ^2.1.4
|
||||||
|
"@types/lodash.debounce": ^4.0.7
|
||||||
"@types/node": ^18.8.3
|
"@types/node": ^18.8.3
|
||||||
"@types/ramda": ^0.28.15
|
"@types/ramda": ^0.28.15
|
||||||
"@types/react": ^18.0.21
|
"@types/react": ^18.0.21
|
||||||
@ -6495,6 +6512,7 @@ __metadata:
|
|||||||
gatsby-source-filesystem: ^5.0.0
|
gatsby-source-filesystem: ^5.0.0
|
||||||
gatsby-transformer-sharp: ^5.0.0
|
gatsby-transformer-sharp: ^5.0.0
|
||||||
kebab-case: ^1.0.1
|
kebab-case: ^1.0.1
|
||||||
|
lodash.debounce: ^4.0.8
|
||||||
node-iptc: ^1.0.5
|
node-iptc: ^1.0.5
|
||||||
node-vibrant: 3.1.6
|
node-vibrant: 3.1.6
|
||||||
postcss: ^8.4.19
|
postcss: ^8.4.19
|
||||||
|
Loading…
x
Reference in New Issue
Block a user