feat: dodanie mechanizmu limitu odtworzeń (TTL) w kolejce oraz konfiguracji w UI i na Discordzie
This commit is contained in:
5 files changed
+218
-9
No files matched your search
+79
-2
@@ -175,6 +175,30 @@ function bindEvents() {
|
||||
if (e.target === settingsModal) closeSettingsModal();
|
||||
});
|
||||
}
|
||||
|
||||
const btnSaveDefaultPlays = document.getElementById('btn-save-default-plays');
|
||||
if (btnSaveDefaultPlays) {
|
||||
btnSaveDefaultPlays.addEventListener('click', async () => {
|
||||
const inputDefaultPlays = document.getElementById('setting-default-plays');
|
||||
if (!inputDefaultPlays) return;
|
||||
const val = parseInt(inputDefaultPlays.value, 10);
|
||||
if (isNaN(val) || val < 1 || val > 999) {
|
||||
showToast('Wartość musi być z przedziału 1-999', 'error');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const res = await fetch('/api/settings/default_plays', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ default_plays: val })
|
||||
});
|
||||
if (!res.ok) throw new Error('Failed to save setting');
|
||||
showToast(`Domyślna liczba odtworzeń: ${val}`, 'success');
|
||||
} catch (err) {
|
||||
showToast('Błąd zapisu ustawienia', 'error');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Uploads Modal Events
|
||||
if (btnOpenAllUploads) btnOpenAllUploads.addEventListener('click', openUploadsModal);
|
||||
@@ -271,6 +295,7 @@ function updateProgressBar() {
|
||||
|
||||
// Update UI States
|
||||
function updateUI(status) {
|
||||
currentStatus = status;
|
||||
// 1. Connection Status & Available Channels
|
||||
if (status.active_voice_channel) {
|
||||
statusDot.className = 'status-indicator online';
|
||||
@@ -320,6 +345,12 @@ function updateUI(status) {
|
||||
if (status.guilds) {
|
||||
renderSettingsGuilds(status.guilds);
|
||||
}
|
||||
if (status.default_plays !== undefined) {
|
||||
const inputDefaultPlays = document.getElementById('setting-default-plays');
|
||||
if (inputDefaultPlays && document.activeElement !== inputDefaultPlays) {
|
||||
inputDefaultPlays.value = status.default_plays;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Playback State
|
||||
if (status.current) {
|
||||
@@ -422,8 +453,8 @@ function updateUI(status) {
|
||||
}
|
||||
}
|
||||
|
||||
// 6. Queue render (if not currently dragging)
|
||||
if (!isDragging) {
|
||||
// 6. Queue render (if not currently dragging and not editing track plays input)
|
||||
if (!isDragging && (!document.activeElement || !document.activeElement.classList.contains('track-plays-input'))) {
|
||||
renderQueue(status.queue, status.queue_index);
|
||||
renderHistory(status.history || []);
|
||||
}
|
||||
@@ -471,6 +502,13 @@ function renderQueue(queue, queueIndex = -1) {
|
||||
${indexHtml}
|
||||
<div class="queue-track-info">
|
||||
<div class="queue-track-title" title="${track.title}">${track.title}</div>
|
||||
<div class="track-plays-control" style="display: flex; align-items: center; gap: 6px; font-size: 0.75rem; background: rgba(255,255,255,0.06); padding: 3px 10px; border-radius: 12px; margin-top: 6px; width: fit-content; border: 1px solid rgba(255,255,255,0.1);">
|
||||
<i data-lucide="repeat" style="width: 13px; height: 13px; opacity: 0.9; color: var(--primary);"></i>
|
||||
<span title="Pozostało odtworzeń z kolejki" style="color: var(--text-muted);">Pozostało:</span>
|
||||
<button class="btn-tiny-action" onclick="changeTrackPlays('${track.id}', -1)" title="Zmniejsz o 1" style="background: rgba(255,255,255,0.12); border: none; color: inherit; cursor: pointer; padding: 2px 6px; border-radius: 6px; margin-left: 2px; transition: background 0.2s;"><i data-lucide="minus" style="width: 11px; height: 11px;"></i></button>
|
||||
<input type="number" class="track-plays-input" min="1" max="999" value="${track.plays_left !== undefined ? track.plays_left : (currentStatus && currentStatus.default_plays ? currentStatus.default_plays : 5)}" onchange="changeTrackPlaysDirect('${track.id}', this.value)" style="width: 44px; text-align: center; background: rgba(0,0,0,0.35); border: 1px solid rgba(255,255,255,0.2); color: #fff; border-radius: 6px; padding: 2px 4px; font-size: 0.8rem; font-weight: bold;">
|
||||
<button class="btn-tiny-action" onclick="changeTrackPlays('${track.id}', 1)" title="Zwiększ o 1" style="background: rgba(255,255,255,0.12); border: none; color: inherit; cursor: pointer; padding: 2px 6px; border-radius: 6px; transition: background 0.2s;"><i data-lucide="plus" style="width: 11px; height: 11px;"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="queue-item-actions">
|
||||
<button class="btn-action-icon" onclick="jumpToTrack(${idx})" title="Odtwarzaj od tej pozycji">
|
||||
@@ -851,6 +889,45 @@ async function saveGuildLogChannel(guildId, channelId) {
|
||||
}
|
||||
}
|
||||
|
||||
async function changeTrackPlays(trackId, delta) {
|
||||
if (!currentStatus || !currentStatus.queue) return;
|
||||
const track = currentStatus.queue.find(t => t.id === trackId);
|
||||
if (!track) return;
|
||||
const currentPlays = track.plays_left !== undefined ? track.plays_left : (currentStatus.default_plays || 5);
|
||||
const newPlays = Math.max(1, Math.min(999, currentPlays + delta));
|
||||
if (newPlays === currentPlays) return;
|
||||
try {
|
||||
const res = await fetch('/api/queue/plays', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ id: trackId, plays: newPlays })
|
||||
});
|
||||
if (!res.ok) throw new Error('Failed to update plays');
|
||||
} catch (err) {
|
||||
showToast('Błąd aktualizacji odtworzeń', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
async function changeTrackPlaysDirect(trackId, val) {
|
||||
const newPlays = parseInt(val, 10);
|
||||
if (isNaN(newPlays) || newPlays < 1 || newPlays > 999) {
|
||||
showToast('Wartość musi być z przedziału 1-999', 'error');
|
||||
if (currentStatus) renderQueue(currentStatus.queue, currentStatus.queue_index);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const res = await fetch('/api/queue/plays', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ id: trackId, plays: newPlays })
|
||||
});
|
||||
if (!res.ok) throw new Error('Failed to update plays');
|
||||
} catch (err) {
|
||||
showToast('Błąd aktualizacji odtworzeń', 'error');
|
||||
if (currentStatus) renderQueue(currentStatus.queue, currentStatus.queue_index);
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch Uploaded Files
|
||||
async function fetchUploads() {
|
||||
try {
|
||||
|
||||
Reference in new issue
Block a user