import { useEffect, useState } from "react"; import { fetchPhoto } from "../api/client"; /* * Foto-id → een blob-URL die geldig is zolang dit component leeft. * * De bytes komen van de mediaserver, die eerst controleert of ik de afzender of de ontvanger van de * brief ben; daarvoor moet het sessietoken mee, en dat kan een niet. Dus: fetch, blob, en * bij het opruimen de URL weer intrekken — anders houdt de browser de foto in het geheugen. * * Geeft { url, failed }: url is null zolang hij laadt (of als het misging). */ export default function usePhoto(id) { const [state, setState] = useState({ url: null, failed: false }); useEffect(() => { setState({ url: null, failed: false }); if (!id) return; const ctrl = new AbortController(); let url = null; fetchPhoto(id, { signal: ctrl.signal }) .then((blob) => { if (ctrl.signal.aborted) return; url = URL.createObjectURL(blob); setState({ url, failed: false }); }) .catch((e) => { if (e.name !== "AbortError") setState({ url: null, failed: true }); }); return () => { ctrl.abort(); if (url) URL.revokeObjectURL(url); }; }, [id]); return state; }