Spaces:
Runtime error
Runtime error
File size: 9,320 Bytes
a3de571 2de827e 9ba1026 8c8edb7 a3de571 728ac49 2de827e 728ac49 2de827e cf7d706 2de827e 8c8edb7 728ac49 86cc9a8 2de827e 827e364 15698cf 2de827e 2d0c3d8 b832130 9b0ef7c b832130 265b8b3 fdb3927 265b8b3 2d0c3d8 6c29de6 265b8b3 6c29de6 265b8b3 728ac49 265b8b3 86cc9a8 9e5b045 435ec37 2de827e 265b8b3 9e5b045 265b8b3 2de827e 265b8b3 2de827e 265b8b3 827e364 265b8b3 79d91d2 265b8b3 2de827e 0920432 f0f023f 462df3a 0920432 462df3a 0920432 462df3a f0f023f 0920432 f0f023f 0920432 86cc9a8 e01d533 1410aee e01d533 8c8edb7 7c98df5 8c8edb7 7c98df5 8c8edb7 7c98df5 8c8edb7 0181a40 8c8edb7 728ac49 df73cb7 4f08056 8c8edb7 df73cb7 e01d533 8487836 6de3914 36864be e504282 8c8edb7 6de3914 8c8edb7 36864be 8c8edb7 8eedc8c 8c8edb7 bef4985 6abe8b6 7e66b3c 37fb96f 36864be 37fb96f 36864be 37fb96f 36864be 37fb96f 8c8edb7 e504282 6abe8b6 cf7d706 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 |
let isLooping = false; // Flag to manage loop state
let isLoadingMusic = false; // Flag to manage loading state
let currentPlaying = ''; // Store the filename of the currently playing music
let trackList = []; // Store currently displayed track filenames
let currentPage = 1;
let totalPages = 0;
let audio = new Audio();
window.onload = () => {
// Attach click handlers for paging
document.getElementById('prev-page').addEventListener('click', () => changePage(-1));
document.getElementById('next-page').addEventListener('click', () => changePage(1));
loadMusicList();
document.getElementById('search-bar').addEventListener('keyup', () => {
currentPage = 1; // Reset to first page on new search
loadMusicList();
});
document.getElementById('audio-player').style.display = 'none';
updatePageIndicator();
setupCustomAudioPlayer();
};
function changePage(direction) {
currentPage += direction;
loadMusicList();
}
function updatePageIndicator(totalPages) {
document.getElementById('page-indicator').textContent = `${currentPage}/${totalPages}`;
}
function debounce(func, delay) {
let debounceTimer;
return function() {
const context = this;
const args = arguments;
clearTimeout(debounceTimer);
debounceTimer = setTimeout(() => func.apply(context, args), delay);
};
}
function toggleLoop() {
isLooping = !isLooping;
document.getElementById('loop-toggle').textContent = `Loop: ${isLooping ? 'On' : 'Off'}`;
const player = document.getElementById('audio-player');
player.loop = isLooping;
}
function updateNavigationVisibility(searchQuery, totalPages) {
const navigation = document.getElementById('navigation');
if (searchQuery) {
navigation.style.display = 'none'; // Hide navigation during search
} else {
navigation.style.display = 'flex'; // Show navigation when not searching
document.getElementById('prev-page').disabled = currentPage <= 1;
document.getElementById('next-page').disabled = currentPage >= totalPages;
}
}
// Call loadMusicList when the search input changes
document.getElementById('search-bar').addEventListener('keyup', debounce(() => {
currentPage = 1;
loadMusicList();
}, 500)); // Waits for 0.5s of inactivity after typing
function loadMusicList() {
const searchQuery = document.getElementById('search-bar').value.toLowerCase();
const params = new URLSearchParams({ page: currentPage });
if (searchQuery) {
params.append('search', searchQuery); // Add search query to the request if it exists
}
// Disabling buttons and showing loading indicator before the request
document.getElementById('prev-page').disabled = true;
document.getElementById('next-page').disabled = true;
const loaderContainer = document.getElementById('loader-container');
loaderContainer.innerHTML = ''; // Clears any existing loader elements if they are present
const loaderElement = document.createElement('div');
loaderElement.classList.add('loader');
loaderContainer.appendChild(loaderElement);
fetch(`/tracks?${params}`)
.then(response => response.json())
.then(data => {
const { tracks, total } = data;
const musicList = document.getElementById('music-list');
musicList.innerHTML = '';
trackList = [];
const totalPages = Math.ceil(total / 5);
// Hide loading indicator
loaderContainer.innerHTML = '';
// Re-enable buttons based on page state
document.getElementById('prev-page').disabled = currentPage === 1;
document.getElementById('next-page').disabled = currentPage === totalPages || searchQuery;
tracks.forEach(track => {
trackList.push(track.filename);
const musicItem = createMusicItem(track);
musicList.appendChild(musicItem);
});
// Show/hide navigation based on whether there is a search query
updatePageIndicator(totalPages);
updateNavigationVisibility(searchQuery, totalPages);
updatePlayingIndicator();
});
}
function createMusicItem(track) {
const musicItem = document.createElement('div');
musicItem.classList.add('music-item');
musicItem.setAttribute('data-filename', track.filename);
const artworkImg = document.createElement('img');
artworkImg.src = track.artwork ? track.artwork : 'placeholder_art.png';
artworkImg.alt = 'Album Art';
artworkImg.classList.add('album-art');
const fileNameSpan = document.createElement('span');
fileNameSpan.textContent = track.filename;
musicItem.append(artworkImg, fileNameSpan);
// Bind the music item click to playMusic
musicItem.addEventListener('click', () => playMusic(track.filename));
return musicItem;
}
function updatePlayingIndicator() {
const musicItems = document.querySelectorAll('.music-item');
musicItems.forEach(item => {
if (item.getAttribute('data-filename') === currentPlaying) {
item.style.boxShadow = '0 0 10px rgba(255, 255, 255, 0.5)'; // Green box shadow
} else {
item.style.boxShadow = ''; // Remove box shadow from other items
}
});
}
function setupCustomAudioPlayer() {
// Play/Pause toggle
document.getElementById('play-pause-btn').addEventListener('click', function() {
if (audio.paused) {
audio.play();
this.textContent = 'ββ'; // Update button text to "ββ"
} else {
audio.pause();
this.textContent = 'βΆ'; // Update button text to "βΆ"
}
});
// Update progress bar as the audio plays
audio.addEventListener('timeupdate', function() {
const progress = document.getElementById('progress-bar');
progress.value = (audio.currentTime / audio.duration) * 100;
});
// Seek in the audio when the progress bar value changes
document.getElementById('progress-bar').addEventListener('input', function() {
const duration = audio.duration;
audio.currentTime = (this.value * duration) / 100;
});
// Mute toggle
document.getElementById('mute-btn').addEventListener('click', function() {
audio.muted = !audio.muted;
this.textContent = audio.muted ? 'π' : 'π'; // Update button text based on mute state
});
// Volume control
document.getElementById('volume-control').addEventListener('input', function() {
audio.volume = this.value / 100;
});
// Initial volume (100%)
audio.volume = 1.0;
audio.addEventListener('timeupdate', function() {
updateProgress();
});
// When audio metadata is loaded, update duration
audio.addEventListener('loadedmetadata', function() {
document.getElementById('duration').textContent = formatTime(audio.duration);
});
}
function updateProgress() {
const progress = document.getElementById('progress-bar');
progress.value = (audio.currentTime / audio.duration) * 100;
document.getElementById('current-time').textContent = formatTime(audio.currentTime);
}
function formatTime(seconds) {
let minutes = Math.floor(seconds / 60);
minutes = (minutes >= 10) ? minutes : "0" + minutes;
seconds = Math.floor(seconds % 60);
seconds = (seconds >= 10) ? seconds : "0" + seconds;
return minutes + ":" + seconds;
}
function playMusic(fileName) {
if (isLoadingMusic && fileName === currentPlaying) {
console.log("This song is already loading.");
return;
} else if (!isLoadingMusic && fileName === currentPlaying) {
console.log("This song is already playing.");
return;
}
isLoadingMusic = true;
currentPlaying = fileName;
updatePlayingIndicator();
document.getElementById('audio-player').style.display = 'none'; // Hide custom player UI
const loaderContainer = document.getElementById('loader-container');
loaderContainer.innerHTML = '';
const loaderElement = document.createElement('div');
loaderElement.classList.add('loader');
loaderContainer.appendChild(loaderElement);
// Set the new source file for audio
audio.src = `/music/${fileName}`;
audio.load(); // Start loading the new source file
audio.oncanplaythrough = () => {
document.getElementById('audio-player').style.display = 'flex'; // Show custom player UI
loaderContainer.innerHTML = '';
isLoadingMusic = false;
document.getElementById('play-pause-btn').textContent = 'ββ'; // Update play/pause button
audio.play(); // Start playback
};
// Updated onended event handler within playMusic function
audio.onended = () => {
if (isLooping) {
// Replay the current song
audio.currentTime = 0;
audio.play();
} else {
const currentIndex = trackList.indexOf(currentPlaying);
if (currentIndex !== -1 && currentIndex < trackList.length - 1) {
playMusic(trackList[currentIndex + 1]);
}
}
};
audio.onerror = () => {
isLoadingMusic = false;
alert(`Error loading the music: ${fileName}`);
currentPlaying = ''; // Reset the current playing track
};
} |