Disable checks + base64 rendering

This commit is contained in:
Sam Becker 2026-02-18 08:30:00 -06:00
parent 6f58b08e7a
commit 6ba4cfe1e3
4 changed files with 44 additions and 26 deletions

View File

@ -3,8 +3,11 @@
import { Photo } from '@/photo'; import { Photo } from '@/photo';
import { NextImageSize } from '@/platforms/next-image'; import { NextImageSize } from '@/platforms/next-image';
import { IS_PREVIEW } from '@/app/config'; import { IS_PREVIEW } from '@/app/config';
import { getOptimizedPhotoUrl } from '@/photo/storage'; import {
import { fetchBase64ImageFromUrl } from '@/utility/image'; getOptimizedPhotoUrl,
getOptimizedPhotoUrlForSuffix,
} from '@/photo/storage';
// import { fetchBase64ImageFromUrl } from '@/utility/image';
import { getSignedUrlForUrl } from '@/platforms/storage'; import { getSignedUrlForUrl } from '@/platforms/storage';
export default async function ImagePhotoGrid({ export default async function ImagePhotoGrid({
@ -36,6 +39,10 @@ export default async function ImagePhotoGrid({
? width ?? 1080 ? width ?? 1080
: 640; : 640;
const optimizedSuffix = count <= 2
? 'lg'
: 'md';
let rows = 1; let rows = 1;
if (count > 12) { rows = 4; } if (count > 12) { rows = 4; }
else if (count > 6) { rows = 3; } else if (count > 6) { rows = 3; }
@ -51,14 +58,26 @@ export default async function ImagePhotoGrid({
(rows - 1) * gap / rows; (rows - 1) * gap / rows;
const photoDataUrls = await Promise.all(photos.map(async({ id, url }) => { const photoDataUrls = await Promise.all(photos.map(async({ id, url }) => {
const optimizedUrl = getOptimizedPhotoUrl({ // Check for optimized image first
imageUrl: url, let optimizedUrl = getOptimizedPhotoUrlForSuffix(url, optimizedSuffix);
size: nextImageWidth, // Get presigned URL in case it's required
addBypassSecret: IS_PREVIEW, optimizedUrl = await getSignedUrlForUrl(optimizedUrl, 'GET');
}); const optimizedUrlExists = await fetch(optimizedUrl)
const presignedUrl = await getSignedUrlForUrl(optimizedUrl, 'GET'); .then(res => res.ok)
const data = await fetchBase64ImageFromUrl(presignedUrl); .catch(() => false);
return { id, data };
// Fall back on `next/image` if optimized image is not available
if (!optimizedUrlExists) {
optimizedUrl = getOptimizedPhotoUrl({
imageUrl: url,
size: nextImageWidth,
addBypassSecret: IS_PREVIEW,
});
}
// const data = await fetchBase64ImageFromUrl(optimizedUrl, 'image/jpeg');
return { id, data: optimizedUrl };
})); }));
const renderPhoto = ( const renderPhoto = (

View File

@ -5,7 +5,6 @@ import {
import { import {
generateFileNameWithId, generateFileNameWithId,
getFileNamePartsFromStorageUrl, getFileNamePartsFromStorageUrl,
getSignedUrlForUrl,
getStorageUrlsForPrefix, getStorageUrlsForPrefix,
uploadFileFromClient, uploadFileFromClient,
} from '@/platforms/storage'; } from '@/platforms/storage';
@ -127,25 +126,20 @@ export const getOptimizedPhotoUrlForManipulation = (
compatibilityMode, compatibilityMode,
}); });
const getTestOptimizedPhotoUrl = (url: string) => { export const getOptimizedPhotoUrlForSuffix = (
url: string,
suffix: OptimizedSuffix,
) => {
const { urlBase, fileNameBase } = getFileNamePartsFromStorageUrl(url); const { urlBase, fileNameBase } = getFileNamePartsFromStorageUrl(url);
return getOptimizedUrl({ return getOptimizedUrl({ urlBase, fileNameBase, suffix });
urlBase,
fileNameBase,
suffix: 'sm',
});
}; };
const getTestOptimizedPhotoUrl = (url: string) =>
getOptimizedPhotoUrlForSuffix(url, 'sm');
export const doesPhotoUrlHaveOptimizedFiles = async (url: string) => export const doesPhotoUrlHaveOptimizedFiles = async (url: string) =>
fetch(getTestOptimizedPhotoUrl(url)).then(res => res.ok); fetch(getTestOptimizedPhotoUrl(url)).then(res => res.ok);
export const doAllPhotosHaveOptimizedFiles = async (photos: Photo[]) =>
Promise.all(photos.map(async ({ url }) => fetch(
await getSignedUrlForUrl(getTestOptimizedPhotoUrl(url), 'GET'),
)))
.then(urls => urls.every(url => url.ok))
.catch(() => false);
export const getStorageUrlsForPhoto = async ({ url }: Photo) => { export const getStorageUrlsForPhoto = async ({ url }: Photo) => {
const getSortScoreForUrl = (url: string) => { const getSortScoreForUrl = (url: string) => {
const { fileNameBase } = getFileNamePartsFromStorageUrl(url); const { fileNameBase } = getFileNamePartsFromStorageUrl(url);

View File

@ -20,10 +20,14 @@ export const safePhotoImageResponse = async (
photos: Photo[], photos: Photo[],
jsx: (isNextImageReady: boolean) => JSX.Element, jsx: (isNextImageReady: boolean) => JSX.Element,
options: ConstructorParameters<typeof ImageResponse>[1], options: ConstructorParameters<typeof ImageResponse>[1],
disableCheck = true,
) => { ) => {
// Make sure next/image can be reached from absolute urls, // Make sure next/image can be reached from absolute urls,
// which may not exist on first pre-render // which may not exist on first pre-render
const isNextImageReady = await isNextImageReadyBasedOnPhotos(photos); const isNextImageReady = (
disableCheck ||
await isNextImageReadyBasedOnPhotos(photos)
);
return new ImageResponse( return new ImageResponse(
jsx(isNextImageReady), jsx(isNextImageReady),

View File

@ -4,11 +4,12 @@ export const removeBase64Prefix = (base64: string) => {
export const fetchBase64ImageFromUrl = ( export const fetchBase64ImageFromUrl = (
url: string, url: string,
contentType?: string,
fetchOptions?: RequestInit, fetchOptions?: RequestInit,
) => ) =>
fetch(url, fetchOptions) fetch(url, fetchOptions)
.then(async response => { .then(async response => {
const blob = await response.arrayBuffer(); const blob = await response.arrayBuffer();
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
return `data:${response.headers.get('content-type')};base64,${Buffer.from(blob).toString('base64')}`; return `data:${contentType ?? response.headers.get('content-type')};base64,${Buffer.from(blob).toString('base64')}`;
}); });