diff --git a/bot.py b/bot.py
index 83b425b..1773eba 100644
--- a/bot.py
+++ b/bot.py
@@ -599,19 +599,27 @@ class MusicBot(commands.Cog):
ephemeral=True
)
- @app_commands.command(name="loop", description="Włącz/wyłącz zapętlanie aktualnego utworu")
+ @app_commands.command(name="loop", description="Zmień tryb zapętlania (Wyłączone -> Cała kolejka -> Jeden utwór)")
async def loop_command(self, interaction: discord.Interaction):
- """Włącz/wyłącz zapętlanie aktualnego utworu"""
+ """Zmień tryb zapętlania jak w YT Music/Spotify"""
guild_id = interaction.guild.id
- loop_current = not self.get_loop_current(guild_id)
- self.set_loop_current(guild_id, loop_current)
- if loop_current:
+ loop_current = self.get_loop_current(guild_id)
+ loop_pl = self.get_loop_playlist(guild_id)
+
+ if not loop_current and not loop_pl:
+ self.set_loop_playlist(guild_id, True)
+ self.set_loop_current(guild_id, False)
+ msg = "🔁 Tryb zapętlania: **Cała kolejka (playlista)**"
+ elif loop_pl and not loop_current:
self.set_loop_playlist(guild_id, False)
- state = "włączone" if loop_current else "wyłączone"
- await interaction.response.send_message(
- f"Zapętlanie aktualnego utworu zostało {state}.",
- ephemeral=False
- )
+ self.set_loop_current(guild_id, True)
+ msg = "🔂 Tryb zapętlania: **Jeden utwór**"
+ else:
+ self.set_loop_playlist(guild_id, False)
+ self.set_loop_current(guild_id, False)
+ msg = "➡️ Tryb zapętlania: **Wyłączone**"
+
+ await interaction.response.send_message(msg, ephemeral=False)
@app_commands.command(name="loopplaylist", description="Włącz/wyłącz zapętlanie całej kolejki (tryb playlisty)")
async def loopplaylist_command(self, interaction: discord.Interaction):
diff --git a/static/app.js b/static/app.js
index 6b21c63..c8772b6 100644
--- a/static/app.js
+++ b/static/app.js
@@ -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 = '';
+ 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 = ' Zapętlenie utworu';
+ } else if (loopMode === 'playlist') {
+ btnLoop.innerHTML = '';
+ 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 = ' Zapętlenie kolejki';
} else {
- btnLoopPlaylist.classList.remove('active');
- btnLoopPlaylist.style.background = '';
- btnLoopPlaylist.style.color = '';
+ btnLoop.innerHTML = '';
+ 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 {
diff --git a/static/index.html b/static/index.html
index c8b78bd..2febe77 100644
--- a/static/index.html
+++ b/static/index.html
@@ -112,10 +112,7 @@
-
-