import type { Asset } from './shared'; import { Link } from 'react-router'; import { Camera, Image as ImageIcon, MapPin } from 'lucide-react'; import { PERSON_PARAM, formatBytes, formatLongDate, formatTime, personThumbUrl, photosSectionPath } from './shared'; // The lightbox's info drawer, in the order Immich's own panel uses: description, date, file, camera, location, // people. Sections with nothing in them are omitted rather than shown empty — a library full of screenshots // has no camera data and shouldn't render a row of dashes for every one. type AssetInfoPanelProps = { asset: Asset | undefined; token: string | null }; export const AssetInfoPanel = ({ asset, token }: AssetInfoPanelProps) => { if (!asset) return
Loading…
; const exif = asset.exifInfo; const megapixels = asset.width && asset.height ? (asset.width * asset.height) / 1_000_000 : 0; const place = [exif?.city, exif?.state, exif?.country].filter(Boolean).join(', '); const aperture = exif?.fNumber ? `ƒ/${exif.fNumber}` : null; const shot = [ aperture, exif?.exposureTime ? `${exif.exposureTime}s` : null, exif?.focalLength ? `${Math.round(exif.focalLength)}mm` : null, exif?.iso ? `ISO ${exif.iso}` : null, ].filter(Boolean); return (
{exif?.description &&

{exif.description}

}

{formatLongDate(asset.localDateTime)}

{formatTime(asset.localDateTime)}

} title={asset.originalFileName}> = 0.1 ? `${megapixels.toFixed(1)} MP` : null} />

{asset.originalPath}

{(exif?.make || exif?.model || shot.length > 0) && (
} title={[exif?.make, exif?.model].filter(Boolean).join(' ')}> {exif?.lensModel &&

{exif.lensModel}

} {shot.length > 0 &&

{shot.join(' · ')}

}
)} {(place || (exif?.latitude != null && exif?.longitude != null)) && (
} title={place || 'Location'}> {exif?.latitude != null && exif?.longitude != null && (

{exif.latitude.toFixed(5)}, {exif.longitude.toFixed(5)}

)}
)} {asset.people && asset.people.length > 0 && (

People

{asset.people.map((person) => ( {person.name || 'Unnamed'} ))}
)}
); }; type SectionProps = { icon: React.ReactNode; title: string; children?: React.ReactNode }; const Section = ({ icon, title, children }: SectionProps) => (
{icon}

{title}

{children}
); const Row = ({ label, value }: { label: string; value: string | null }) => (

{value ? `${label} · ${value}` : label}

);