diff --git a/index.html b/index.html
index ce0ac89..633d243 100644
--- a/index.html
+++ b/index.html
@@ -3297,13 +3297,15 @@
-
- In Your Library
-
+
+
-
+
Albums
diff --git a/js/db.js b/js/db.js
index 122155b..1924e49 100644
--- a/js/db.js
+++ b/js/db.js
@@ -585,6 +585,7 @@ export class MusicDatabase {
// TRIGGER SYNC
this._dispatchPlaylistSync('create', playlist);
+ window.dispatchEvent(new CustomEvent('playlist-tracks-changed'));
return playlist;
}
@@ -657,6 +658,7 @@ export class MusicDatabase {
// TRIGGER SYNC (but for deleting)
this._dispatchPlaylistSync('delete', { id: playlistId });
+ window.dispatchEvent(new CustomEvent('playlist-tracks-changed'));
}
async getPlaylist(playlistId) {
diff --git a/js/ui.js b/js/ui.js
index e363cc8..15a6017 100644
--- a/js/ui.js
+++ b/js/ui.js
@@ -3953,11 +3953,13 @@ export class UIRenderer {
if (inLibrarySection) inLibrarySection.style.display = 'none';
if (inLibraryContainer) {
inLibraryContainer.innerHTML = '';
- inLibraryContainer.style.display = 'none';
+ inLibraryContainer.hidden = true;
}
- // Reset chevron state
+ // Reset chevron and toggle state
const chevronEl = document.getElementById('in-library-chevron');
if (chevronEl) chevronEl.style.transform = 'rotate(0deg)';
+ const toggleBtn = document.getElementById('in-library-toggle');
+ if (toggleBtn) toggleBtn.setAttribute('aria-expanded', 'false');
try {
const artist = await this.api.getArtist(artistId, provider);
@@ -4199,12 +4201,16 @@ export class UIRenderer {
const isTrackByArtist = (track) => {
if (track.artists && Array.isArray(track.artists)) {
return track.artists.some(
- (a) => a && a.name && a.name.toLowerCase() === artistNameLower
+ (a) => a && ((artist.id && a.id === artist.id) || (a.name && a.name.toLowerCase() === artistNameLower))
);
}
if (track.artist) {
- const artistStr = typeof track.artist === 'string' ? track.artist : track.artist.name;
- if (artistStr && artistStr.toLowerCase() === artistNameLower) return true;
+ if (typeof track.artist === 'object') {
+ if (artist.id && track.artist.id === artist.id) return true;
+ if (track.artist.name && track.artist.name.toLowerCase() === artistNameLower) return true;
+ } else if (typeof track.artist === 'string') {
+ if (track.artist.toLowerCase() === artistNameLower) return true;
+ }
}
return false;
};
@@ -4285,18 +4291,27 @@ export class UIRenderer {
const sourceSpan = document.createElement('span');
sourceSpan.className = 'library-source';
+ const labelSpan = document.createElement('span');
+ labelSpan.className = 'library-source-label';
+ labelSpan.textContent = '· Source:\u00a0';
+
+ const linkSpan = document.createElement('span');
+ linkSpan.className = 'library-source-link';
+
+ sourceSpan.style.cursor = 'pointer';
+ sourceSpan.appendChild(labelSpan);
+ sourceSpan.appendChild(linkSpan);
+
if (sources.length === 1) {
const srcLabel = sources[0].label.length > 15 ? sources[0].label.slice(0, 15) + '…' : sources[0].label;
- sourceSpan.innerHTML = `· Source: ${srcLabel}`;
- sourceSpan.style.cursor = 'pointer';
+ linkSpan.textContent = srcLabel;
sourceSpan.addEventListener('click', (e) => {
e.preventDefault();
e.stopPropagation();
navigate(sources[0].href);
});
} else {
- sourceSpan.innerHTML = `· Source: Multiple Playlists`;
- sourceSpan.style.cursor = 'pointer';
+ linkSpan.textContent = 'Multiple Playlists';
sourceSpan.addEventListener('click', (e) => {
e.preventDefault();
e.stopPropagation();
@@ -4306,11 +4321,16 @@ export class UIRenderer {
const cancelBtn = document.getElementById('goto-playlist-cancel');
const overlay = modal.querySelector('.modal-overlay');
- list.innerHTML = sources.map((s) =>
- `
- ${s.label}
-
`
- ).join('');
+ list.innerHTML = '';
+ sources.forEach((s) => {
+ const option = document.createElement('div');
+ option.className = 'modal-option';
+ option.dataset.href = s.href;
+ const span = document.createElement('span');
+ span.textContent = s.label;
+ option.appendChild(span);
+ list.appendChild(option);
+ });
const closeModal = () => {
modal.classList.remove('active');
@@ -4357,7 +4377,7 @@ export class UIRenderer {
// Initial load
refreshInLibrary().then(() => {
- inLibraryContainer.style.display = 'none';
+ inLibraryContainer.hidden = true;
});
// Setup chevron toggle (once)
@@ -4365,8 +4385,9 @@ export class UIRenderer {
const chevron = document.getElementById('in-library-chevron');
if (toggle) {
toggle.onclick = () => {
- const isOpen = inLibraryContainer.style.display !== 'none';
- inLibraryContainer.style.display = isOpen ? 'none' : '';
+ const isOpen = !inLibraryContainer.hidden;
+ inLibraryContainer.hidden = isOpen;
+ toggle.setAttribute('aria-expanded', String(!isOpen));
if (chevron) {
chevron.style.transform = isOpen ? 'rotate(0deg)' : 'rotate(90deg)';
}
@@ -4379,15 +4400,17 @@ export class UIRenderer {
clearTimeout(refreshTimeout);
refreshTimeout = setTimeout(() => refreshInLibrary(), 300);
};
- window.addEventListener('favorites-changed', debouncedRefresh);
- window.addEventListener('playlist-tracks-changed', debouncedRefresh);
- // Cleanup listeners when navigating away
+ // Cleanup previous listeners before attaching new ones
const cleanupOnNav = () => {
window.removeEventListener('favorites-changed', debouncedRefresh);
window.removeEventListener('playlist-tracks-changed', debouncedRefresh);
window.removeEventListener('popstate', cleanupOnNav);
};
+ cleanupOnNav();
+
+ window.addEventListener('favorites-changed', debouncedRefresh);
+ window.addEventListener('playlist-tracks-changed', debouncedRefresh);
window.addEventListener('popstate', cleanupOnNav, { once: true });
}
diff --git a/styles.css b/styles.css
index 71a5579..1740d4f 100644
--- a/styles.css
+++ b/styles.css
@@ -1994,6 +1994,10 @@ input[type='search']::-webkit-search-cancel-button {
gap: 2px var(--spacing-xl);
}
+#artist-detail-in-library[hidden] {
+ display: none;
+}
+
.library-source {
color: var(--muted-foreground);
font-size: inherit;
@@ -2365,8 +2369,8 @@ input[type='search']::-webkit-search-cancel-button {
align-items: center;
gap: 1rem;
flex-wrap: wrap;
- overflow-wrap: break-word;
- word-break: break-word;
+ overflow-wrap: anywhere;
+ word-break: normal;
min-width: 0;
}