Refactor photo set type names

This commit is contained in:
Sam Becker 2025-01-11 13:13:21 -06:00
parent 60169538b3
commit aabe66f202
17 changed files with 41 additions and 46 deletions

View File

@ -1,5 +1,5 @@
import { absolutePathForCamera, pathForCamera } from '@/site/paths'; import { absolutePathForCamera, pathForCamera } from '@/site/paths';
import { Photo, PhotoDateRange } from '../photo'; import { PhotoSetAttributes } from '../photo';
import ShareModal from '@/components/ShareModal'; import ShareModal from '@/components/ShareModal';
import CameraOGTile from './CameraOGTile'; import CameraOGTile from './CameraOGTile';
import { Camera } from '.'; import { Camera } from '.';
@ -12,10 +12,7 @@ export default function CameraShareModal({
dateRange, dateRange,
}: { }: {
camera: Camera camera: Camera
photos: Photo[] } & PhotoSetAttributes) {
count: number
dateRange?: PhotoDateRange,
}) {
return ( return (
<ShareModal <ShareModal
pathShare={absolutePathForCamera(camera)} pathShare={absolutePathForCamera(camera)}

View File

@ -1,5 +1,5 @@
import { absolutePathForFocalLength, pathForFocalLength } from '@/site/paths'; import { absolutePathForFocalLength, pathForFocalLength } from '@/site/paths';
import { Photo, PhotoDateRange } from '../photo'; import { PhotoSetAttributes } from '../photo';
import ShareModal from '@/components/ShareModal'; import ShareModal from '@/components/ShareModal';
import FocalLengthOGTile from './FocalLengthOGTile'; import FocalLengthOGTile from './FocalLengthOGTile';
import { shareTextFocalLength } from '.'; import { shareTextFocalLength } from '.';
@ -11,10 +11,7 @@ export default function FocalLengthShareModal({
dateRange, dateRange,
}: { }: {
focal: number focal: number
photos: Photo[] } & PhotoSetAttributes) {
count?: number
dateRange?: PhotoDateRange
}) {
return ( return (
<ShareModal <ShareModal
pathShare={absolutePathForFocalLength(focal)} pathShare={absolutePathForFocalLength(focal)}

View File

@ -10,7 +10,7 @@ import {
import SiteGrid from '@/components/SiteGrid'; import SiteGrid from '@/components/SiteGrid';
import Spinner from '@/components/Spinner'; import Spinner from '@/components/Spinner';
import { getPhotosCachedAction, getPhotosAction } from '@/photo/actions'; import { getPhotosCachedAction, getPhotosAction } from '@/photo/actions';
import { Photo, PhotoSetAttributes } from '.'; import { Photo, PhotoSetCategory } from '.';
import { clsx } from 'clsx/lite'; import { clsx } from 'clsx/lite';
import { useAppState } from '@/state/AppState'; import { useAppState } from '@/state/AppState';
import { GetPhotosOptions } from './db'; import { GetPhotosOptions } from './db';
@ -45,7 +45,7 @@ export default function InfinitePhotoScroll({
onLastPhotoVisible: () => void onLastPhotoVisible: () => void
revalidatePhoto?: RevalidatePhoto revalidatePhoto?: RevalidatePhoto
}) => ReactNode }) => ReactNode
} & PhotoSetAttributes) { } & PhotoSetCategory) {
const { swrTimestamp, isUserSignedIn } = useAppState(); const { swrTimestamp, isUserSignedIn } = useAppState();
const key = `${swrTimestamp}-${cacheKey}`; const key = `${swrTimestamp}-${cacheKey}`;

View File

@ -1,5 +1,5 @@
import AnimateItems from '@/components/AnimateItems'; import AnimateItems from '@/components/AnimateItems';
import { Photo, PhotoDateRange, PhotoSetAttributes } from '.'; import { Photo, PhotoDateRange, PhotoSetCategory } from '.';
import PhotoLarge from './PhotoLarge'; import PhotoLarge from './PhotoLarge';
import SiteGrid from '@/components/SiteGrid'; import SiteGrid from '@/components/SiteGrid';
import PhotoGrid from './PhotoGrid'; import PhotoGrid from './PhotoGrid';
@ -34,7 +34,7 @@ export default function PhotoDetailPage({
dateRange?: PhotoDateRange dateRange?: PhotoDateRange
shouldShare?: boolean shouldShare?: boolean
includeFavoriteInAdminMenu?: boolean includeFavoriteInAdminMenu?: boolean
} & PhotoSetAttributes) { } & PhotoSetCategory) {
let customHeader: JSX.Element | undefined; let customHeader: JSX.Element | undefined;
if (tag) { if (tag) {

View File

@ -1,6 +1,6 @@
'use client'; 'use client';
import { Photo, PhotoSetAttributes } from '.'; import { Photo, PhotoSetCategory } from '.';
import PhotoMedium from './PhotoMedium'; import PhotoMedium from './PhotoMedium';
import { clsx } from 'clsx/lite'; import { clsx } from 'clsx/lite';
import AnimateItems from '@/components/AnimateItems'; import AnimateItems from '@/components/AnimateItems';
@ -41,7 +41,7 @@ export default function PhotoGrid({
canSelect?: boolean canSelect?: boolean
onLastPhotoVisible?: () => void onLastPhotoVisible?: () => void
onAnimationComplete?: () => void onAnimationComplete?: () => void
} & PhotoSetAttributes) { } & PhotoSetCategory) {
const { const {
isUserSignedIn, isUserSignedIn,
selectedPhotoIds, selectedPhotoIds,

View File

@ -4,7 +4,7 @@ import { clsx } from 'clsx/lite';
import { import {
Photo, Photo,
PhotoDateRange, PhotoDateRange,
PhotoSetAttributes, PhotoSetCategory,
dateRangeForPhotos, dateRangeForPhotos,
titleForPhoto, titleForPhoto,
} from '.'; } from '.';
@ -41,7 +41,7 @@ export default function PhotoHeader({
indexNumber?: number indexNumber?: number
count?: number count?: number
dateRange?: PhotoDateRange dateRange?: PhotoDateRange
} & PhotoSetAttributes) { } & PhotoSetCategory) {
const { isGridHighDensity } = useAppState(); const { isGridHighDensity } = useAppState();
const { start, end } = dateRangeForPhotos(photos, dateRange); const { start, end } = dateRangeForPhotos(photos, dateRange);

View File

@ -1,7 +1,7 @@
'use client'; 'use client';
import { ReactNode } from 'react'; import { ReactNode } from 'react';
import { Photo, PhotoSetAttributes, titleForPhoto } from '@/photo'; import { Photo, PhotoSetCategory, titleForPhoto } from '@/photo';
import Link from 'next/link'; import Link from 'next/link';
import { AnimationConfig } from '../components/AnimateItems'; import { AnimationConfig } from '../components/AnimateItems';
import { useAppState } from '@/state/AppState'; import { useAppState } from '@/state/AppState';
@ -26,7 +26,7 @@ export default function PhotoLink({
nextPhotoAnimation?: AnimationConfig nextPhotoAnimation?: AnimationConfig
className?: string className?: string
children?: ReactNode children?: ReactNode
} & PhotoSetAttributes) { } & PhotoSetCategory) {
const { setNextPhotoAnimation } = useAppState(); const { setNextPhotoAnimation } = useAppState();
return ( return (

View File

@ -2,7 +2,7 @@
import { import {
Photo, Photo,
PhotoSetAttributes, PhotoSetCategory,
altTextForPhoto, altTextForPhoto,
doesPhotoNeedBlurCompatibility, doesPhotoNeedBlurCompatibility,
} from '.'; } from '.';
@ -32,7 +32,7 @@ export default function PhotoMedium({
prefetch?: boolean prefetch?: boolean
className?: string className?: string
onVisible?: () => void onVisible?: () => void
} & PhotoSetAttributes) { } & PhotoSetCategory) {
const ref = useRef<HTMLAnchorElement>(null); const ref = useRef<HTMLAnchorElement>(null);
useOnVisible(ref, onVisible); useOnVisible(ref, onVisible);

View File

@ -3,7 +3,7 @@
import { useEffect } from 'react'; import { useEffect } from 'react';
import { import {
Photo, Photo,
PhotoSetAttributes, PhotoSetCategory,
getNextPhoto, getNextPhoto,
getPreviousPhoto, getPreviousPhoto,
} from '@/photo'; } from '@/photo';
@ -32,7 +32,7 @@ export default function PhotoPrevNext({
photo?: Photo photo?: Photo
photos?: Photo[] photos?: Photo[]
className?: string className?: string
} & PhotoSetAttributes) { } & PhotoSetCategory) {
const router = useRouter(); const router = useRouter();
const { const {

View File

@ -1,11 +1,11 @@
import PhotoOGTile from '@/photo/PhotoOGTile'; import PhotoOGTile from '@/photo/PhotoOGTile';
import { absolutePathForPhoto, pathForPhoto } from '@/site/paths'; import { absolutePathForPhoto, pathForPhoto } from '@/site/paths';
import { Photo, PhotoSetAttributes } from '.'; import { Photo, PhotoSetCategory } from '.';
import ShareModal from '@/components/ShareModal'; import ShareModal from '@/components/ShareModal';
export default function PhotoShareModal(props: { export default function PhotoShareModal(props: {
photo: Photo photo: Photo
} & PhotoSetAttributes) { } & PhotoSetCategory) {
return ( return (
<ShareModal <ShareModal
pathShare={absolutePathForPhoto(props)} pathShare={absolutePathForPhoto(props)}

View File

@ -1,6 +1,6 @@
import { import {
Photo, Photo,
PhotoSetAttributes, PhotoSetCategory,
altTextForPhoto, altTextForPhoto,
doesPhotoNeedBlurCompatibility, doesPhotoNeedBlurCompatibility,
} from '.'; } from '.';
@ -28,7 +28,7 @@ export default function PhotoSmall({
className?: string className?: string
prefetch?: boolean prefetch?: boolean
onVisible?: () => void onVisible?: () => void
} & PhotoSetAttributes) { } & PhotoSetCategory) {
const ref = useRef<HTMLAnchorElement>(null); const ref = useRef<HTMLAnchorElement>(null);
useOnVisible(ref, onVisible); useOnVisible(ref, onVisible);

View File

@ -1,6 +1,6 @@
import { PRIORITY_ORDER_ENABLED } from '@/site/config'; import { PRIORITY_ORDER_ENABLED } from '@/site/config';
import { parameterize } from '@/utility/string'; import { parameterize } from '@/utility/string';
import { PhotoSetAttributes } from '..'; import { PhotoSetCategory } from '..';
export const GENERATE_STATIC_PARAMS_LIMIT = 1000; export const GENERATE_STATIC_PARAMS_LIMIT = 1000;
export const PHOTO_DEFAULT_LIMIT = 100; export const PHOTO_DEFAULT_LIMIT = 100;
@ -14,7 +14,7 @@ export type GetPhotosOptions = {
takenAfterInclusive?: Date takenAfterInclusive?: Date
updatedBefore?: Date updatedBefore?: Date
hidden?: 'exclude' | 'include' | 'only' hidden?: 'exclude' | 'include' | 'only'
} & PhotoSetAttributes; } & PhotoSetCategory;
export const areOptionsSensitive = (options: GetPhotosOptions) => export const areOptionsSensitive = (options: GetPhotosOptions) =>
options.hidden === 'include' || options.hidden === 'only'; options.hidden === 'include' || options.hidden === 'only';

View File

@ -102,7 +102,7 @@ export interface Photo extends PhotoDb {
takenAtNaiveFormatted: string takenAtNaiveFormatted: string
} }
export interface PhotoSetAttributes { export interface PhotoSetCategory {
tag?: string tag?: string
camera?: Camera camera?: Camera
simulation?: FilmSimulation simulation?: FilmSimulation
@ -110,6 +110,12 @@ export interface PhotoSetAttributes {
lens?: Lens // Unimplemented as a set lens?: Lens // Unimplemented as a set
} }
export interface PhotoSetAttributes {
photos: Photo[]
count?: number
dateRange?: PhotoDateRange
}
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>,

View File

@ -2,7 +2,7 @@ import {
absolutePathForFilmSimulation, absolutePathForFilmSimulation,
pathForFilmSimulation, pathForFilmSimulation,
} from '@/site/paths'; } from '@/site/paths';
import { Photo, PhotoDateRange } from '../photo'; import { PhotoSetAttributes } from '../photo';
import ShareModal from '@/components/ShareModal'; import ShareModal from '@/components/ShareModal';
import FilmSimulationOGTile from './FilmSimulationOGTile'; import FilmSimulationOGTile from './FilmSimulationOGTile';
import { FilmSimulation, shareTextForFilmSimulation } from '.'; import { FilmSimulation, shareTextForFilmSimulation } from '.';
@ -14,10 +14,7 @@ export default function FilmSimulationShareModal({
dateRange, dateRange,
}: { }: {
simulation: FilmSimulation simulation: FilmSimulation
photos: Photo[] } & PhotoSetAttributes) {
count?: number
dateRange?: PhotoDateRange
}) {
return ( return (
<ShareModal <ShareModal
pathShare={absolutePathForFilmSimulation(simulation)} pathShare={absolutePathForFilmSimulation(simulation)}

View File

@ -1,4 +1,4 @@
import { Photo, PhotoSetAttributes } from '@/photo'; import { Photo, PhotoSetCategory } from '@/photo';
import { BASE_URL, GRID_HOMEPAGE_ENABLED } from './config'; import { BASE_URL, GRID_HOMEPAGE_ENABLED } from './config';
import { Camera } from '@/camera'; import { Camera } from '@/camera';
import { FilmSimulation } from '@/simulation'; import { FilmSimulation } from '@/simulation';
@ -75,7 +75,7 @@ export const PATHS_TO_CACHE = [
...PATHS_ADMIN, ...PATHS_ADMIN,
]; ];
type PhotoPathParams = { photo: PhotoOrPhotoId } & PhotoSetAttributes; type PhotoPathParams = { photo: PhotoOrPhotoId } & PhotoSetCategory;
// Absolute paths // Absolute paths
export const ABSOLUTE_PATH_FOR_HOME_IMAGE = `${BASE_URL}/home-image`; export const ABSOLUTE_PATH_FOR_HOME_IMAGE = `${BASE_URL}/home-image`;
@ -274,7 +274,7 @@ export const isPathProtected = (pathname?: string) =>
export const getPathComponents = (pathname = ''): { export const getPathComponents = (pathname = ''): {
photoId?: string photoId?: string
} & PhotoSetAttributes => { } & PhotoSetCategory => {
const photoIdFromPhoto = pathname.match( const photoIdFromPhoto = pathname.match(
new RegExp(`^${PREFIX_PHOTO}/([^/]+)`))?.[1]; new RegExp(`^${PREFIX_PHOTO}/([^/]+)`))?.[1];
const photoIdFromTag = pathname.match( const photoIdFromTag = pathname.match(

View File

@ -2,7 +2,7 @@ import { Dispatch, SetStateAction, createContext, useContext } from 'react';
import { AnimationConfig } from '@/components/AnimateItems'; import { AnimationConfig } from '@/components/AnimateItems';
export interface AppStateContext { export interface AppStateContext {
// CORE // GLOBAL
previousPathname?: string previousPathname?: string
hasLoaded?: boolean hasLoaded?: boolean
setHasLoaded?: Dispatch<SetStateAction<boolean>> setHasLoaded?: Dispatch<SetStateAction<boolean>>
@ -13,9 +13,10 @@ export interface AppStateContext {
clearNextPhotoAnimation?: () => void clearNextPhotoAnimation?: () => void
shouldRespondToKeyboardCommands?: boolean shouldRespondToKeyboardCommands?: boolean
setShouldRespondToKeyboardCommands?: Dispatch<SetStateAction<boolean>> setShouldRespondToKeyboardCommands?: Dispatch<SetStateAction<boolean>>
// MODAL
isCommandKOpen?: boolean isCommandKOpen?: boolean
setIsCommandKOpen?: Dispatch<SetStateAction<boolean>> setIsCommandKOpen?: Dispatch<SetStateAction<boolean>>
// ADMIN // ADMIN
userEmail?: string userEmail?: string
setUserEmail?: Dispatch<SetStateAction<string | undefined>> setUserEmail?: Dispatch<SetStateAction<string | undefined>>
isUserSignedIn?: boolean isUserSignedIn?: boolean

View File

@ -1,5 +1,5 @@
import { absolutePathForTag, pathForTag } from '@/site/paths'; import { absolutePathForTag, pathForTag } from '@/site/paths';
import { Photo, PhotoDateRange } from '../photo'; import { PhotoSetAttributes } from '../photo';
import ShareModal from '@/components/ShareModal'; import ShareModal from '@/components/ShareModal';
import TagOGTile from './TagOGTile'; import TagOGTile from './TagOGTile';
import { shareTextForTag } from '.'; import { shareTextForTag } from '.';
@ -11,10 +11,7 @@ export default function TagShareModal({
dateRange, dateRange,
}: { }: {
tag: string tag: string
photos: Photo[] } & PhotoSetAttributes) {
count?: number
dateRange?: PhotoDateRange
}) {
return ( return (
<ShareModal <ShareModal
pathShare={absolutePathForTag(tag)} pathShare={absolutePathForTag(tag)}