Merge pull request #154 from blacksigkill/feature/playlist-search
add a search bar in playlists to quickly find titles
This commit is contained in:
commit
31c9890db8
3 changed files with 79 additions and 0 deletions
|
|
@ -1642,6 +1642,14 @@
|
|||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="track-list-search-container">
|
||||
<input
|
||||
type="text"
|
||||
id="track-list-search-input"
|
||||
placeholder="Search tracks..."
|
||||
class="track-list-search-input"
|
||||
/>
|
||||
</div>
|
||||
<div id="playlist-detail-tracklist" class="track-list"></div>
|
||||
|
||||
<section
|
||||
|
|
|
|||
43
js/ui.js
43
js/ui.js
|
|
@ -539,6 +539,43 @@ export class UIRenderer {
|
|||
.join('')}</div>`;
|
||||
}
|
||||
|
||||
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}`);
|
||||
|
|
|
|||
28
styles.css
28
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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue