mirror of
https://lavaforge.org/spotizerr/spotizerr.git
synced 2025-12-23 18:29:13 -05:00
ts
This commit is contained in:
@@ -4,6 +4,7 @@ services:
|
||||
spotizerr:
|
||||
volumes:
|
||||
- ./creds:/app/creds
|
||||
- ./config:/app/config
|
||||
- ./downloads:/app/downloads # <-- Change this for your music library dir
|
||||
ports:
|
||||
- 7171:7171
|
||||
|
||||
@@ -57,7 +57,7 @@ function renderArtist(artistData, artistId) {
|
||||
downloadArtistBtn = document.createElement('button');
|
||||
downloadArtistBtn.id = 'downloadArtistBtn';
|
||||
downloadArtistBtn.className = 'download-btn download-btn--main';
|
||||
downloadArtistBtn.textContent = 'Download All Albums';
|
||||
downloadArtistBtn.textContent = 'Download All Discography';
|
||||
document.getElementById('artist-header').appendChild(downloadArtistBtn);
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ function renderPlaylist(playlist) {
|
||||
downloadPlaylistBtn.id = 'downloadPlaylistBtn';
|
||||
downloadPlaylistBtn.textContent = 'Download Whole Playlist';
|
||||
downloadPlaylistBtn.className = 'download-btn download-btn--main';
|
||||
// Insert the button into the header container (e.g. after the description)
|
||||
// Insert the button into the header container.
|
||||
const headerContainer = document.getElementById('playlist-header');
|
||||
headerContainer.appendChild(downloadPlaylistBtn);
|
||||
}
|
||||
@@ -97,6 +97,36 @@ function renderPlaylist(playlist) {
|
||||
});
|
||||
});
|
||||
|
||||
// --- Add "Download Playlist's Albums" Button ---
|
||||
let downloadAlbumsBtn = document.getElementById('downloadAlbumsBtn');
|
||||
if (!downloadAlbumsBtn) {
|
||||
downloadAlbumsBtn = document.createElement('button');
|
||||
downloadAlbumsBtn.id = 'downloadAlbumsBtn';
|
||||
downloadAlbumsBtn.textContent = "Download Playlist's Albums";
|
||||
downloadAlbumsBtn.className = 'download-btn download-btn--main';
|
||||
// Insert the new button into the header container.
|
||||
const headerContainer = document.getElementById('playlist-header');
|
||||
headerContainer.appendChild(downloadAlbumsBtn);
|
||||
}
|
||||
downloadAlbumsBtn.addEventListener('click', () => {
|
||||
// Remove individual track download buttons (but leave this album button).
|
||||
document.querySelectorAll('.download-btn').forEach(btn => {
|
||||
if (btn.id !== 'downloadAlbumsBtn') btn.remove();
|
||||
});
|
||||
|
||||
downloadAlbumsBtn.disabled = true;
|
||||
downloadAlbumsBtn.textContent = 'Queueing...';
|
||||
|
||||
downloadPlaylistAlbums(playlist)
|
||||
.then(() => {
|
||||
downloadAlbumsBtn.textContent = 'Queued!';
|
||||
})
|
||||
.catch(err => {
|
||||
showError('Failed to queue album downloads: ' + err.message);
|
||||
downloadAlbumsBtn.disabled = false;
|
||||
});
|
||||
});
|
||||
|
||||
// Render tracks list
|
||||
const tracksList = document.getElementById('tracks-list');
|
||||
tracksList.innerHTML = ''; // Clear any existing content
|
||||
@@ -166,20 +196,16 @@ function showError(message) {
|
||||
*/
|
||||
function attachDownloadListeners() {
|
||||
document.querySelectorAll('.download-btn').forEach((btn) => {
|
||||
// Skip the whole playlist button.
|
||||
if (btn.id === 'downloadPlaylistBtn') return;
|
||||
// Skip the whole playlist and album download buttons.
|
||||
if (btn.id === 'downloadPlaylistBtn' || btn.id === 'downloadAlbumsBtn') return;
|
||||
btn.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
const url = e.currentTarget.dataset.url;
|
||||
const type = e.currentTarget.dataset.type;
|
||||
const name = e.currentTarget.dataset.name || extractName(url);
|
||||
const albumType = e.currentTarget.dataset.albumType;
|
||||
|
||||
// Remove the button after click
|
||||
// Remove the button immediately after click.
|
||||
e.currentTarget.remove();
|
||||
|
||||
// Start the download for this track.
|
||||
startDownload(url, type, { name }, albumType);
|
||||
startDownload(url, type, { name });
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -187,7 +213,6 @@ function attachDownloadListeners() {
|
||||
/**
|
||||
* Initiates the whole playlist download by calling the playlist endpoint.
|
||||
*/
|
||||
// playlist.js
|
||||
async function downloadWholePlaylist(playlist) {
|
||||
const url = playlist.external_urls.spotify;
|
||||
try {
|
||||
@@ -198,12 +223,45 @@ async function downloadWholePlaylist(playlist) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiates album downloads for each unique album in the playlist.
|
||||
*/
|
||||
async function downloadPlaylistAlbums(playlist) {
|
||||
// Use a Map to ensure each album is processed only once (by album ID).
|
||||
const albumMap = new Map();
|
||||
playlist.tracks.items.forEach(item => {
|
||||
const album = item.track.album;
|
||||
if (album && album.id) {
|
||||
albumMap.set(album.id, album);
|
||||
}
|
||||
});
|
||||
|
||||
const uniqueAlbums = Array.from(albumMap.values());
|
||||
if (uniqueAlbums.length === 0) {
|
||||
showError('No albums found in this playlist.');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Start album downloads concurrently.
|
||||
await Promise.all(uniqueAlbums.map(album =>
|
||||
downloadQueue.startAlbumDownload(
|
||||
album.external_urls.spotify,
|
||||
{ name: album.name }
|
||||
)
|
||||
));
|
||||
} catch (error) {
|
||||
// Propagate any errors.
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the download process by building the API URL,
|
||||
* fetching download details, and then adding the download to the queue.
|
||||
*/
|
||||
async function startDownload(url, type, item, albumType) {
|
||||
// Retrieve configuration (if any) from localStorage
|
||||
// Retrieve configuration (if any) from localStorage.
|
||||
const config = JSON.parse(localStorage.getItem('activeConfig')) || {};
|
||||
const {
|
||||
fallback = false,
|
||||
|
||||
Reference in New Issue
Block a user