diff --git a/index.html b/index.html index 0720add..4a8edb2 100644 --- a/index.html +++ b/index.html @@ -2605,6 +2605,7 @@

+
+
+ +
+ `; + + document.body.appendChild(modal); + + const close = (e) => { + if (e) { + e.preventDefault(); + e.stopPropagation(); + } + modal.remove(); + }; + + modal.querySelector('.modal-overlay').onclick = close; + modal.querySelector('.btn-close').onclick = close; + + // Ensure links are clickable by attaching the listener to the modal body + const modalBody = modal.querySelector('.modal-body'); + modalBody.addEventListener( + 'click', + (e) => { + const link = e.target.closest('.bio-link'); + if (link) { + e.preventDefault(); + e.stopPropagation(); + const { type, id } = link.dataset; + if (type && id) { + modal.remove(); + navigate(`/${type}/t/${id}`); + } + } + }, + true + ); // Use capture phase to ensure it's hit + }; + + const renderBioPreview = (bio) => { + const text = typeof bio === 'string' ? bio : bio.text; + if (text) { + // Use stripped text for preview to avoid broken tags/links + const cleanText = stripBioTags(text); + const isLong = cleanText.length > 200; + const previewText = isLong ? cleanText.substring(0, 200).trim() + '...' : cleanText; + + bioEl.innerHTML = previewText.replace(/\n/g, '
'); + bioEl.style.display = 'block'; + bioEl.style.webkitLineClamp = 'unset'; + bioEl.style.cursor = 'default'; + bioEl.onclick = null; + + if (isLong) { + bioEl.appendChild(document.createElement('br')); + const readMore = document.createElement('span'); + readMore.className = 'bio-read-more'; + readMore.textContent = 'Read More'; + readMore.onclick = (e) => { + e.preventDefault(); + e.stopPropagation(); + showBioModal(bio); + }; + bioEl.appendChild(readMore); + } + } else { + bioEl.style.display = 'none'; + } + }; + + if (artist.biography) { + renderBioPreview(artist.biography); + } else { + // Try to fetch biography asynchronously + this.api + .getArtistBiography(artistId, provider) + .then((bio) => { + if (bio) renderBioPreview(bio); + }) + .catch(() => { + /* ignore */ + }); + } + } + // Handle Artist Mix Button const mixBtn = document.getElementById('artist-mix-btn'); if (mixBtn) { diff --git a/styles.css b/styles.css index 5ea8c3a..0bbd4ff 100644 --- a/styles.css +++ b/styles.css @@ -2360,6 +2360,59 @@ input[type='search']::-webkit-search-cancel-button { color: var(--highlight); } +/* Artist Biography Styles */ +.artist-bio { + color: var(--muted-foreground); + margin-top: 1rem; + font-size: 0.95rem; + line-height: 1.5; + max-width: 600px; + display: block; + overflow: hidden; + transition: color var(--transition); +} + +.artist-bio:hover { + color: var(--foreground); +} + +.bio-link { + color: var(--highlight) !important; + text-decoration: underline !important; + cursor: pointer !important; + font-weight: 500 !important; + pointer-events: auto !important; +} + +.bio-link:hover { + color: var(--primary) !important; + text-decoration: none !important; +} + +.bio-read-more { + display: block; + color: var(--highlight); + text-decoration: underline; + cursor: pointer; + font-weight: bold; + font-size: 0.95rem; + margin-top: 0.5rem; +} + +.bio-read-more:hover { + color: var(--primary); +} + +.bio-source { + display: block; + margin-top: 1.5rem; + font-size: 0.9rem; + opacity: 0.6; + font-style: italic; + border-top: 1px solid var(--border); + padding-top: 1rem; +} + .detail-header-actions { display: flex; gap: 0.5rem; @@ -4999,6 +5052,10 @@ img[src=''] { max-width: 600px; } +.modal-content.extra-wide { + max-width: 1000px; +} + .modal-content.medium { max-width: 500px; }