'use client'; import { Photo, altTextForPhoto, doesPhotoNeedBlurCompatibility, shouldShowCameraDataForPhoto, shouldShowExifDataForPhoto, titleForPhoto, } from '.'; import SiteGrid from '@/components/SiteGrid'; import ImageLarge from '@/components/image/ImageLarge'; import { clsx } from 'clsx/lite'; import Link from 'next/link'; import { pathForFocalLength, pathForPhoto, } from '@/app/paths'; import PhotoTags from '@/tag/PhotoTags'; import ShareButton from '@/share/ShareButton'; import DownloadButton from '@/components/DownloadButton'; import PhotoCamera from '../camera/PhotoCamera'; import { cameraFromPhoto } from '@/camera'; import PhotoFilmSimulation from '@/simulation/PhotoFilmSimulation'; import { sortTags } from '@/tag'; import DivDebugBaselineGrid from '@/components/DivDebugBaselineGrid'; import PhotoLink from './PhotoLink'; import { SHOULD_PREFETCH_ALL_LINKS, ALLOW_PUBLIC_DOWNLOADS, SHOW_TAKEN_AT_TIME, } from '@/app/config'; import AdminPhotoMenuClient from '@/admin/AdminPhotoMenuClient'; import { RevalidatePhoto } from './InfinitePhotoScroll'; import { useRef } from 'react'; import useVisible from '@/utility/useVisible'; import PhotoDate from './PhotoDate'; import { useAppState } from '@/state/AppState'; import { LuExpand } from 'react-icons/lu'; import LoaderButton from '@/components/primitives/LoaderButton'; import Tooltip from '@/components/Tooltip'; import ZoomControls, { ZoomControlsRef } from '@/components/image/ZoomControls'; export default function PhotoLarge({ photo, className, primaryTag, priority, prefetch = SHOULD_PREFETCH_ALL_LINKS, prefetchRelatedLinks = SHOULD_PREFETCH_ALL_LINKS, revalidatePhoto, showTitle = true, showTitleAsH1, showCamera = true, showSimulation = true, showZoomControls: showZoomControlsProp = true, shouldZoomOnFKeydown = true, shouldShare = true, shouldShareTag, shouldShareCamera, shouldShareSimulation, shouldShareFocalLength, includeFavoriteInAdminMenu, onVisible, }: { photo: Photo className?: string primaryTag?: string priority?: boolean prefetch?: boolean prefetchRelatedLinks?: boolean revalidatePhoto?: RevalidatePhoto showTitle?: boolean showTitleAsH1?: boolean showCamera?: boolean showSimulation?: boolean showZoomControls?: boolean shouldZoomOnFKeydown?: boolean shouldShare?: boolean shouldShareTag?: boolean shouldShareCamera?: boolean shouldShareSimulation?: boolean shouldShareFocalLength?: boolean includeFavoriteInAdminMenu?: boolean onVisible?: () => void }) { const ref = useRef(null); const zoomControlsRef = useRef(null); const { areZoomControlsShown, arePhotosMatted, isUserSignedIn, } = useAppState(); const showZoomControls = showZoomControlsProp && areZoomControlsShown; const tags = sortTags(photo.tags, primaryTag); const camera = cameraFromPhoto(photo); const showCameraContent = showCamera && shouldShowCameraDataForPhoto(photo); const showTagsContent = tags.length > 0; const showExifContent = shouldShowExifDataForPhoto(photo); useVisible({ ref, onVisible }); const hasTitle = showTitle && Boolean(photo.title); const hasTitleContent = hasTitle || Boolean(photo.caption); const hasMetaContent = showCameraContent || showTagsContent || showExifContent; const hasNonDateContent = hasTitleContent || hasMetaContent; const renderPhotoLink = () => ; const matteContentWidthForAspectRatio = () => { // Restrict width for landscape photos // (portrait photos are always height restricted) if (photo.aspectRatio > 3 / 2 + 0.1) { return 'w-[90%]'; } else if (photo.aspectRatio >= 1) { return 'w-[80%]'; } }; const largePhotoContent =
; const largePhotoContainerClassName = clsx(arePhotosMatted && 'flex items-center justify-center aspect-3/2 bg-gray-100', ); return ( {largePhotoContent} : {largePhotoContent} } contentSide={ {/* Meta */}
{hasTitle && (showTitleAsH1 ?

{renderPhotoLink()}

: renderPhotoLink())}
{photo.caption &&
{photo.caption}
} {(showCameraContent || showTagsContent) &&
{showCameraContent && } {showTagsContent && }
}
{/* EXIF Data */}
{showExifContent && <>
  • {photo.focalLength && {photo.focalLengthFormatted} } {( photo.focalLengthIn35MmFormatFormatted && // eslint-disable-next-line max-len photo.focalLengthIn35MmFormatFormatted !== photo.focalLengthFormatted ) && <> {' '} {photo.focalLengthIn35MmFormatFormatted} }
  • {photo.fNumberFormatted}
  • {photo.exposureTimeFormatted}
  • {photo.isoFormatted}
  • {photo.exposureCompensationFormatted ?? '0ev'}
{showSimulation && photo.filmSimulation && } }
{showZoomControls && } onClick={() => zoomControlsRef.current?.open()} styleAs="link" className="text-medium translate-y-[0.25px]" hideFocusOutline />} {shouldShare && } {ALLOW_PUBLIC_DOWNLOADS && }
} /> ); };