feat: improve playlist management and visualizer consistency

This commit is contained in:
Julien Maille 2026-01-30 22:39:28 +01:00
parent eea02e9452
commit 758d1ffd6f
3 changed files with 58 additions and 16 deletions

View file

@ -1403,11 +1403,8 @@
stroke-linecap="round" stroke-linecap="round"
stroke-linejoin="round" stroke-linejoin="round"
> >
<path d="M21 12h-6" /> <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" />
<path d="M18 9v6" /> <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" />
<path d="M3 6h18" />
<path d="M3 12h10" />
<path d="M3 18h10" />
</svg> </svg>
</button> </button>
<button <button

View file

@ -771,6 +771,16 @@ document.addEventListener('DOMContentLoaded', async () => {
} }
const cover = document.getElementById('playlist-cover-input').value.trim(); const cover = document.getElementById('playlist-cover-input').value.trim();
// Check for pending tracks (from Add to Playlist -> New Playlist)
const modal = document.getElementById('playlist-modal');
if (modal._pendingTracks && Array.isArray(modal._pendingTracks)) {
tracks = [...tracks, ...modal._pendingTracks];
delete modal._pendingTracks;
// Also clear CSV input if we came from there? No, keep it separate.
console.log(`Added ${tracks.length} tracks (including pending)`);
}
db.createPlaylist(name, tracks, cover).then(async (playlist) => { db.createPlaylist(name, tracks, cover).then(async (playlist) => {
await handlePublicStatus(playlist); await handlePublicStatus(playlist);
// Update DB again with isPublic flag // Update DB again with isPublic flag
@ -983,12 +993,11 @@ document.addEventListener('DOMContentLoaded', async () => {
const playlists = await db.getPlaylists(false); const playlists = await db.getPlaylists(false);
if (playlists.length === 0) { list.innerHTML = `
showNotification('No playlists found. Create one first.'); <div class="modal-option create-new-option" style="border-bottom: 1px solid var(--border); margin-bottom: 0.5rem;">
return; <span style="font-weight: 600; color: var(--primary);">+ Create New Playlist</span>
} </div>
` + playlists
list.innerHTML = playlists
.map( .map(
(p) => ` (p) => `
<div class="modal-option" data-id="${p.id}"> <div class="modal-option" data-id="${p.id}">
@ -1006,6 +1015,24 @@ document.addEventListener('DOMContentLoaded', async () => {
const handleOptionClick = async (e) => { const handleOptionClick = async (e) => {
const option = e.target.closest('.modal-option'); const option = e.target.closest('.modal-option');
if (!option) return; if (!option) return;
if (option.classList.contains('create-new-option')) {
closeModal();
const createModal = document.getElementById('playlist-modal');
document.getElementById('playlist-modal-title').textContent = 'Create Playlist';
document.getElementById('playlist-name-input').value = '';
document.getElementById('playlist-cover-input').value = '';
createModal.dataset.editingId = '';
document.getElementById('csv-import-section').style.display = 'none'; // Hide CSV for simple add
// Pass tracks
createModal._pendingTracks = tracks;
createModal.classList.add('active');
document.getElementById('playlist-name-input').focus();
return;
}
const playlistId = option.dataset.id; const playlistId = option.dataset.id;
try { try {

View file

@ -832,10 +832,7 @@ export async function handleTrackAction(
const renderModal = async () => { const renderModal = async () => {
const playlists = await db.getPlaylists(true); const playlists = await db.getPlaylists(true);
if (playlists.length === 0) { // Removed empty check to allow creating new playlist
showNotification('No playlists yet. Create one first.');
return false;
}
const trackId = item.id; const trackId = item.id;
const playlistsWithTrack = new Set(); const playlistsWithTrack = new Set();
@ -846,7 +843,11 @@ export async function handleTrackAction(
} }
} }
list.innerHTML = playlists list.innerHTML = `
<div class="modal-option create-new-option" style="border-bottom: 1px solid var(--border); margin-bottom: 0.5rem;">
<span style="font-weight: 600; color: var(--primary);">+ Create New Playlist</span>
</div>
` + playlists
.map((p) => { .map((p) => {
const alreadyContains = playlistsWithTrack.has(p.id); const alreadyContains = playlistsWithTrack.has(p.id);
return ` return `
@ -877,6 +878,23 @@ export async function handleTrackAction(
if (!option) return; if (!option) return;
if (option.classList.contains('create-new-option')) {
closeModal();
const createModal = document.getElementById('playlist-modal');
document.getElementById('playlist-modal-title').textContent = 'Create Playlist';
document.getElementById('playlist-name-input').value = '';
document.getElementById('playlist-cover-input').value = '';
createModal.dataset.editingId = '';
document.getElementById('csv-import-section').style.display = 'none';
// Pass track
createModal._pendingTracks = [item];
createModal.classList.add('active');
document.getElementById('playlist-name-input').focus();
return;
}
const playlistId = option.dataset.id; const playlistId = option.dataset.id;
if (removeBtn) { if (removeBtn) {