download re implemented
This commit is contained in:
@@ -505,19 +505,6 @@ class AniWorldApp {
|
||||
this.hideStatus();
|
||||
});
|
||||
|
||||
// Download controls
|
||||
document.getElementById('pause-download').addEventListener('click', () => {
|
||||
this.pauseDownload();
|
||||
});
|
||||
|
||||
document.getElementById('resume-download').addEventListener('click', () => {
|
||||
this.resumeDownload();
|
||||
});
|
||||
|
||||
document.getElementById('cancel-download').addEventListener('click', () => {
|
||||
this.cancelDownload();
|
||||
});
|
||||
|
||||
// Logout functionality
|
||||
document.getElementById('logout-btn').addEventListener('click', () => {
|
||||
this.logout();
|
||||
@@ -2006,57 +1993,6 @@ class AniWorldApp {
|
||||
}
|
||||
}
|
||||
|
||||
async pauseDownload() {
|
||||
if (!this.isDownloading || this.isPaused) return;
|
||||
|
||||
try {
|
||||
const response = await this.makeAuthenticatedRequest('/api/queue/pause', { method: 'POST' });
|
||||
if (!response) return;
|
||||
const data = await response.json();
|
||||
|
||||
document.getElementById('pause-download').classList.add('hidden');
|
||||
document.getElementById('resume-download').classList.remove('hidden');
|
||||
this.showToast('Queue paused', 'warning');
|
||||
} catch (error) {
|
||||
console.error('Pause error:', error);
|
||||
this.showToast('Failed to pause queue', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
async resumeDownload() {
|
||||
if (!this.isDownloading || !this.isPaused) return;
|
||||
|
||||
try {
|
||||
const response = await this.makeAuthenticatedRequest('/api/queue/resume', { method: 'POST' });
|
||||
if (!response) return;
|
||||
const data = await response.json();
|
||||
|
||||
document.getElementById('pause-download').classList.remove('hidden');
|
||||
document.getElementById('resume-download').classList.add('hidden');
|
||||
this.showToast('Queue resumed', 'success');
|
||||
} catch (error) {
|
||||
console.error('Resume error:', error);
|
||||
this.showToast('Failed to resume queue', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
async cancelDownload() {
|
||||
if (!this.isDownloading) return;
|
||||
|
||||
if (confirm('Are you sure you want to stop the download queue?')) {
|
||||
try {
|
||||
const response = await this.makeAuthenticatedRequest('/api/queue/stop', { method: 'POST' });
|
||||
if (!response) return;
|
||||
const data = await response.json();
|
||||
|
||||
this.showToast('Queue stopped', 'warning');
|
||||
} catch (error) {
|
||||
console.error('Stop error:', error);
|
||||
this.showToast('Failed to stop queue', 'error');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
showDownloadQueue(data) {
|
||||
const queueSection = document.getElementById('download-queue-section');
|
||||
const queueProgress = document.getElementById('queue-progress');
|
||||
|
||||
@@ -6,9 +6,6 @@ class QueueManager {
|
||||
constructor() {
|
||||
this.socket = null;
|
||||
this.refreshInterval = null;
|
||||
this.isReordering = false;
|
||||
this.draggedElement = null;
|
||||
this.draggedId = null;
|
||||
|
||||
this.init();
|
||||
}
|
||||
@@ -19,7 +16,6 @@ class QueueManager {
|
||||
this.initTheme();
|
||||
this.startRefreshTimer();
|
||||
this.loadQueueData();
|
||||
this.initDragAndDrop();
|
||||
}
|
||||
|
||||
initSocket() {
|
||||
@@ -131,10 +127,6 @@ class QueueManager {
|
||||
});
|
||||
|
||||
// Queue management actions
|
||||
document.getElementById('clear-queue-btn').addEventListener('click', () => {
|
||||
this.clearQueue('pending');
|
||||
});
|
||||
|
||||
document.getElementById('clear-completed-btn').addEventListener('click', () => {
|
||||
this.clearQueue('completed');
|
||||
});
|
||||
@@ -149,11 +141,11 @@ class QueueManager {
|
||||
|
||||
// Download controls
|
||||
document.getElementById('start-queue-btn').addEventListener('click', () => {
|
||||
this.startDownloadQueue();
|
||||
this.startDownload();
|
||||
});
|
||||
|
||||
document.getElementById('stop-queue-btn').addEventListener('click', () => {
|
||||
this.stopDownloadQueue();
|
||||
this.stopDownloads();
|
||||
});
|
||||
|
||||
// Modal events
|
||||
@@ -326,23 +318,15 @@ class QueueManager {
|
||||
}
|
||||
|
||||
container.innerHTML = queue.map((item, index) => this.createPendingQueueCard(item, index)).join('');
|
||||
|
||||
// Re-attach drag and drop event listeners
|
||||
this.attachDragListeners();
|
||||
}
|
||||
|
||||
createPendingQueueCard(download, index) {
|
||||
const addedAt = new Date(download.added_at).toLocaleString();
|
||||
const priorityClass = download.priority === 'high' ? 'high-priority' : '';
|
||||
|
||||
return `
|
||||
<div class="download-card pending ${priorityClass} draggable-item"
|
||||
<div class="download-card pending"
|
||||
data-id="${download.id}"
|
||||
data-index="${index}"
|
||||
draggable="true">
|
||||
<div class="drag-handle" title="Drag to reorder">
|
||||
<i class="fas fa-grip-vertical"></i>
|
||||
</div>
|
||||
data-index="${index}">
|
||||
<div class="queue-position">${index + 1}</div>
|
||||
<div class="download-header">
|
||||
<div class="download-info">
|
||||
@@ -351,7 +335,6 @@ class QueueManager {
|
||||
<small>Added: ${addedAt}</small>
|
||||
</div>
|
||||
<div class="download-actions">
|
||||
${download.priority === 'high' ? '<i class="fas fa-arrow-up priority-indicator" title="High Priority"></i>' : ''}
|
||||
<button class="btn btn-small btn-secondary" onclick="queueManager.removeFromQueue('${download.id}')">
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>
|
||||
@@ -470,13 +453,11 @@ class QueueManager {
|
||||
|
||||
async clearQueue(type) {
|
||||
const titles = {
|
||||
pending: 'Clear Queue',
|
||||
completed: 'Clear Completed Downloads',
|
||||
failed: 'Clear Failed Downloads'
|
||||
};
|
||||
|
||||
const messages = {
|
||||
pending: 'Are you sure you want to clear all pending downloads from the queue?',
|
||||
completed: 'Are you sure you want to clear all completed downloads?',
|
||||
failed: 'Are you sure you want to clear all failed downloads?'
|
||||
};
|
||||
@@ -505,26 +486,6 @@ class QueueManager {
|
||||
|
||||
this.showToast(`Cleared ${data.count} failed downloads`, 'success');
|
||||
this.loadQueueData();
|
||||
} else if (type === 'pending') {
|
||||
// Get all pending items
|
||||
const pendingCards = document.querySelectorAll('#pending-queue .download-card.pending');
|
||||
const itemIds = Array.from(pendingCards).map(card => card.dataset.id).filter(id => id);
|
||||
|
||||
if (itemIds.length === 0) {
|
||||
this.showToast('No pending items to clear', 'info');
|
||||
return;
|
||||
}
|
||||
|
||||
const response = await this.makeAuthenticatedRequest('/api/queue/', {
|
||||
method: 'DELETE',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ item_ids: itemIds })
|
||||
});
|
||||
|
||||
if (!response) return;
|
||||
|
||||
this.showToast(`Cleared ${itemIds.length} pending items`, 'success');
|
||||
this.loadQueueData();
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
@@ -617,7 +578,7 @@ class QueueManager {
|
||||
return `${minutes}m ${seconds}s`;
|
||||
}
|
||||
|
||||
async startDownloadQueue() {
|
||||
async startDownload() {
|
||||
try {
|
||||
const response = await this.makeAuthenticatedRequest('/api/queue/start', {
|
||||
method: 'POST'
|
||||
@@ -627,22 +588,24 @@ class QueueManager {
|
||||
const data = await response.json();
|
||||
|
||||
if (data.status === 'success') {
|
||||
this.showToast('Download queue started', 'success');
|
||||
this.showToast('Download started', 'success');
|
||||
|
||||
// Update UI
|
||||
document.getElementById('start-queue-btn').style.display = 'none';
|
||||
document.getElementById('stop-queue-btn').style.display = 'inline-flex';
|
||||
document.getElementById('stop-queue-btn').disabled = false;
|
||||
|
||||
this.loadQueueData(); // Refresh display
|
||||
} else {
|
||||
this.showToast(`Failed to start queue: ${data.message}`, 'error');
|
||||
this.showToast(`Failed to start download: ${data.message || 'Unknown error'}`, 'error');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error starting download queue:', error);
|
||||
this.showToast('Failed to start download queue', 'error');
|
||||
console.error('Error starting download:', error);
|
||||
this.showToast('Failed to start download', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
async stopDownloadQueue() {
|
||||
async stopDownloads() {
|
||||
try {
|
||||
const response = await this.makeAuthenticatedRequest('/api/queue/stop', {
|
||||
method: 'POST'
|
||||
@@ -652,156 +615,20 @@ class QueueManager {
|
||||
const data = await response.json();
|
||||
|
||||
if (data.status === 'success') {
|
||||
this.showToast('Download queue stopped', 'success');
|
||||
this.showToast('Queue processing stopped', 'success');
|
||||
|
||||
// Update UI
|
||||
document.getElementById('stop-queue-btn').style.display = 'none';
|
||||
document.getElementById('start-queue-btn').style.display = 'inline-flex';
|
||||
document.getElementById('start-queue-btn').disabled = false;
|
||||
|
||||
this.loadQueueData(); // Refresh display
|
||||
} else {
|
||||
this.showToast(`Failed to stop queue: ${data.message}`, 'error');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error stopping download queue:', error);
|
||||
this.showToast('Failed to stop download queue', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
initDragAndDrop() {
|
||||
// Initialize drag and drop on the pending queue container
|
||||
const container = document.getElementById('pending-queue');
|
||||
if (container) {
|
||||
container.addEventListener('dragover', this.handleDragOver.bind(this));
|
||||
container.addEventListener('drop', this.handleDrop.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
attachDragListeners() {
|
||||
// Attach listeners to all draggable items
|
||||
const items = document.querySelectorAll('.draggable-item');
|
||||
items.forEach(item => {
|
||||
item.addEventListener('dragstart', this.handleDragStart.bind(this));
|
||||
item.addEventListener('dragend', this.handleDragEnd.bind(this));
|
||||
item.addEventListener('dragenter', this.handleDragEnter.bind(this));
|
||||
item.addEventListener('dragleave', this.handleDragLeave.bind(this));
|
||||
});
|
||||
}
|
||||
|
||||
handleDragStart(e) {
|
||||
this.draggedElement = e.currentTarget;
|
||||
this.draggedId = e.currentTarget.dataset.id;
|
||||
e.currentTarget.classList.add('dragging');
|
||||
e.dataTransfer.effectAllowed = 'move';
|
||||
e.dataTransfer.setData('text/html', e.currentTarget.innerHTML);
|
||||
}
|
||||
|
||||
handleDragEnd(e) {
|
||||
e.currentTarget.classList.remove('dragging');
|
||||
|
||||
// Remove all drag-over classes
|
||||
document.querySelectorAll('.drag-over').forEach(item => {
|
||||
item.classList.remove('drag-over');
|
||||
});
|
||||
}
|
||||
|
||||
handleDragOver(e) {
|
||||
if (e.preventDefault) {
|
||||
e.preventDefault();
|
||||
}
|
||||
e.dataTransfer.dropEffect = 'move';
|
||||
return false;
|
||||
}
|
||||
|
||||
handleDragEnter(e) {
|
||||
if (e.currentTarget.classList.contains('draggable-item') &&
|
||||
e.currentTarget !== this.draggedElement) {
|
||||
e.currentTarget.classList.add('drag-over');
|
||||
}
|
||||
}
|
||||
|
||||
handleDragLeave(e) {
|
||||
e.currentTarget.classList.remove('drag-over');
|
||||
}
|
||||
|
||||
async handleDrop(e) {
|
||||
if (e.stopPropagation) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
e.preventDefault();
|
||||
|
||||
// Get the target element (the item we dropped onto)
|
||||
let target = e.target;
|
||||
while (target && !target.classList.contains('draggable-item')) {
|
||||
target = target.parentElement;
|
||||
if (target === document.getElementById('pending-queue')) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!target || target === this.draggedElement) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get all items to determine new order
|
||||
const container = document.getElementById('pending-queue');
|
||||
const items = Array.from(container.querySelectorAll('.draggable-item'));
|
||||
|
||||
const draggedIndex = items.indexOf(this.draggedElement);
|
||||
const targetIndex = items.indexOf(target);
|
||||
|
||||
if (draggedIndex === targetIndex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Reorder visually
|
||||
if (draggedIndex < targetIndex) {
|
||||
target.parentNode.insertBefore(this.draggedElement, target.nextSibling);
|
||||
} else {
|
||||
target.parentNode.insertBefore(this.draggedElement, target);
|
||||
}
|
||||
|
||||
// Update position numbers
|
||||
const updatedItems = Array.from(container.querySelectorAll('.draggable-item'));
|
||||
updatedItems.forEach((item, index) => {
|
||||
const posElement = item.querySelector('.queue-position');
|
||||
if (posElement) {
|
||||
posElement.textContent = index + 1;
|
||||
}
|
||||
item.dataset.index = index;
|
||||
});
|
||||
|
||||
// Get the new order of IDs
|
||||
const newOrder = updatedItems.map(item => item.dataset.id);
|
||||
|
||||
// Send reorder request to backend
|
||||
await this.reorderQueue(newOrder);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
async reorderQueue(newOrder) {
|
||||
try {
|
||||
const response = await this.makeAuthenticatedRequest('/api/queue/reorder', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ item_ids: newOrder })
|
||||
});
|
||||
|
||||
if (!response) return;
|
||||
|
||||
if (response.ok) {
|
||||
this.showToast('Queue reordered successfully', 'success');
|
||||
} else {
|
||||
const data = await response.json();
|
||||
this.showToast(`Failed to reorder: ${data.detail || 'Unknown error'}`, 'error');
|
||||
// Reload to restore correct order
|
||||
this.loadQueueData();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error reordering queue:', error);
|
||||
this.showToast('Failed to reorder queue', 'error');
|
||||
// Reload to restore correct order
|
||||
this.loadQueueData();
|
||||
console.error('Error stopping queue:', error);
|
||||
this.showToast('Failed to stop queue', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user