fix: use iTunes lookup endpoint for explicit artist tracks

iTunes search endpoint always returns cleaned versions.
Added itunesLookupArtistSongs() using /lookup?explicit=Yes which returns
the actual explicit tracks. Used in artist profile (global search) and
artist detail page (library). Album track lookup also gets explicit=Yes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
HoneyandClaude Sonnet 4.6 committed 2026-04-26 17:58:32 +02:00
1 parent fc951d103b
commit 3c5048f017
2 files changed
+16 -5

No files matched your search

+8 -4
View File
@@ -1,7 +1,7 @@
import { S } from './state.js';
import { esc, formatDur, toast } from './utils.js';
import { api, coverUrl } from './api.js';
import { itunesSearch, itunesLookupAlbum, itunesTopCharts, itunesTopSongs } from './api.js';
import { itunesSearch, itunesLookupAlbum, itunesLookupArtistSongs, itunesTopCharts, itunesTopSongs } from './api.js';
// Circular imports — safe (only used inside function bodies)
import { playQueue, dlSongLocal, toggleStar, playPreview } from './player.js';
import { showCtxMenu, openEditPlModal, openPlModal, openDlModal, closeSidebar, switchNavMode, closeNowPlaying, closeNpMenu } from './ui.js';
@@ -230,14 +230,18 @@ export async function loadArtistDetail(artist) {
g.innerHTML = '<div class="spinner"></div>';
document.getElementById('artist-itunes-extra')?.remove();
const [imgRes, albumRes, infoRes, topRes, itunesTracksRes, itunesAlbumsRes] = await Promise.allSettled([
const [imgRes, albumRes, infoRes, topRes, itunesArtistRes, itunesAlbumsRes] = await Promise.allSettled([
getArtistImage(artist.id),
api('getArtist', `&id=${artist.id}`),
api('getArtistInfo2', `&id=${artist.id}&count=8`),
api('getTopSongs', `&artist=${encodeURIComponent(artist.name)}&count=10`),
itunesSearch(artist.name, 'musicTrack', 10),
itunesSearch(artist.name, 'musicArtist', 1),
itunesSearch(artist.name, 'album', 20),
]);
const itunesArtistId = itunesArtistRes.status==='fulfilled' ? (itunesArtistRes.value[0]?.artistId ?? null) : null;
const itunesTracksRes = itunesArtistId
? await Promise.allSettled([itunesLookupArtistSongs(itunesArtistId, 10)])[0]
: { status: 'rejected' };
const img = imgRes.status==='fulfilled' ? imgRes.value : null;
if(img) {
@@ -625,7 +629,7 @@ export async function loadItunesArtistResults(artistId, artistName) {
try {
const [albums, topTracks] = await Promise.all([
itunesSearch(artistName, 'album', 20),
itunesSearch(artistName, 'musicTrack', 10),
itunesLookupArtistSongs(artistId, 15),
]);
const artistAlbums = albums.filter(a => a.artistId===artistId || a.artistName===artistName);
const artistTracks = topTracks.filter(t => t.wrapperType==='track' && (t.artistId===artistId || t.artistName===artistName));