cleanup js
This commit is contained in:
parent
7d938c046a
commit
576f6f9bc1
@ -226,4 +226,7 @@ footer {
|
||||
|
||||
#reload-button svg.rotate {
|
||||
animation: rotate-icon 0.5s linear;
|
||||
transition: opacity 1s ease;
|
||||
opacity: 0;
|
||||
cursor: auto;
|
||||
}
|
||||
127
static/app.js
127
static/app.js
@ -175,15 +175,21 @@ function attachEventListeners() {
|
||||
});
|
||||
});
|
||||
|
||||
// Cache common DOM elements
|
||||
const nowPlayingInfo = document.getElementById('nowPlayingInfo');
|
||||
const audioPlayer = document.getElementById('globalAudio');
|
||||
const playerButton = document.querySelector('.player-button');
|
||||
const audioPlayerContainer = document.getElementById('audioPlayerContainer');
|
||||
const footer = document.querySelector('footer');
|
||||
|
||||
// Global variable to store the current fetch's AbortController.
|
||||
let currentFetchController = null;
|
||||
|
||||
document.querySelectorAll('.play-file').forEach(link => {
|
||||
link.addEventListener('click', async function (event) {
|
||||
event.preventDefault();
|
||||
const fileType = this.getAttribute('data-file-type');
|
||||
const relUrl = this.getAttribute('data-url');
|
||||
const nowPlayingInfo = document.getElementById('nowPlayingInfo');
|
||||
|
||||
const { fileType, url: relUrl, index } = this.dataset;
|
||||
|
||||
// Remove the class from all file items.
|
||||
document.querySelectorAll('.file-item').forEach(item => {
|
||||
@ -191,83 +197,91 @@ document.querySelectorAll('.play-file').forEach(link => {
|
||||
});
|
||||
|
||||
if (fileType === 'music') {
|
||||
const idx = this.getAttribute('data-index');
|
||||
const audioPlayer = document.getElementById('globalAudio');
|
||||
const playerButton = document.querySelector('.player-button');
|
||||
// Update the current music index.
|
||||
currentMusicIndex = index !== undefined ? parseInt(index) : -1;
|
||||
|
||||
// Update currentMusicIndex based on the clicked element.
|
||||
currentMusicIndex = idx !== null ? parseInt(idx) : -1;
|
||||
// Display the audio player container.
|
||||
audioPlayerContainer.style.display = "block";
|
||||
|
||||
// Show the audio player container.
|
||||
document.getElementById('audioPlayerContainer').style.display = "block"
|
||||
|
||||
// Add the class to the clicked file item's parent.
|
||||
// Mark the clicked item as currently playing.
|
||||
this.closest('.file-item').classList.add('currently-playing');
|
||||
|
||||
// Abort any previous fetch if it is still running.
|
||||
// Abort any previous fetch if still running.
|
||||
if (currentFetchController) {
|
||||
currentFetchController.abort();
|
||||
}
|
||||
// Create a new AbortController for the current fetch.
|
||||
currentFetchController = new AbortController();
|
||||
|
||||
// Pause the audio and clear its source.
|
||||
audioPlayer.pause();
|
||||
audioPlayer.src = ''; // Clear existing source.
|
||||
// only show this if it takes longer. avoid flicker
|
||||
let loaderTimeout = setTimeout(() => {
|
||||
audioPlayer.src = '';
|
||||
|
||||
// Set a timeout to display a loader message if needed.
|
||||
const loaderTimeout = setTimeout(() => {
|
||||
playerButton.innerHTML = playIcon;
|
||||
nowPlayingInfo.textContent = "Wird geladen...";
|
||||
}, 500);
|
||||
document.querySelector('footer').style.display = 'flex';
|
||||
|
||||
const mediaUrl = '/media/' + relUrl;
|
||||
footer.style.display = 'flex';
|
||||
|
||||
const mediaUrl = `/media/${relUrl}`;
|
||||
|
||||
try {
|
||||
// Pass the signal to the fetch so it can be aborted.
|
||||
// Perform a HEAD request to verify media availability.
|
||||
const response = await fetch(mediaUrl, { method: 'HEAD', signal: currentFetchController.signal });
|
||||
clearTimeout(loaderTimeout); // done loading. stop timeout
|
||||
clearTimeout(loaderTimeout);
|
||||
|
||||
if (response.status === 403) {
|
||||
nowPlayingInfo.textContent = "Fehler: Zugriff verweigert.";
|
||||
window.location.href = '/'; // Redirect if forbidden.
|
||||
window.location.href = '/';
|
||||
return;
|
||||
} else if (!response.ok) {
|
||||
nowPlayingInfo.textContent = `Fehler: Unerwarteter Status (${response.status}).`;
|
||||
console.error('Unexpected response status:', response.status);
|
||||
} else {
|
||||
audioPlayer.src = mediaUrl;
|
||||
audioPlayer.load();
|
||||
audioPlayer.play();
|
||||
playerButton.innerHTML = pauseIcon;
|
||||
const pathParts = relUrl.split('/');
|
||||
const folderName = pathParts[pathParts.length - 2];
|
||||
const fileName = pathParts.pop();
|
||||
const pathStr = pathParts.join('/');
|
||||
// write into hardware player
|
||||
if ('mediaSession' in navigator) {
|
||||
navigator.mediaSession.metadata = new MediaMetadata({
|
||||
title: currentMusicFiles[currentMusicIndex].title,
|
||||
artist: folderName,
|
||||
artwork: [
|
||||
{ src: '/static/icons/logo-192x192.png', sizes: '192x192', type: 'image/png' }
|
||||
]
|
||||
});
|
||||
};
|
||||
nowPlayingInfo.innerHTML = pathStr.replace(/\//g, ' > ') + '<br><span style="font-size: larger; font-weight: bold;">' + fileName.replace('.mp3', '') + '</span>';
|
||||
// Delay preloading to avoid blocking playback
|
||||
setTimeout(preload_audio, 1000);
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the media URL, load, and play the audio.
|
||||
audioPlayer.src = mediaUrl;
|
||||
audioPlayer.load();
|
||||
await audioPlayer.play();
|
||||
playerButton.innerHTML = pauseIcon;
|
||||
|
||||
// Process file path for display.
|
||||
const pathParts = relUrl.split('/');
|
||||
const folderName = pathParts[pathParts.length - 2];
|
||||
const fileName = pathParts.pop();
|
||||
const pathStr = pathParts.join('/');
|
||||
|
||||
// Update Media Session metadata if available.
|
||||
if ('mediaSession' in navigator) {
|
||||
navigator.mediaSession.metadata = new MediaMetadata({
|
||||
title: currentMusicFiles[currentMusicIndex].title,
|
||||
artist: folderName,
|
||||
artwork: [
|
||||
{ src: '/static/icons/logo-192x192.png', sizes: '192x192', type: 'image/png' }
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
nowPlayingInfo.innerHTML = pathStr.replace(/\//g, ' > ') +
|
||||
'<br><span style="font-size: larger; font-weight: bold;">' +
|
||||
fileName.replace('.mp3', '') + '</span>';
|
||||
|
||||
// Delay preloading to avoid blocking playback.
|
||||
setTimeout(preload_audio, 1000);
|
||||
} catch (error) {
|
||||
// If the fetch was aborted, error.name will be 'AbortError'.
|
||||
if (error.name === 'AbortError') {
|
||||
console.log('Previous fetch aborted.');
|
||||
} else {
|
||||
console.error('Error fetching media:', error);
|
||||
nowPlayingInfo.textContent = "Fehler: Netzwerkproblem oder ungültige URL.";
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
} else if (fileType === 'image') {
|
||||
// Open the gallery modal for image files.
|
||||
openGalleryModal(relUrl);
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -341,23 +355,20 @@ function reloadDirectory() {
|
||||
// Force reflow to reset the animation
|
||||
void reloadBtnSVG.offsetWidth;
|
||||
reloadBtnSVG.classList.add("rotate");
|
||||
|
||||
// Gradually fade out the button by reducing opacity over 500ms
|
||||
setTimeout(() => {
|
||||
reloadBtnSVG.classList.remove("rotate");
|
||||
reloadBtn.style.transition = 'opacity 0.5s ease';
|
||||
reloadBtn.style.opacity = '0';
|
||||
isReloadButtonVisible = false; // Update the visibility status.
|
||||
}, 500);
|
||||
isReloadButtonVisible = false;
|
||||
|
||||
// Gradually fade back in after 10 seconds
|
||||
setTimeout(() => {
|
||||
reloadBtnSVG.classList.remove("rotate");
|
||||
reloadBtn.style.transition = 'opacity 0.5s ease';
|
||||
reloadBtn.style.opacity = '1';
|
||||
isReloadButtonVisible = true; // Update the visibility status.
|
||||
reloadBtn.style.pointer = 'cursor';
|
||||
isReloadButtonVisible = true;
|
||||
}, 10000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ('mediaSession' in navigator) {
|
||||
|
||||
// Handler for the play action
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user