From 31e5940ab65ed79f80446da42891d124930ec14b Mon Sep 17 00:00:00 2001 From: Honey Date: Sun, 26 Apr 2026 17:43:31 +0200 Subject: [PATCH] fix: remove library results from global search, filter explicit content - Global search now shows only iTunes results (no Navidrome library section) - All iTunes results (tracks, albums, artist pages, album detail, recommendations) filtered to exclude explicit content (trackExplicitness/collectionExplicitness === 'explicit') Co-Authored-By: Claude Sonnet 4.6 --- src/views.js | 66 ++++++++++++++++------------------------------------ 1 file changed, 20 insertions(+), 46 deletions(-) diff --git a/src/views.js b/src/views.js index f0785a2..eb5034d 100644 --- a/src/views.js +++ b/src/views.js @@ -305,7 +305,7 @@ export async function loadArtistDetail(artist) { // ── iTunes: global top tracks ── const itunesTracks = itunesTracksRes.status==='fulfilled' - ? (itunesTracksRes.value||[]).filter(t => t.wrapperType==='track' && t.artistName?.toLowerCase()===artist.name.toLowerCase()) + ? (itunesTracksRes.value||[]).filter(t => t.wrapperType==='track' && !isExplicit(t) && t.artistName?.toLowerCase()===artist.name.toLowerCase()) : []; if(itunesTracks.length) { const tsEl = document.getElementById('artist-topsongs-section'); @@ -325,7 +325,8 @@ export async function loadArtistDetail(artist) { const serverAlbumNames = new Set((albumRes.status==='fulfilled' ? (albumRes.value.artist?.album||[]) : []).map(a => a.name.toLowerCase())); const extraAlbums = itunesAlbums.filter(a => (a.artistId === undefined || a.artistName?.toLowerCase() === artist.name.toLowerCase()) && - !serverAlbumNames.has(a.collectionName?.toLowerCase()) + !serverAlbumNames.has(a.collectionName?.toLowerCase()) && + !isExplicit(a) ); if(extraAlbums.length) { const g = document.getElementById('artist-albums-grid'); @@ -533,48 +534,16 @@ export function onGlobalSearch(val) { export async function doGlobalSearch(q) { const el = document.getElementById('global-search-results'); try { - const [serverRes, tracks, albums, artists] = await Promise.all([ - api('search3', `&query=${encodeURIComponent(q)}&songCount=15&albumCount=5&artistCount=3`).catch(() => null), - itunesSearch(q,'musicTrack',20), + const [tracks, albums, artists] = await Promise.all([ + itunesSearch(q,'musicTrack',25), itunesSearch(q,'album',10), itunesSearch(q,'musicArtist',6) ]); el.innerHTML = ''; - // ── Library results (Navidrome) ── - const srvRes = serverRes?.searchResult3 || {}; - const srvSongs = srvRes.song || [], srvArtists = srvRes.artist || [], srvAlbums = srvRes.album || []; - if(srvSongs.length || srvArtists.length || srvAlbums.length) { - const s = mkSection('📚 In meiner Bibliothek'); - if(srvArtists.length) { - const row = document.createElement('div'); row.className = 'scroll-row'; - srvArtists.forEach(a => { - const c = makeCard(a.name, a.albumCount+' Alben', null, '🎤'); - c.onclick = () => navigate('artist-detail', a); - row.appendChild(c); - getArtistImage(a.id).then(img => { - if(!img) return; - const artEl = c.querySelector('.card-art'); if(!artEl) return; - artEl.innerHTML = `
`; - }); - }); - s.appendChild(row); - } - if(srvAlbums.length) { - const row = document.createElement('div'); row.className = 'scroll-row'; - srvAlbums.forEach(a => row.appendChild(makeAlbumCard(a))); - s.appendChild(row); - } - if(srvSongs.length) { - const list = document.createElement('div'); list.className = 'song-list'; - srvSongs.forEach((so, i) => list.appendChild(makeSongItem(so, i, srvSongs))); - s.appendChild(list); - } - el.appendChild(s); - } + const trackResults = tracks.filter(t => t.wrapperType === 'track' && !isExplicit(t)); + const albumResults = albums.filter(a => !isExplicit(a)); - // ── iTunes results ── - const trackResults = tracks.filter(t => t.wrapperType === 'track'); if(artists.length) { const s = mkSection('Künstler'); const row = document.createElement('div'); row.className = 'scroll-row'; @@ -598,10 +567,10 @@ export async function doGlobalSearch(q) { }); s.appendChild(row); el.appendChild(s); } - if(albums.length) { + if(albumResults.length) { const s = mkSection('Alben'); const row = document.createElement('div'); row.className = 'scroll-row'; - albums.forEach(a => { + albumResults.forEach(a => { const art = a.artworkUrl100?.replace('100x100','300x300'); const c = makeCard(a.collectionName, a.artistName, art, '💿'); c.querySelector('.play-btn').onclick = (e) => { e.stopPropagation(); loadItunesAlbum(a); }; @@ -623,7 +592,7 @@ export async function doGlobalSearch(q) { trackResults.forEach((t,i) => list.appendChild(makeGlobalTrackItem(t, i, trackResults))); s.appendChild(list); el.appendChild(s); } - if(!srvSongs.length && !srvArtists.length && !srvAlbums.length && !artists.length && !albums.length && !trackResults.length) { + if(!artists.length && !albumResults.length && !trackResults.length) { el.innerHTML = '
🔍

Keine Ergebnisse gefunden

'; } } catch(e) { el.innerHTML = `

Suche fehlgeschlagen: ${e.message}

`; } @@ -631,7 +600,8 @@ export async function doGlobalSearch(q) { export async function loadItunesAlbum(album) { try { - const tracks = await itunesLookupAlbum(album.collectionId); + const rawTracks = await itunesLookupAlbum(album.collectionId); + const tracks = rawTracks.filter(t => !isExplicit(t)); if(!tracks.length) { toast('Keine Tracks gefunden'); return; } const el = document.getElementById('global-search-results'); const s = document.createElement('div'); s.className = 'search-section'; @@ -659,8 +629,8 @@ export async function loadItunesArtistResults(artistId, artistName) { itunesSearch(artistName, 'album', 20), itunesSearch(artistName, 'musicTrack', 10), ]); - 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)); + const artistAlbums = albums.filter(a => (a.artistId===artistId || a.artistName===artistName) && !isExplicit(a)); + const artistTracks = topTracks.filter(t => t.wrapperType==='track' && !isExplicit(t) && (t.artistId===artistId || t.artistName===artistName)); const coverImg = artistAlbums[0]?.artworkUrl100?.replace('100x100','600x600') || ''; el.innerHTML = ''; @@ -827,12 +797,16 @@ async function loadItunesFallbackRecommendations(el, artist, title, html) { const sec = document.createElement('div'); sec.innerHTML = `
Mehr von ${esc(artist)}
`; const list = document.createElement('div'); list.className = 'song-list'; - results.filter(t => t.artistName===artist).slice(0,15).forEach(t => list.appendChild(makeGlobalTrackItem(t, 0, [t]))); - if(!list.children.length) results.slice(0,15).forEach(t => list.appendChild(makeGlobalTrackItem(t, 0, [t]))); + results.filter(t => t.artistName===artist && !isExplicit(t)).slice(0,15).forEach(t => list.appendChild(makeGlobalTrackItem(t, 0, [t]))); + if(!list.children.length) results.filter(t => !isExplicit(t)).slice(0,15).forEach(t => list.appendChild(makeGlobalTrackItem(t, 0, [t]))); sec.appendChild(list); el.appendChild(sec); } // ─── HELPERS ─── +function isExplicit(item) { + return item.trackExplicitness === 'explicit' || item.collectionExplicitness === 'explicit'; +} + export function expandArtistBio() { const el = document.getElementById('artist-bio-text'); if(el && window._artistBioFull) el.textContent = window._artistBioFull;