import { S } from './state.js'; import { esc, formatDur } from './utils.js'; import { coverUrl } from './api.js'; // Circular imports — safe (only used inside event handlers after module init) import { playQueue, dlSongLocal, toggleStar, playPreview } from './player.js'; import { showCtxMenu, openDlModal } from './ui.js'; import { navigate, quickPlayAlbum } from './views.js'; // ─── GENERIC CARD ─── export function makeCard(title, sub, imgUrl, fallback='💿') { const c = document.createElement('div'); c.className = 'card'; c.innerHTML = `
${imgUrl ? `` : `
${fallback}
`}
${esc(title)}
${esc(sub||'')}
`; return c; } export function makeAlbumCard(a) { const cv = coverUrl(a.coverArt, 200); const c = makeCard(a.name, a.artist||'', cv, '💿'); c.querySelector('.play-btn').onclick = (e) => { e.stopPropagation(); quickPlayAlbum(a); }; c.onclick = () => navigate('album-detail', a); return c; } // ─── SONG LIST ITEM (library) ─── export function makeSongItem(s, idx, list, { noArtistLink = false, noAlbumLink = false } = {}) { const el = document.createElement('div'); if(s.starred && !s._starred) s._starred = true; el.className = 'song-item' + (S.queue[S.qIdx]?.id === s.id ? ' playing' : ''); const cv = coverUrl(s.coverArt, 60); const artistParts = (s.artist || '').split(/\s*(?:\/|•|,)\s*/).filter(Boolean); const artistHtml = artistParts.length ? artistParts.map((name, i) => { const aid = i === 0 ? (s.artistId || '') : ''; return noArtistLink ? `${esc(name)}` : `${esc(name)}`; }).join(' • ') : ''; const albumHtml = !noAlbumLink && (s.albumId||s.album) ? ` · ${esc(s.album||'')}` : ''; el.innerHTML = `
${idx+1}
${cv ? `` : '
♪
'}
${esc(s.title)}
${artistHtml}${albumHtml}
${formatDur(s.duration)}
`; const btns = el.querySelectorAll('.icon-btn'); btns[0].onclick = (e) => { e.stopPropagation(); toggleStar(s, btns[0]); }; btns[1].onclick = (e) => { e.stopPropagation(); dlSongLocal(s); }; el.onclick = () => playQueue(list, idx); el.addEventListener('contextmenu', e => { e.preventDefault(); showCtxMenu(e, s, list, idx); }); return el; } // ─── GLOBAL TRACK ITEM (iTunes / Spotify results) ─── export function makeGlobalTrackItem(t, idx, list) { const el = document.createElement('div'); el.className = 'gtrack-item'; const art = t.artworkUrl60 || t.artworkUrl100 || ''; el.innerHTML = `
${art ? `` : '
🎵
'}
${esc(t.trackName||t.collectionName||'—')}${t.trackExplicitness==='explicit'?'E':''}
${esc(t.artistName||'—')} · ${esc(t.collectionName||'')} ${t.releaseDate?'· '+new Date(t.releaseDate).getFullYear():''}
${t.previewUrl ? `` : ''}
`; el.onclick = () => { if(t.previewUrl) playPreview(t); }; return el; } // ─── SEARCH SECTION HEADER ─── export function mkSection(title) { const d = document.createElement('div'); d.className = 'search-section'; d.innerHTML = `
${title}
`; return d; }