feat: improve playlist management and visualizer consistency
This commit is contained in:
parent
eea02e9452
commit
758d1ffd6f
3 changed files with 58 additions and 16 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
39
js/app.js
39
js/app.js
|
|
@ -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 {
|
||||||
|
|
|
||||||
28
js/events.js
28
js/events.js
|
|
@ -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) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue