import { useState, useEffect } from 'react'; import { Attachment } from 'fhir/r4'; import { getFhirPhotoUrl, isScannedPhoto } from '../utils/fhirPhoto'; import { usePhotoUploadService } from '../services/PhotoUploadService'; // Links are stamped with their photo, so a changed photo never shows the old link or its late answer. Inline bytes show // only when the server marked them clean; otherwise a reader who may open the file sees it through a checked link. export const usePhotoUrl = (photo?: Attachment | null, type?: string): { url: string; loading: boolean } => { const { getPresignedDownloadUrl } = usePhotoUploadService(); const defaultUrl = getFhirPhotoUrl(null, type); const remoteKey = !isScannedPhoto(photo) && photo?.url && !/^[a-z][a-z0-9+.-]*:/i.test(photo.url) ? photo.url : undefined; const [resolved, setResolved] = useState<{ key: string; url: string } | undefined>(); useEffect(() => { if (!remoteKey) return; let current = true; getPresignedDownloadUrl(remoteKey) .then((url) => { if (current) setResolved({ key: remoteKey, url }); }) .catch(() => { if (current) setResolved({ key: remoteKey, url: defaultUrl }); }); return () => { current = false; }; }, [remoteKey, type]); if (isScannedPhoto(photo)) return { url: getFhirPhotoUrl(photo, type), loading: false }; if (!remoteKey) return { url: defaultUrl, loading: false }; if (resolved?.key === remoteKey) return { url: resolved.url, loading: false }; return { url: defaultUrl, loading: true }; };