diff --git a/index.html b/index.html
index 7c5b05c..233b51d 100644
--- a/index.html
+++ b/index.html
@@ -1642,6 +1642,14 @@
+
+
+
`;
}
+ setupTracklistSearch(searchInputId = 'track-list-search-input', tracklistContainerId = 'playlist-detail-tracklist') {
+ const searchInput = document.getElementById(searchInputId);
+ const tracklistContainer = document.getElementById(tracklistContainerId);
+
+ if (!searchInput || !tracklistContainer) return;
+
+ // Remove previous listener if exists
+ const oldListener = searchInput._searchListener;
+ if (oldListener) {
+ searchInput.removeEventListener('input', oldListener);
+ }
+
+ // Create new listener
+ const listener = () => {
+ const query = searchInput.value.toLowerCase().trim();
+ const trackItems = tracklistContainer.querySelectorAll('.track-item');
+
+ trackItems.forEach((item) => {
+ const trackData = trackDataStore.get(item);
+ if (!trackData) {
+ item.style.display = '';
+ return;
+ }
+
+ const title = (trackData.title || '').toLowerCase();
+ const artist = (trackData.artist?.name || trackData.artists?.[0]?.name || '').toLowerCase();
+ const album = (trackData.album?.title || '').toLowerCase();
+
+ const matches = title.includes(query) || artist.includes(query) || album.includes(query);
+ item.style.display = matches ? '' : 'none';
+ });
+ };
+
+ searchInput._searchListener = listener;
+ searchInput.addEventListener('input', listener);
+ }
+
renderListWithTracks(container, tracks, showCover, append = false, useTrackNumber = false) {
const fragment = document.createDocumentFragment();
const tempDiv = document.createElement('div');
@@ -2085,6 +2122,9 @@ export class UIRenderer {
isUserPlaylist: true,
});
document.title = `${playlistData.name || playlistData.title} - Monochrome`;
+
+ // Setup playlist search
+ this.setupTracklistSearch();
} else {
// If source was explicitly 'user' and we didn't find it, fail.
if (source === 'user') {
@@ -2154,6 +2194,9 @@ export class UIRenderer {
recentActivityManager.addPlaylist(playlist);
document.title = playlist.title || 'Artist Mix';
}
+
+ // Setup playlist search
+ this.setupTracklistSearch();
} catch (error) {
console.error('Failed to load playlist:', error);
tracklistContainer.innerHTML = createPlaceholder(`Could not load playlist details. ${error.message}`);
diff --git a/styles.css b/styles.css
index 6620248..1501260 100644
--- a/styles.css
+++ b/styles.css
@@ -5515,3 +5515,31 @@ textarea:focus {
min-width: 30px;
}
}
+
+/* Track List Search */
+.track-list-search-container {
+ margin: 1rem 0;
+}
+
+.track-list-search-input {
+ width: 100%;
+ padding: 0.75rem 1rem;
+ background-color: var(--input);
+ border: 1px solid var(--border);
+ border-radius: var(--radius);
+ color: var(--foreground);
+ font-size: 0.95rem;
+ transition:
+ box-shadow var(--transition-fast),
+ border-color var(--transition-fast);
+}
+
+.track-list-search-input:focus {
+ outline: none;
+ border-color: var(--ring);
+ box-shadow: 0 0 0 3px rgb(var(--highlight-rgb) / 0.2);
+}
+
+.track-list-search-input::placeholder {
+ color: var(--muted-foreground);
+}