feat: add search filter bar to playlist detail and favorites views

This commit is contained in:
Honey committed 2026-05-13 13:58:08 +02:00
1 parent d5470a6440
commit e78df7bdb9
4 files changed
+37 -2

No files matched your search

+2 -2
View File
@@ -15,7 +15,7 @@ import {
navigate, _navGoBack, _navLoad, onLocalSearch, onMobileSearch,
onGlobalSearch, s_goArtist, s_goAlbum, playerBarGoArtist, playerBarGoAlbum,
searchSimilarArtist, searchAndPreview, loadItunesAlbum, expandArtistBio,
loadAlbums, loadStarred, loadRandom,
loadAlbums, loadStarred, loadRandom, filterStarred, filterPlaylist,
} from './views.js';
import { loadSpotifyImporter, resolveSpotifyLink, clearSpotifyPreview, spotifyDlAll } from './spotify.js';
import {
@@ -282,7 +282,7 @@ Object.assign(window, {
openSettings, closeSettings, saveSettings, confirmDisconnect, checkBackend,
openSidebar, closeSidebar, switchNavMode, showCtxMenu,
// Views
loadAlbums, loadStarred, loadRandom, loadSpotifyImporter, resolveSpotifyLink, clearSpotifyPreview, spotifyDlAll,
loadAlbums, loadStarred, loadRandom, filterStarred, filterPlaylist, loadSpotifyImporter, resolveSpotifyLink, clearSpotifyPreview, spotifyDlAll,
executeSpotifyDownload,
openPlModal, closePlModal, addSongsToPlaylist, createAndAddPlaylist, createPlaylistPrompt,
showSongInfo, closeInfoModal,
+22
View File
@@ -557,11 +557,22 @@ export async function loadPlaylistDetail(pl) {
};
sl.innerHTML = '';
sl.classList.add('pl-draggable');
const plSearch = document.getElementById('playlist-search');
if (plSearch) plSearch.value = '';
songs.forEach((s,i) => sl.appendChild(makeSongItem(s, i, songs, { noArtistLink: true, noAlbumLink: true })));
_initPlaylistDragDrop(sl, songs, S._currentPlaylist);
} catch(e) { sl.innerHTML = `<p style="color:var(--danger)">${e.message}</p>`; }
}
export function filterPlaylist(val) {
const q = val.trim().toLowerCase();
document.querySelectorAll('#playlist-songs .song-item').forEach(item => {
const title = (item.querySelector('.song-title')?.textContent || '').toLowerCase();
const artist = (item.querySelector('.song-artist')?.textContent || '').toLowerCase();
item.style.display = (!q || title.includes(q) || artist.includes(q)) ? '' : 'none';
});
}
function _initPlaylistDragDrop(container, songs, pl) {
let dragSrc = null;
let saveTimer = null;
@@ -645,6 +656,8 @@ export async function loadStarred(sort = _starredSort) {
c.classList.toggle('active', c.dataset.sort === sort));
const el = document.getElementById('starred-songs');
el.innerHTML = '<div class="spinner"></div>';
const searchEl = document.getElementById('starred-search');
if (searchEl) searchEl.value = '';
try {
const r = await api('getStarred2');
let songs = (r.starred2?.song || []).map(s => ({...s, _starred: true}));
@@ -659,6 +672,15 @@ export async function loadStarred(sort = _starredSort) {
} catch(e) { el.innerHTML = `<p style="color:var(--danger)">${e.message}</p>`; }
}
export function filterStarred(val) {
const q = val.trim().toLowerCase();
document.querySelectorAll('#starred-songs .song-item').forEach(item => {
const title = (item.querySelector('.song-title')?.textContent || '').toLowerCase();
const artist = (item.querySelector('.song-artist')?.textContent || '').toLowerCase();
item.style.display = (!q || title.includes(q) || artist.includes(q)) ? '' : 'none';
});
}
export async function loadRandom() {
const el = document.getElementById('random-songs');
el.innerHTML = '<div class="spinner"></div>';