Merge branch 'main' into static

This commit is contained in:
Sam Becker 2024-02-23 21:05:59 -06:00
commit 6665a52089
8 changed files with 138 additions and 96 deletions

View File

@ -38,8 +38,8 @@
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"nanoid": "^5.0.6",
"next": "14.1.1-canary.70",
"next-auth": "5.0.0-beta.9",
"next": "14.1.1-canary.71",
"next-auth": "5.0.0-beta.13",
"next-themes": "^0.2.1",
"postcss": "8.4.35",
"react": "18.2.0",

106
pnpm-lock.yaml generated
View File

@ -46,7 +46,7 @@ dependencies:
version: 7.0.2(eslint@8.56.0)(typescript@5.3.3)
'@vercel/analytics':
specifier: ^1.2.2
version: 1.2.2(next@14.1.1-canary.70)(react@18.2.0)
version: 1.2.2(next@14.1.1-canary.71)(react@18.2.0)
'@vercel/blob':
specifier: ^0.22.1
version: 0.22.1
@ -55,7 +55,7 @@ dependencies:
version: 0.7.2
'@vercel/speed-insights':
specifier: ^1.0.10
version: 1.0.10(next@14.1.1-canary.70)(react@18.2.0)
version: 1.0.10(next@14.1.1-canary.71)(react@18.2.0)
autoprefixer:
specifier: 10.4.17
version: 10.4.17(postcss@8.4.35)
@ -93,14 +93,14 @@ dependencies:
specifier: ^5.0.6
version: 5.0.6
next:
specifier: 14.1.1-canary.70
version: 14.1.1-canary.70(@babel/core@7.23.9)(react-dom@18.2.0)(react@18.2.0)
specifier: 14.1.1-canary.71
version: 14.1.1-canary.71(@babel/core@7.23.9)(react-dom@18.2.0)(react@18.2.0)
next-auth:
specifier: 5.0.0-beta.9
version: 5.0.0-beta.9(next@14.1.1-canary.70)(react@18.2.0)
specifier: 5.0.0-beta.13
version: 5.0.0-beta.13(next@14.1.1-canary.71)(react@18.2.0)
next-themes:
specifier: ^0.2.1
version: 0.2.1(next@14.1.1-canary.70)(react-dom@18.2.0)(react@18.2.0)
version: 0.2.1(next@14.1.1-canary.71)(react-dom@18.2.0)(react@18.2.0)
postcss:
specifier: 8.4.35
version: 8.4.35
@ -153,11 +153,11 @@ packages:
'@jridgewell/trace-mapping': 0.3.22
dev: false
/@auth/core@0.26.3:
resolution: {integrity: sha512-Ka6rMjWMdiQCvLW/CnYZxj4Rq2bhQ/ZtU32NLxmtyAaixGb0mRXQ9MxJUBZA7GHovbghdzu55p2Cb54qNlVFzw==}
/@auth/core@0.27.0:
resolution: {integrity: sha512-3bydnRJIM/Al6mkYmb53MsC+6G8ojw3lLPzwgVnX4dCo6N2lrib6Wq6r0vxZIhuHGjLObqqtUfpeaEj5aeTHFg==}
peerDependencies:
'@simplewebauthn/browser': ^9.0.1
'@simplewebauthn/server': ^9.0.1
'@simplewebauthn/server': ^9.0.2
nodemailer: ^6.8.0
peerDependenciesMeta:
'@simplewebauthn/browser':
@ -1563,8 +1563,8 @@ packages:
- utf-8-validate
dev: false
/@next/env@14.1.1-canary.70:
resolution: {integrity: sha512-y1Ye30DB15DLGM6E/VcOnkWgErtLSkszDks6opBtUnqI9Vr1gXPuIxNpH08our8/VyfyFvG0An5GBbMcooyLSg==}
/@next/env@14.1.1-canary.71:
resolution: {integrity: sha512-3ls1iTTHMZrVtjWmiG5MFQZvvdKY+VEcvyzqVSX03MAU5UmE6G+4oB+lKXIrtApBN91EgRu/mx5sBWmeNQ7DuA==}
dev: false
/@next/eslint-plugin-next@14.1.0:
@ -1573,8 +1573,8 @@ packages:
glob: 10.3.10
dev: false
/@next/swc-darwin-arm64@14.1.1-canary.70:
resolution: {integrity: sha512-eb6RhknFYzamnjHc1diSO/3ymEUMHBJDnrQilTqEjOiOx8oR/GshP3136KDMuF/JlIxqeNTojr2vKMyRNnC7tw==}
/@next/swc-darwin-arm64@14.1.1-canary.71:
resolution: {integrity: sha512-fTbEiTuD9XOstiM4bxxQoz8vzS/Yl2PDWFQQuD1m7H0sf2dj5kW1xmyYB0Sa5n3JEeLSz0415faWoZ3JfWrobg==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [darwin]
@ -1582,8 +1582,8 @@ packages:
dev: false
optional: true
/@next/swc-darwin-x64@14.1.1-canary.70:
resolution: {integrity: sha512-1Cqt0OmpI3J6Wq5bopzUpjJWoY0W92RcaSJdWSsmXgrLnxBHSmaPPhlDt3ZKZ/0f/9RDYXtqUnwS+q984f1R7w==}
/@next/swc-darwin-x64@14.1.1-canary.71:
resolution: {integrity: sha512-aJgvXTm50TzxdgdWu/Wgm2sgSoZXGyWDGMA+VR6osNrJCBdILvK5bLX/moE8grhKIMnAl+fE4xVvM0q+SgzpVA==}
engines: {node: '>= 10'}
cpu: [x64]
os: [darwin]
@ -1591,8 +1591,8 @@ packages:
dev: false
optional: true
/@next/swc-linux-arm64-gnu@14.1.1-canary.70:
resolution: {integrity: sha512-PGPhSYuVrilIVlPz9Lj3fyLs2nkB+eX2mK0GPpX25yCXFr2UD2vVhiMBqfFpkGtVKLvOjWhzjWQxFxN4u/NtRg==}
/@next/swc-linux-arm64-gnu@14.1.1-canary.71:
resolution: {integrity: sha512-dg0ibSNATNYdRCag2G/qunteDyMQmj00SelTbV3rrnWu+BV+NdqSeKi62N3oEyAznZc7GnNKemwGtin4PFxJkA==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
@ -1600,8 +1600,8 @@ packages:
dev: false
optional: true
/@next/swc-linux-arm64-musl@14.1.1-canary.70:
resolution: {integrity: sha512-EcW14+f5/vDa3Zn4Nmw7KqJpmbFObdBYPHxuuti6bKc0VYsWgoPQEyniHKr9EEsI0efrNX05Kzaoy/3T5ZuS7w==}
/@next/swc-linux-arm64-musl@14.1.1-canary.71:
resolution: {integrity: sha512-ECp672RF6DSyufqTuDCrITAfYESN3g22fSxw+C1NQXns0PhUyy3Wuzc6SkGaD27FJmKdV+bFTplaPWykZuZVfg==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
@ -1609,8 +1609,8 @@ packages:
dev: false
optional: true
/@next/swc-linux-x64-gnu@14.1.1-canary.70:
resolution: {integrity: sha512-aGPexcyfMKCHMQ5AoKehvMETLQcCOjJOcO0GK90fVO51d67DiOQo/v+EUm3M6wuciv6K7VKbqB9rYLPSPY6ZpA==}
/@next/swc-linux-x64-gnu@14.1.1-canary.71:
resolution: {integrity: sha512-GP5pkRVq+3AMBjVvRpvSft/T7psXRC8neOWG1iEOPaQFn/jpRxdo6pSVJ3koc5jcyjhePCcFA09JutuoBBZVxA==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
@ -1618,8 +1618,8 @@ packages:
dev: false
optional: true
/@next/swc-linux-x64-musl@14.1.1-canary.70:
resolution: {integrity: sha512-MI4+TZaNpZ61PwiR4F/pTdO21js+yRvSAXGMstmMF3memZYhFEIRmGMmcO6RewUd843r3TKsROG138AIztQFLA==}
/@next/swc-linux-x64-musl@14.1.1-canary.71:
resolution: {integrity: sha512-8JKHbO3o4qe+HIAgw8rdfxzuGRegeFTeO+i8fG6WjUAfKYydOX3KHnjp12UsoRixrp+pSPRFQjsq8PsSkFArSA==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
@ -1627,8 +1627,8 @@ packages:
dev: false
optional: true
/@next/swc-win32-arm64-msvc@14.1.1-canary.70:
resolution: {integrity: sha512-7CgLuiCPndVl8vrKVIS/NKXpuEqN+kdgM9aVrAyIUyAjcltBFKlTgJFAylPUb8ZGPW6URdKk+snJ7adkpsBA4w==}
/@next/swc-win32-arm64-msvc@14.1.1-canary.71:
resolution: {integrity: sha512-77fqJQ3M6N7Ey8iK2jP6xPdgHfscC+T61jgDPBNIHGVWvvZj5Vki4Agxslejto0uqqu59lpkn8yRk9/u2e9FZA==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [win32]
@ -1636,8 +1636,8 @@ packages:
dev: false
optional: true
/@next/swc-win32-ia32-msvc@14.1.1-canary.70:
resolution: {integrity: sha512-fptIFqxpUntN1HEbkn41ERMN3+uILHS5OzTUbm/ilAARIKc33clZ6VzhoyGCY0VFPF38L7hDUgCOfu/wjmUz8g==}
/@next/swc-win32-ia32-msvc@14.1.1-canary.71:
resolution: {integrity: sha512-i4nQ8zKc9E2pib9TuLS3NKn4nq//zY7iSWPY49y79Y1XR5JkQEy2Sai/kbOY/vbhx86vzyB7aN31RqcdFFNGTg==}
engines: {node: '>= 10'}
cpu: [ia32]
os: [win32]
@ -1645,8 +1645,8 @@ packages:
dev: false
optional: true
/@next/swc-win32-x64-msvc@14.1.1-canary.70:
resolution: {integrity: sha512-0URUGOsTfddsxQORgX4TIRBQUEhlZve8K+XxTEQXj23caUktwQjRVkI7Pah6prPuHTf3OeKhnnfVMLCFyHW8Rw==}
/@next/swc-win32-x64-msvc@14.1.1-canary.71:
resolution: {integrity: sha512-hfrhD5DEYjgdzS+v56j9KOirN0qPTjtSQF5rlJJwwOMfZmFtrAzhD0uhj4KUC+9HMnQpvPRvnm71JgmGzFI1Mw==}
engines: {node: '>= 10'}
cpu: [x64]
os: [win32]
@ -3243,7 +3243,7 @@ packages:
resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
dev: false
/@vercel/analytics@1.2.2(next@14.1.1-canary.70)(react@18.2.0):
/@vercel/analytics@1.2.2(next@14.1.1-canary.71)(react@18.2.0):
resolution: {integrity: sha512-X0rctVWkQV1e5Y300ehVNqpOfSOufo7ieA5PIdna8yX/U7Vjz0GFsGf4qvAhxV02uQ2CVt7GYcrFfddXXK2Y4A==}
peerDependencies:
next: '>= 13'
@ -3254,7 +3254,7 @@ packages:
react:
optional: true
dependencies:
next: 14.1.1-canary.70(@babel/core@7.23.9)(react-dom@18.2.0)(react@18.2.0)
next: 14.1.1-canary.71(@babel/core@7.23.9)(react-dom@18.2.0)(react@18.2.0)
react: 18.2.0
server-only: 0.0.1
dev: false
@ -3279,7 +3279,7 @@ packages:
ws: 8.14.2(bufferutil@4.0.8)(utf-8-validate@6.0.3)
dev: false
/@vercel/speed-insights@1.0.10(next@14.1.1-canary.70)(react@18.2.0):
/@vercel/speed-insights@1.0.10(next@14.1.1-canary.71)(react@18.2.0):
resolution: {integrity: sha512-4uzdKB0RW6Ff2FkzshzjZ+RlJfLPxgm/00i0XXgxfMPhwnnsk92YgtqsxT9OcPLdJUyVU1DqFlSWWjIQMPkh0g==}
requiresBuild: true
peerDependencies:
@ -3303,7 +3303,7 @@ packages:
vue-router:
optional: true
dependencies:
next: 14.1.1-canary.70(@babel/core@7.23.9)(react-dom@18.2.0)(react@18.2.0)
next: 14.1.1-canary.71(@babel/core@7.23.9)(react-dom@18.2.0)(react@18.2.0)
react: 18.2.0
dev: false
@ -6194,11 +6194,11 @@ packages:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
dev: false
/next-auth@5.0.0-beta.9(next@14.1.1-canary.70)(react@18.2.0):
resolution: {integrity: sha512-BWFiwJ/wzfxWpHnGpAoFsXHSlVofWgFns6tjtIGeDrXfEf3D+afnBpmzCNyek2RNYDVgMHi8Q5uXzFoNBd2l5g==}
/next-auth@5.0.0-beta.13(next@14.1.1-canary.71)(react@18.2.0):
resolution: {integrity: sha512-2m2Gq69WQ0YXcHCCpHn2y5z1bxSlqD/XOuAgrdtz49/VIAdTFFeYZz97RYqf6xMF8VGmoG32VUnJ6LzaHk6Fwg==}
peerDependencies:
'@simplewebauthn/browser': ^9.0.1
'@simplewebauthn/server': ^9.0.1
'@simplewebauthn/server': ^9.0.2
next: ^14
nodemailer: ^6.6.5
react: ^18.2.0
@ -6210,25 +6210,25 @@ packages:
nodemailer:
optional: true
dependencies:
'@auth/core': 0.26.3
next: 14.1.1-canary.70(@babel/core@7.23.9)(react-dom@18.2.0)(react@18.2.0)
'@auth/core': 0.27.0
next: 14.1.1-canary.71(@babel/core@7.23.9)(react-dom@18.2.0)(react@18.2.0)
react: 18.2.0
dev: false
/next-themes@0.2.1(next@14.1.1-canary.70)(react-dom@18.2.0)(react@18.2.0):
/next-themes@0.2.1(next@14.1.1-canary.71)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-B+AKNfYNIzh0vqQQKqQItTS8evEouKD7H5Hj3kmuPERwddR2TxvDSFZuTj6T7Jfn1oyeUyJMydPl1Bkxkh0W7A==}
peerDependencies:
next: '*'
react: '*'
react-dom: '*'
dependencies:
next: 14.1.1-canary.70(@babel/core@7.23.9)(react-dom@18.2.0)(react@18.2.0)
next: 14.1.1-canary.71(@babel/core@7.23.9)(react-dom@18.2.0)(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
dev: false
/next@14.1.1-canary.70(@babel/core@7.23.9)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-mTi8FgDUuU/pnNUbfEPUG3CtlmQJz+WbHbSuE75DBtxUZe7g4IY92336TiQBaoyNnhRJBCjCILWFFj8XZCEtjQ==}
/next@14.1.1-canary.71(@babel/core@7.23.9)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-Es0dlb3GNtOQoTnsgU9tXLQbALDuz9q6JtRp/WCIHJW2T5EBOoJ8Gvh1IDn1eC5vWDpuRpMMdSoimc3/JWzguA==}
engines: {node: '>=18.17.0'}
hasBin: true
peerDependencies:
@ -6242,7 +6242,7 @@ packages:
sass:
optional: true
dependencies:
'@next/env': 14.1.1-canary.70
'@next/env': 14.1.1-canary.71
'@swc/helpers': 0.5.5
busboy: 1.6.0
caniuse-lite: 1.0.30001585
@ -6252,15 +6252,15 @@ packages:
react-dom: 18.2.0(react@18.2.0)
styled-jsx: 5.1.1(@babel/core@7.23.9)(react@18.2.0)
optionalDependencies:
'@next/swc-darwin-arm64': 14.1.1-canary.70
'@next/swc-darwin-x64': 14.1.1-canary.70
'@next/swc-linux-arm64-gnu': 14.1.1-canary.70
'@next/swc-linux-arm64-musl': 14.1.1-canary.70
'@next/swc-linux-x64-gnu': 14.1.1-canary.70
'@next/swc-linux-x64-musl': 14.1.1-canary.70
'@next/swc-win32-arm64-msvc': 14.1.1-canary.70
'@next/swc-win32-ia32-msvc': 14.1.1-canary.70
'@next/swc-win32-x64-msvc': 14.1.1-canary.70
'@next/swc-darwin-arm64': 14.1.1-canary.71
'@next/swc-darwin-x64': 14.1.1-canary.71
'@next/swc-linux-arm64-gnu': 14.1.1-canary.71
'@next/swc-linux-arm64-musl': 14.1.1-canary.71
'@next/swc-linux-x64-gnu': 14.1.1-canary.71
'@next/swc-linux-x64-musl': 14.1.1-canary.71
'@next/swc-win32-arm64-msvc': 14.1.1-canary.71
'@next/swc-win32-ia32-msvc': 14.1.1-canary.71
'@next/swc-win32-x64-msvc': 14.1.1-canary.71
transitivePeerDependencies:
- '@babel/core'
- babel-plugin-macros

View File

@ -1,22 +1,87 @@
'use client';
/* eslint-disable jsx-a11y/alt-text */
import { BLUR_ENABLED } from '@/site/config';
import { clsx} from 'clsx/lite';
import Image, { ImageProps } from 'next/image';
import { useEffect, useRef, useState } from 'react';
export default function ImageBlurFallback(props: ImageProps) {
const {
className,
priority,
blurDataURL,
...rest
} = props;
const [wasCached, setWasCached] = useState(true);
const [isLoading, setIsLoading] = useState(true);
const [didError, setDidError] = useState(false);
const [hideBlurPlaceholder, setHideBlurPlaceholder] = useState(false);
const imageClassName = 'object-cover h-full';
const imgRef = useRef<HTMLImageElement>(null);
useEffect(() => {
const timeout = setTimeout(
() => setWasCached(imgRef.current?.complete ?? false),
100,
);
return () => clearTimeout(timeout);
}, []);
useEffect(() => {
if (!isLoading && !didError) {
const timeout = setTimeout(() => {
setHideBlurPlaceholder(true);
}, 1000);
return () => clearTimeout(timeout);
}
}, [isLoading, didError]);
const showPlaceholder =
!wasCached &&
!hideBlurPlaceholder;
return (
// eslint-disable-next-line jsx-a11y/alt-text
<Image {...{
...props,
...BLUR_ENABLED && props.blurDataURL ? {
placeholder: 'blur',
blurDataURL: props.blurDataURL,
}: {
placeholder: 'empty',
<div
className={clsx(
className,
'flex relative',
)}
>
{showPlaceholder &&
<div className={clsx(
'absolute inset-0',
'bg-main overflow-hidden',
'transition-opacity duration-300 ease-in',
isLoading ? 'opacity-100' : 'opacity-0',
)}>
{(BLUR_ENABLED && props.blurDataURL)
? <img {...{
...rest,
src: blurDataURL,
className: clsx(
props.className,
'bg-gray-100/50 dark:bg-gray-900/50',
imageClassName,
// Fix poorly blurred placeholder data generated by Safari
'blur-md scale-110',
),
},
}} />
: <div className={clsx(
'w-full h-full',
'bg-gray-100/50 dark:bg-gray-900/50',
)}/>}
</div>}
<Image {...{
...rest,
ref: imgRef,
priority,
className: imageClassName,
onLoad: () => setIsLoading(false),
onError: () => setDidError(true),
}} />
</div>
);
}

View File

@ -23,7 +23,6 @@ export default function ImageSmall({
alt,
priority,
blurDataURL: blurData,
placeholder: 'blur',
width: IMAGE_SMALL_WIDTH,
height: Math.round(IMAGE_SMALL_WIDTH / aspectRatio),
}} />

View File

@ -19,10 +19,7 @@ export default function ImageTiny({
className,
src,
alt,
...blurData && {
blurDataURL: blurData,
placeholder: 'blur',
},
width: IMAGE_TINY_WIDTH,
height: Math.round(IMAGE_TINY_WIDTH / aspectRatio),
}} />

View File

@ -55,12 +55,7 @@ export default function PhotoGrid({
<div
key={photo.id}
className={GRID_ASPECT_RATIO !== 0
? clsx(
'aspect-square',
'overflow-hidden',
'[&>*]:flex [&>*]:w-full [&>*]:h-full',
'[&>*>*]:object-cover [&>*>*]:min-h-full',
)
? 'aspect-square overflow-hidden'
: undefined}
style={{
...GRID_ASPECT_RATIO !== 0 && {

View File

@ -5,8 +5,6 @@ import { clsx } from 'clsx/lite';
import { pathForPhoto } from '@/site/paths';
import { Camera } from '@/camera';
import { FilmSimulation } from '@/simulation';
import AdminPhotoMenu from '@/admin/AdminPhotoMenu';
import { Suspense } from 'react';
export default function PhotoSmall({
photo,
@ -14,7 +12,6 @@ export default function PhotoSmall({
camera,
simulation,
selected,
showAdminMenu,
priority,
}: {
photo: Photo
@ -22,28 +19,17 @@ export default function PhotoSmall({
camera?: Camera
simulation?: FilmSimulation
selected?: boolean
showAdminMenu?: boolean
priority?: boolean
}) {
return (
<Link
href={pathForPhoto(photo, tag, camera, simulation)}
className={clsx(
'relative group',
'flex w-full h-full',
'active:brightness-75',
selected && 'brightness-50',
)}
>
<Suspense>
{showAdminMenu &&
<AdminPhotoMenu
buttonClassName={clsx(
'absolute top-1 right-1 opacity-0',
'group-hover:opacity-100 group-focus:opacity-100',
)}
photo={photo}
/>}
</Suspense>
<ImageSmall
src={photo.url}
aspectRatio={photo.aspectRatio}

View File

@ -5,4 +5,4 @@ export const IMAGE_TINY_WIDTH = 50;
export const IMAGE_SMALL_WIDTH = 300;
// Height determined by intrinsic photo aspect ratio
export const IMAGE_LARGE_WIDTH = 900;
export const IMAGE_LARGE_WIDTH = 1080;