feat: połączenie przycisków zapętlania w jeden przycisk z cyklem Wyłączone -> Kolejka -> Utwór (styl YT Music/Spotify)
This commit is contained in:
4 files changed
+86
-59
No files matched your search
+38
-45
@@ -31,7 +31,6 @@ const playPauseIcon = document.getElementById('play-pause-icon');
|
||||
const btnSkip = document.getElementById('btn-skip');
|
||||
const btnStop = document.getElementById('btn-stop');
|
||||
const btnLoop = document.getElementById('btn-loop');
|
||||
const btnLoopPlaylist = document.getElementById('btn-loop-playlist');
|
||||
const vinylRecord = document.getElementById('vinyl-record');
|
||||
const musicWave = document.getElementById('music-wave');
|
||||
const volumeSlider = document.getElementById('volume-slider');
|
||||
@@ -142,9 +141,6 @@ function bindEvents() {
|
||||
btnSkip.addEventListener('click', skipTrack);
|
||||
btnStop.addEventListener('click', stopPlayback);
|
||||
btnLoop.addEventListener('click', toggleLoop);
|
||||
if (btnLoopPlaylist) {
|
||||
btnLoopPlaylist.addEventListener('click', toggleLoopPlaylist);
|
||||
}
|
||||
|
||||
// Volume slider
|
||||
volumeSlider.addEventListener('input', (e) => {
|
||||
@@ -375,28 +371,39 @@ function updateUI(status) {
|
||||
updateVolumeIcon(status.volume);
|
||||
}
|
||||
|
||||
// 5. Loop State
|
||||
if (status.loop_single) {
|
||||
loopBadge.style.display = 'flex';
|
||||
btnLoop.classList.add('active');
|
||||
btnLoop.style.background = 'var(--primary)';
|
||||
btnLoop.style.color = 'var(--bg-card)';
|
||||
} else {
|
||||
loopBadge.style.display = 'none';
|
||||
btnLoop.classList.remove('active');
|
||||
btnLoop.style.background = '';
|
||||
btnLoop.style.color = '';
|
||||
}
|
||||
// 5. Loop State (Combined toggle: Off -> Playlist -> Single)
|
||||
let loopMode = 'off';
|
||||
if (status.loop_single) loopMode = 'single';
|
||||
else if (status.loop_playlist) loopMode = 'playlist';
|
||||
|
||||
if (btnLoopPlaylist) {
|
||||
if (status.loop_playlist) {
|
||||
btnLoopPlaylist.classList.add('active');
|
||||
btnLoopPlaylist.style.background = 'var(--primary)';
|
||||
btnLoopPlaylist.style.color = 'var(--bg-card)';
|
||||
if (btnLoop.dataset.loopMode !== loopMode) {
|
||||
btnLoop.dataset.loopMode = loopMode;
|
||||
if (loopMode === 'single') {
|
||||
btnLoop.innerHTML = '<i data-lucide="repeat-1"></i>';
|
||||
btnLoop.classList.add('active');
|
||||
btnLoop.style.background = 'var(--primary)';
|
||||
btnLoop.style.color = 'var(--bg-card)';
|
||||
btnLoop.title = "Zapętlenie: jeden utwór (kliknij, aby wyłączyć)";
|
||||
loopBadge.style.display = 'flex';
|
||||
loopBadge.innerHTML = '<i data-lucide="repeat-1"></i> Zapętlenie utworu';
|
||||
} else if (loopMode === 'playlist') {
|
||||
btnLoop.innerHTML = '<i data-lucide="repeat"></i>';
|
||||
btnLoop.classList.add('active');
|
||||
btnLoop.style.background = 'var(--primary)';
|
||||
btnLoop.style.color = 'var(--bg-card)';
|
||||
btnLoop.title = "Zapętlenie: cała kolejka (kliknij, aby zapętlić jeden utwór)";
|
||||
loopBadge.style.display = 'flex';
|
||||
loopBadge.innerHTML = '<i data-lucide="repeat"></i> Zapętlenie kolejki';
|
||||
} else {
|
||||
btnLoopPlaylist.classList.remove('active');
|
||||
btnLoopPlaylist.style.background = '';
|
||||
btnLoopPlaylist.style.color = '';
|
||||
btnLoop.innerHTML = '<i data-lucide="repeat"></i>';
|
||||
btnLoop.classList.remove('active');
|
||||
btnLoop.style.background = '';
|
||||
btnLoop.style.color = '';
|
||||
btnLoop.title = "Zapętlenie: wyłączone (kliknij, aby zapętlić kolejkę)";
|
||||
loopBadge.style.display = 'none';
|
||||
}
|
||||
if (window.lucide) {
|
||||
lucide.createIcons();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -700,35 +707,21 @@ async function stopPlayback() {
|
||||
}
|
||||
}
|
||||
|
||||
// Toggle Loop State
|
||||
// Toggle Loop State (Cycle: Off -> Playlist -> Single -> Off)
|
||||
async function toggleLoop() {
|
||||
if (!currentStatus) return;
|
||||
const nextState = !currentStatus.loop_single;
|
||||
try {
|
||||
const res = await fetch('/api/loop', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ loop: nextState })
|
||||
});
|
||||
if (!res.ok) throw new Error('Loop failed');
|
||||
showToast(nextState ? 'Zapętlanie utworu włączone' : 'Zapętlanie utworu wyłączone', 'info');
|
||||
const res = await fetch('/api/loop_cycle', { method: 'POST' });
|
||||
if (!res.ok) throw new Error('Loop cycle failed');
|
||||
const data = await res.json();
|
||||
if (data.mode === 'playlist') showToast('Zapętlanie kolejki włączone', 'info');
|
||||
else if (data.mode === 'single') showToast('Zapętlanie utworu włączone', 'info');
|
||||
else showToast('Zapętlanie wyłączone', 'info');
|
||||
} catch (err) {
|
||||
showToast('Błąd ustawiania pętli', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// Toggle Playlist Loop State
|
||||
async function toggleLoopPlaylist() {
|
||||
try {
|
||||
const res = await fetch('/api/loop_playlist', { method: 'POST' });
|
||||
const data = await res.json();
|
||||
if (!res.ok) throw new Error(data.detail || 'Błąd zapętlania');
|
||||
showToast(data.loop_playlist ? 'Włączono zapętlanie całej kolejki (playlisty)!' : 'Wyłączono zapętlanie kolejki.', 'info');
|
||||
} catch (err) {
|
||||
showToast('Nie udało się zmienić trybu zapętlania', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// Set Volume
|
||||
async function setVolume(vol) {
|
||||
try {
|
||||
|
||||
Reference in new issue
Block a user