fix: always generate CAA cover art URL, handle missing covers with onError
Per CAA API docs, front-250 URLs are predictable from mbId. Remove the cover-art-archive.front check (unreliable in search results) and always construct the URL. A CoverThumb component handles 404s gracefully. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -49,10 +49,11 @@ function normalizeRelease(release) {
|
|||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
let coverArtUrl = null;
|
// Always generate the CAA URL when an id is present; the browser/onError
|
||||||
if (release['cover-art-archive'] && release['cover-art-archive'].front) {
|
// handles 404s for releases that have no front cover.
|
||||||
coverArtUrl = `https://coverartarchive.org/release/${release.id}/front-250`;
|
const coverArtUrl = release.id
|
||||||
}
|
? `https://coverartarchive.org/release/${release.id}/front-250`
|
||||||
|
: null;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
mbId: String(release.id || ''),
|
mbId: String(release.id || ''),
|
||||||
@@ -92,7 +93,7 @@ class MusicBrainzService {
|
|||||||
url.searchParams.set('query', q);
|
url.searchParams.set('query', q);
|
||||||
url.searchParams.set('fmt', 'json');
|
url.searchParams.set('fmt', 'json');
|
||||||
url.searchParams.set('limit', '10');
|
url.searchParams.set('limit', '10');
|
||||||
url.searchParams.set('inc', 'artist-credits+labels+recordings+cover-art-archive');
|
url.searchParams.set('inc', 'artist-credits+labels+recordings');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const data = await mbFetch(url.toString());
|
const data = await mbFetch(url.toString());
|
||||||
|
|||||||
@@ -7,6 +7,21 @@ import { InputText } from 'primereact/inputtext';
|
|||||||
import { InputNumber } from 'primereact/inputnumber';
|
import { InputNumber } from 'primereact/inputnumber';
|
||||||
import { Checkbox } from 'primereact/checkbox';
|
import { Checkbox } from 'primereact/checkbox';
|
||||||
|
|
||||||
|
function CoverThumb({ url, alt }) {
|
||||||
|
const [failed, setFailed] = useState(false);
|
||||||
|
if (!url || failed) {
|
||||||
|
return <div className="poster-thumb-lg poster-fallback">-</div>;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<img
|
||||||
|
src={url}
|
||||||
|
alt={alt}
|
||||||
|
className="poster-thumb-lg"
|
||||||
|
onError={() => setFailed(true)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function formatDurationMs(ms) {
|
function formatDurationMs(ms) {
|
||||||
const totalSec = Math.round((ms || 0) / 1000);
|
const totalSec = Math.round((ms || 0) / 1000);
|
||||||
const min = Math.floor(totalSec / 60);
|
const min = Math.floor(totalSec / 60);
|
||||||
@@ -135,11 +150,7 @@ export default function CdMetadataDialog({
|
|||||||
|
|
||||||
const mbTitleBody = (row) => (
|
const mbTitleBody = (row) => (
|
||||||
<div className="mb-result-row">
|
<div className="mb-result-row">
|
||||||
{row.coverArtUrl ? (
|
<CoverThumb url={row.coverArtUrl} alt={row.title} />
|
||||||
<img src={row.coverArtUrl} alt={row.title} className="poster-thumb-lg" />
|
|
||||||
) : (
|
|
||||||
<div className="poster-thumb-lg poster-fallback">-</div>
|
|
||||||
)}
|
|
||||||
<div>
|
<div>
|
||||||
<div><strong>{row.title}</strong></div>
|
<div><strong>{row.title}</strong></div>
|
||||||
<small>{row.artist}{row.year ? ` | ${row.year}` : ''}</small>
|
<small>{row.artist}{row.year ? ` | ${row.year}` : ''}</small>
|
||||||
|
|||||||
Reference in New Issue
Block a user