Fix ESLINT 9 configuration

This commit is contained in:
Sam Becker 2025-01-05 19:47:40 -06:00
parent 6e72c02769
commit e45c1eb8d9
34 changed files with 96 additions and 95 deletions

View File

@ -1,38 +0,0 @@
{
"extends": "next/core-web-vitals",
"plugins": ["@typescript-eslint"],
"rules": {
"@next/next/no-img-element": "off",
"@typescript-eslint/no-unused-expressions": ["warn"],
"@typescript-eslint/no-unused-vars": [
"warn", {
"argsIgnorePattern": "^_",
"varsIgnorePattern": "^_"
}
],
"comma-dangle": [
"warn",
"always-multiline"
],
"indent": [
"warn",
2
],
"linebreak-style": [
"warn",
"unix"
],
"quotes": [
"warn",
"single"
],
"semi": [
"warn",
"always"
],
"max-len": [
"warn",
{ "code": 80 }
]
}
}

51
eslint.config.mjs Normal file
View File

@ -0,0 +1,51 @@
import { dirname } from 'path';
import { fileURLToPath } from 'url';
import { FlatCompat } from '@eslint/eslintrc';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const compat = new FlatCompat({
baseDirectory: __dirname,
});
const eslintConfig = [
...compat.extends('next/core-web-vitals', 'next/typescript'), {
rules: {
'@next/next/no-img-element': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'no-unused-expressions': 'warn',
'@typescript-eslint/no-unused-vars': [
'warn', {
'argsIgnorePattern': '^_',
'varsIgnorePattern': '^_',
},
],
'comma-dangle': [
'warn',
'always-multiline',
],
'indent': [
'warn',
2,
],
'linebreak-style': [
'warn',
'unix',
],
'quotes': [
'warn',
'single',
],
'semi': [
'warn',
'always',
],
'max-len': [
'warn',
{ 'code': 80 },
],
},
}];
export default eslintConfig;

View File

@ -26,8 +26,6 @@
"@types/react": "19.0.2", "@types/react": "19.0.2",
"@types/react-dom": "19.0.2", "@types/react-dom": "19.0.2",
"@types/sanitize-html": "^2.13.0", "@types/sanitize-html": "^2.13.0",
"@typescript-eslint/eslint-plugin": "^8.19.0",
"@typescript-eslint/parser": "^8.19.0",
"@upstash/ratelimit": "^2.0.5", "@upstash/ratelimit": "^2.0.5",
"@vercel/analytics": "^1.4.1", "@vercel/analytics": "^1.4.1",
"@vercel/blob": "^0.27.0", "@vercel/blob": "^0.27.0",

6
pnpm-lock.yaml generated
View File

@ -59,12 +59,6 @@ importers:
'@types/sanitize-html': '@types/sanitize-html':
specifier: ^2.13.0 specifier: ^2.13.0
version: 2.13.0 version: 2.13.0
'@typescript-eslint/eslint-plugin':
specifier: ^8.19.0
version: 8.19.0(@typescript-eslint/parser@8.19.0(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.2))(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.2)
'@typescript-eslint/parser':
specifier: ^8.19.0
version: 8.19.0(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.2)
'@upstash/ratelimit': '@upstash/ratelimit':
specifier: ^2.0.5 specifier: ^2.0.5
version: 2.0.5(@upstash/redis@1.34.3) version: 2.0.5(@upstash/redis@1.34.3)

View File

@ -58,7 +58,7 @@ export default function AdminAddAllUploads({
for await (const data of readStreamableValue(stream)) { for await (const data of readStreamableValue(stream)) {
setButtonText(addedUploadCount.current === 0 setButtonText(addedUploadCount.current === 0
? `Adding 1 of ${storageUrls.length}` ? `Adding 1 of ${storageUrls.length}`
: `Adding ${addedUploadCount.current + 1} of ${storageUrls.length}` : `Adding ${addedUploadCount.current + 1} of ${storageUrls.length}`,
); );
setUrlAddStatuses(current => { setUrlAddStatuses(current => {
const update = current.map(status => const update = current.map(status =>
@ -70,7 +70,7 @@ export default function AdminAddAllUploads({
statusMessage: data.statusMessage, statusMessage: data.statusMessage,
progress: data.progress, progress: data.progress,
} }
: status : status,
); );
addedUploadCount.current = update addedUploadCount.current = update
.filter(({ status }) => status === 'added') .filter(({ status }) => status === 'added')

View File

@ -48,7 +48,7 @@ export default function AdminOutdatedClient({
onClick={async () => { onClick={async () => {
if (window.confirm( if (window.confirm(
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
`Are you sure you want to sync the oldest ${updateBatchSize} photos? This action cannot be undone.` `Are you sure you want to sync the oldest ${updateBatchSize} photos? This action cannot be undone.`,
)) { )) {
const photosToSync = photos const photosToSync = photos
.slice(0, updateBatchSize) .slice(0, updateBatchSize)

View File

@ -9,7 +9,7 @@ import { BiTrash } from 'react-icons/bi';
export default function DeleteFormButton ( export default function DeleteFormButton (
props: ComponentProps<typeof SubmitButtonWithStatus> & { props: ComponentProps<typeof SubmitButtonWithStatus> & {
clearLocalState?: boolean clearLocalState?: boolean
} },
) { ) {
const { const {
onFormSubmit: onFormSubmitProps, onFormSubmit: onFormSubmitProps,

View File

@ -9,7 +9,7 @@ import { CONFIG_CHECKLIST_STATUS } from '@/site/config';
const scanForError = ( const scanForError = (
shouldCheck: boolean, shouldCheck: boolean,
promise: () => Promise<any> promise: () => Promise<any>,
): Promise<string> => ): Promise<string> =>
shouldCheck shouldCheck
? promise() ? promise()

View File

@ -184,7 +184,7 @@ export default function ComponentsPage() {
{DEBUG_LINES.map((_, i) => {DEBUG_LINES.map((_, i) =>
<div key={i}> <div key={i}>
Line {(i + 1).toString().padStart(2, '0')} Line {(i + 1).toString().padStart(2, '0')}
</div> </div>,
)} )}
</div> </div>
</DivDebugBaselineGrid> </DivDebugBaselineGrid>

View File

@ -28,13 +28,13 @@ export default async function PhotoEditPage({
// Only generate image thumbnails when AI generation is enabled // Only generate image thumbnails when AI generation is enabled
const imageThumbnailBase64 = AI_TEXT_GENERATION_ENABLED const imageThumbnailBase64 = AI_TEXT_GENERATION_ENABLED
? await resizeImageFromUrl( ? await resizeImageFromUrl(
getNextImageUrlForManipulation(photo.url, IS_PREVIEW) getNextImageUrlForManipulation(photo.url, IS_PREVIEW),
) )
: ''; : '';
const blurData = BLUR_ENABLED const blurData = BLUR_ENABLED
? await blurImageFromUrl( ? await blurImageFromUrl(
getNextImageUrlForManipulation(photo.url, IS_PREVIEW) getNextImageUrlForManipulation(photo.url, IS_PREVIEW),
) )
: ''; : '';

View File

@ -25,7 +25,7 @@ export async function GET(
CURRENT_STORAGE === 'cloudflare-r2' CURRENT_STORAGE === 'cloudflare-r2'
? cloudflareR2PutObjectCommandForKey(key) ? cloudflareR2PutObjectCommandForKey(key)
: awsS3PutObjectCommandForKey(key), : awsS3PutObjectCommandForKey(key),
{ expiresIn: 3600 } { expiresIn: 3600 },
); );
return new Response( return new Response(
url, url,

View File

@ -58,7 +58,7 @@ export const cameraFromPhoto = (
export const formatCameraText = ( export const formatCameraText = (
{ make: makeRaw, model: modelRaw }: Camera, { make: makeRaw, model: modelRaw }: Camera,
includeMake: 'always' | 'never' | 'if-not-apple' = 'if-not-apple', includeMake: 'always' | 'never' | 'if-not-apple' = 'if-not-apple',
removeIPhoneOnLongModels?: boolean removeIPhoneOnLongModels?: boolean,
) => { ) => {
// Remove 'Corporation' from makes like 'Nikon Corporation' // Remove 'Corporation' from makes like 'Nikon Corporation'
const make = makeRaw.replace(/ Corporation/i, ''); const make = makeRaw.replace(/ Corporation/i, '');

View File

@ -70,7 +70,7 @@ export default function FieldSetWithStatus({
</span>} </span>}
{isModified && !error && {isModified && !error &&
<span className={clsx( <span className={clsx(
'text-main font-medium text-[0.9rem] -ml-1.5 translate-y-[-1px]' 'text-main font-medium text-[0.9rem] -ml-1.5 translate-y-[-1px]',
)}> )}>
* *
</span>} </span>}

View File

@ -104,7 +104,7 @@ export default function ImageInput({
// Specify wide gamut to avoid data loss while resizing // Specify wide gamut to avoid data loss while resizing
const ctx = canvas?.getContext( const ctx = canvas?.getContext(
'2d', { colorSpace: 'display-p3' } '2d', { colorSpace: 'display-p3' },
); );
if ((shouldResize || isPng) && canvas && ctx) { if ((shouldResize || isPng) && canvas && ctx) {

View File

@ -47,7 +47,7 @@ import { formatCount, formatCountDescriptive } from '@/utility/string';
import CommandKItem from './CommandKItem'; import CommandKItem from './CommandKItem';
import { GRID_HOMEPAGE_ENABLED } from '@/site/config'; import { GRID_HOMEPAGE_ENABLED } from '@/site/config';
import { DialogDescription, DialogTitle } from '@radix-ui/react-dialog'; import { DialogDescription, DialogTitle } from '@radix-ui/react-dialog';
import * as VisuallyHidden from "@radix-ui/react-visually-hidden"; import * as VisuallyHidden from '@radix-ui/react-visually-hidden';
const DIALOG_TITLE = 'Global Command-K Menu'; const DIALOG_TITLE = 'Global Command-K Menu';
const DIALOG_DESCRIPTION = 'For searching photos, views, and settings'; const DIALOG_DESCRIPTION = 'For searching photos, views, and settings';

View File

@ -46,7 +46,7 @@ export default function MoreMenu({
)} )}
> >
{items.map(props => {items.map(props =>
<MoreMenuItem key={`${props.label}`} {...props} /> <MoreMenuItem key={`${props.label}`} {...props} />,
)} )}
</DropdownMenu.Content> </DropdownMenu.Content>
</DropdownMenu.Portal> </DropdownMenu.Portal>

View File

@ -44,7 +44,7 @@ export default function LabeledIcon({
{children && type !== 'icon-only' && {children && type !== 'icon-only' &&
<span className={clsx( <span className={clsx(
'uppercase', 'uppercase',
debug && 'bg-gray-700' debug && 'bg-gray-700',
)}> )}>
{children} {children}
</span>} </span>}

View File

@ -80,7 +80,7 @@ export default function ImagePhotoGrid({
objectFit: 'cover', objectFit: 'cover',
}, },
}} /> }} />
</div> </div>,
)} )}
</div> </div>
); );

View File

@ -27,7 +27,7 @@ export default function PhotoGridPage({
useEffect( useEffect(
() => () => setSelectedPhotoIds?.(undefined), () => () => setSelectedPhotoIds?.(undefined),
[setSelectedPhotoIds] [setSelectedPhotoIds],
); );
return ( return (

View File

@ -176,7 +176,7 @@ export const addAllUploadsAction = async ({
})(); })();
if (shouldRevalidateAllKeysAndPaths) { if (shouldRevalidateAllKeysAndPaths) {
after(revalidateAllKeysAndPaths) after(revalidateAllKeysAndPaths);
} }
return stream.value; return stream.value;
@ -355,7 +355,7 @@ export const syncPhotoAction = async (photoId: string) =>
semanticDescription: aiSemanticDescription, semanticDescription: aiSemanticDescription,
} = await generateAiImageQueries( } = await generateAiImageQueries(
imageResizedBase64, imageResizedBase64,
AI_TEXT_AUTO_GENERATED_FIELDS AI_TEXT_AUTO_GENERATED_FIELDS,
); );
const photoFormDbInsert = convertFormDataToPhotoDbInsert({ const photoFormDbInsert = convertFormDataToPhotoDbInsert({

View File

@ -81,7 +81,7 @@ const getPhotosCacheKeys = (options: GetPhotosOptions = {}) => {
Object.keys(options).forEach(key => { Object.keys(options).forEach(key => {
const tag = getPhotosCacheKeyForOption( const tag = getPhotosCacheKeyForOption(
options, options,
key as keyof GetPhotosOptions key as keyof GetPhotosOptions,
); );
if (tag) { tags.push(tag); } if (tag) { tags.push(tag); }
}); });
@ -181,7 +181,7 @@ export const getPhotosMostRecentUpdateCached =
export const getPhotoCached = (...args: Parameters<typeof getPhoto>) => export const getPhotoCached = (...args: Parameters<typeof getPhoto>) =>
unstable_cache( unstable_cache(
getPhoto, getPhoto,
[KEY_PHOTOS, KEY_PHOTO] [KEY_PHOTOS, KEY_PHOTO],
)(...args).then(photo => photo ? parseCachedPhotoDates(photo) : undefined); )(...args).then(photo => photo ? parseCachedPhotoDates(photo) : undefined);
export const getUniqueTagsCached = export const getUniqueTagsCached =
@ -193,19 +193,19 @@ export const getUniqueTagsCached =
export const getUniqueTagsHiddenCached = export const getUniqueTagsHiddenCached =
unstable_cache( unstable_cache(
getUniqueTagsHidden, getUniqueTagsHidden,
[KEY_PHOTOS, KEY_TAGS, KEY_HIDDEN] [KEY_PHOTOS, KEY_TAGS, KEY_HIDDEN],
); );
export const getUniqueCamerasCached = export const getUniqueCamerasCached =
unstable_cache( unstable_cache(
getUniqueCameras, getUniqueCameras,
[KEY_PHOTOS, KEY_CAMERAS] [KEY_PHOTOS, KEY_CAMERAS],
); );
export const getUniqueLensesCached = export const getUniqueLensesCached =
unstable_cache( unstable_cache(
getUniqueLenses, getUniqueLenses,
[KEY_PHOTOS, KEY_LENSES] [KEY_PHOTOS, KEY_LENSES],
); );
export const getUniqueFilmSimulationsCached = export const getUniqueFilmSimulationsCached =

View File

@ -21,7 +21,7 @@ export const areOptionsSensitive = (options: GetPhotosOptions) =>
export const getWheresFromOptions = ( export const getWheresFromOptions = (
options: GetPhotosOptions, options: GetPhotosOptions,
initialValuesIndex = 1 initialValuesIndex = 1,
) => { ) => {
const { const {
hidden = 'exclude', hidden = 'exclude',

View File

@ -80,7 +80,7 @@ const runMigration02 = () =>
// Wrapper for most queries for JIT table creation/migration running // Wrapper for most queries for JIT table creation/migration running
const safelyQueryPhotos = async <T>( const safelyQueryPhotos = async <T>(
callback: () => Promise<T>, callback: () => Promise<T>,
debugMessage: string debugMessage: string,
): Promise<T> => { ): Promise<T> => {
let result: T; let result: T;
@ -370,8 +370,6 @@ export const getPhotos = async (options: GetPhotosOptions = {}) =>
lastValuesIndex, lastValuesIndex,
} = getWheresFromOptions(options); } = getWheresFromOptions(options);
let valuesIndex = lastValuesIndex;
if (wheres) { if (wheres) {
sql.push(wheres); sql.push(wheres);
values.push(...wheresValues); values.push(...wheresValues);
@ -382,7 +380,7 @@ export const getPhotos = async (options: GetPhotosOptions = {}) =>
const { const {
limitAndOffset, limitAndOffset,
limitAndOffsetValues, limitAndOffsetValues,
} = getLimitAndOffsetFromOptions(options, valuesIndex); } = getLimitAndOffsetFromOptions(options, lastValuesIndex);
// LIMIT + OFFSET // LIMIT + OFFSET
sql.push(limitAndOffset); sql.push(limitAndOffset);
@ -421,7 +419,7 @@ export const getPhotosNearId = async (
WHERE twi.row_number >= current.row_number - 1 WHERE twi.row_number >= current.row_number - 1
LIMIT $${valuesIndex++} LIMIT $${valuesIndex++}
`, `,
[...wheresValues, photoId, limit] [...wheresValues, photoId, limit],
) )
.then(({ rows }) => { .then(({ rows }) => {
const photo = rows.find(({ id }) => id === photoId); const photo = rows.find(({ id }) => id === photoId);

View File

@ -133,7 +133,7 @@ export const convertFormKeysToLabels = (keys: (keyof PhotoFormData)[]) =>
keys.map(key => FORM_METADATA()[key].label.toUpperCase()); keys.map(key => FORM_METADATA()[key].label.toUpperCase());
export const getFormErrors = ( export const getFormErrors = (
formData: Partial<PhotoFormData> formData: Partial<PhotoFormData>,
): Partial<Record<keyof PhotoFormData, string>> => ): Partial<Record<keyof PhotoFormData, string>> =>
Object.keys(formData).reduce((acc, key) => ({ Object.keys(formData).reduce((acc, key) => ({
...acc, ...acc,
@ -147,7 +147,7 @@ export const isFormValid = (formData: Partial<PhotoFormData>) =>
(!required || Boolean(formData[key])) && (!required || Boolean(formData[key])) &&
(!validate?.(formData[key])) && (!validate?.(formData[key])) &&
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
(!validateStringMaxLength || (formData[key]?.length ?? 0) <= validateStringMaxLength) (!validateStringMaxLength || (formData[key]?.length ?? 0) <= validateStringMaxLength),
); );
export const formHasTextContent = ({ export const formHasTextContent = ({
@ -302,12 +302,12 @@ export const getChangedFormFields = (
.keys(current) .keys(current)
.filter(key => .filter(key =>
(original[key as keyof PhotoFormData] ?? '') !== (original[key as keyof PhotoFormData] ?? '') !==
(current[key as keyof PhotoFormData] ?? '') (current[key as keyof PhotoFormData] ?? ''),
) as (keyof PhotoFormData)[]; ) as (keyof PhotoFormData)[];
}; };
export const generateTakenAtFields = ( export const generateTakenAtFields = (
form?: Partial<PhotoFormData> form?: Partial<PhotoFormData>,
): { takenAt: string, takenAtNaive: string } => ({ ): { takenAt: string, takenAtNaive: string } => ({
takenAt: form?.takenAt || generateLocalPostgresString(), takenAt: form?.takenAt || generateLocalPostgresString(),
takenAtNaive: form?.takenAtNaive || generateLocalNaivePostgresString(), takenAtNaive: form?.takenAtNaive || generateLocalNaivePostgresString(),

View File

@ -112,7 +112,7 @@ export interface PhotoSetAttributes {
export const parsePhotoFromDb = (photoDbRaw: PhotoDb): Photo => { export const parsePhotoFromDb = (photoDbRaw: PhotoDb): Photo => {
const photoDb = camelcaseKeys( const photoDb = camelcaseKeys(
photoDbRaw as unknown as Record<string, unknown> photoDbRaw as unknown as Record<string, unknown>,
) as unknown as PhotoDb; ) as unknown as PhotoDb;
return { return {
...photoDb, ...photoDb,
@ -193,7 +193,7 @@ export const generateOgImageMetaForPhotos = (photos: Photo[]): Metadata => {
}; };
const PHOTO_ID_FORWARDING_TABLE: Record<string, string> = JSON.parse( const PHOTO_ID_FORWARDING_TABLE: Record<string, string> = JSON.parse(
process.env.PHOTO_ID_FORWARDING_TABLE || '{}' process.env.PHOTO_ID_FORWARDING_TABLE || '{}',
); );
export const translatePhotoId = (id: string) => export const translatePhotoId = (id: string) =>
@ -251,7 +251,7 @@ export const descriptionForPhotoSet = (
const sortPhotosByDate = ( const sortPhotosByDate = (
photos: Photo[], photos: Photo[],
order: 'ASC' | 'DESC' = 'DESC' order: 'ASC' | 'DESC' = 'DESC',
) => ) =>
[...photos].sort((a, b) => order === 'DESC' [...photos].sort((a, b) => order === 'DESC'
? b.takenAt.getTime() - a.takenAt.getTime() ? b.takenAt.getTime() - a.takenAt.getTime()

View File

@ -117,14 +117,14 @@ const generateBase64 = async (
const resizeImage = async (image: ArrayBuffer) => const resizeImage = async (image: ArrayBuffer) =>
generateBase64(image, sharp => sharp generateBase64(image, sharp => sharp
.resize(IMAGE_WIDTH_RESIZE) .resize(IMAGE_WIDTH_RESIZE),
); );
const blurImage = async (image: ArrayBuffer) => const blurImage = async (image: ArrayBuffer) =>
generateBase64(image, sharp => sharp generateBase64(image, sharp => sharp
.resize(IMAGE_WIDTH_BLUR) .resize(IMAGE_WIDTH_BLUR)
.modulate({ saturation: 1.15 }) .modulate({ saturation: 1.15 })
.blur(4) .blur(4),
); );
export const resizeImageFromUrl = async (url: string) => export const resizeImageFromUrl = async (url: string) =>

View File

@ -25,7 +25,7 @@ export const convertUploadToPhoto = async ({
if (shouldStripGpsData) { if (shouldStripGpsData) {
const fileWithoutGps = await removeGpsData( const fileWithoutGps = await removeGpsData(
fileBytes ?? await fetch(urlOrigin, { cache: 'no-store' }) fileBytes ?? await fetch(urlOrigin, { cache: 'no-store' })
.then(res => res.arrayBuffer()) .then(res => res.arrayBuffer()),
); );
return putFile(fileWithoutGps, photoPath).then(async url => { return putFile(fileWithoutGps, photoPath).then(async url => {
if (url && shouldDeleteOrigin) { await deleteFile(urlOrigin); } if (url && shouldDeleteOrigin) { await deleteFile(urlOrigin); }

View File

@ -1,5 +1,3 @@
/* eslint-disable max-len */
const INTRINSIC_WIDTH = 28; const INTRINSIC_WIDTH = 28;
const INTRINSIC_HEIGHT = 24; const INTRINSIC_HEIGHT = 24;

View File

@ -262,7 +262,7 @@ export default function SiteChecklistClient({
)} )}
{' '} {' '}
and connect to project and connect to project
</> </>,
)} )}
{hasCloudflareR2Storage {hasCloudflareR2Storage
? renderSubStatus('checked', 'Cloudflare R2: connected') ? renderSubStatus('checked', 'Cloudflare R2: connected')

View File

@ -14,7 +14,7 @@ const getFontData = async () => {
} else { } else {
data = await fetch(new URL( data = await fetch(new URL(
'/public/fonts/IBMPlexMono-Medium.ttf', '/public/fonts/IBMPlexMono-Medium.ttf',
import.meta.url import.meta.url,
)).then(res => res.arrayBuffer()); )).then(res => res.arrayBuffer());
} }
return data; return data;

View File

@ -7,7 +7,7 @@ export const getOffsetFromExif = (data: ExifData) =>
Object.values(data.tags as any) Object.values(data.tags as any)
.find((value: any) => .find((value: any) =>
typeof value === 'string' && typeof value === 'string' &&
OFFSET_REGEX.test(value) OFFSET_REGEX.test(value),
) as string | undefined; ) as string | undefined;
export const getAspectRatioFromExif = (data: ExifData): number => { export const getAspectRatioFromExif = (data: ExifData): number => {
@ -32,7 +32,7 @@ export const getAspectRatioFromExif = (data: ExifData): number => {
}; };
export const convertApertureValueToFNumber = ( export const convertApertureValueToFNumber = (
apertureValue?: string apertureValue?: string,
): string | undefined => { ): string | undefined => {
if (apertureValue) { if (apertureValue) {
const aperture = parseInt(apertureValue); const aperture = parseInt(apertureValue);

View File

@ -2,7 +2,7 @@ import { useEffect } from 'react';
export default function useOnVisible( export default function useOnVisible(
ref: React.RefObject<HTMLElement | null>, ref: React.RefObject<HTMLElement | null>,
onVisible?: () => void onVisible?: () => void,
) { ) {
useEffect(() => { useEffect(() => {
if (onVisible && ref.current) { if (onVisible && ref.current) {

View File

@ -9,7 +9,7 @@ const safelyGetMediaQuery = () => typeof window !== 'undefined'
const usePrefersReducedMotion = () => { const usePrefersReducedMotion = () => {
const [prefersReducedMotion, setPrefersReducedMotion] = useState<boolean>( const [prefersReducedMotion, setPrefersReducedMotion] = useState<boolean>(
safelyGetMediaQuery()?.matches ?? false safelyGetMediaQuery()?.matches ?? false,
); );
useEffect(() => { useEffect(() => {

View File

@ -233,7 +233,7 @@ export const labelForFilmSimulation = (simulation: FujifilmSimulation) =>
const parseFujifilmMakerNote = ( const parseFujifilmMakerNote = (
bytes: Buffer, bytes: Buffer,
valueForTagUInt: (tagId: number, value: number) => void valueForTagUInt: (tagId: number, value: number) => void,
) => { ) => {
const tagCount = bytes.readUint16LE(BYTE_INDEX_TAG_COUNT); const tagCount = bytes.readUint16LE(BYTE_INDEX_TAG_COUNT);
for (let i = 0; i < tagCount; i++) { for (let i = 0; i < tagCount; i++) {