Add download client ordering and filtering to active downloads list
This commit is contained in:
+78
-9
@@ -1,6 +1,8 @@
|
||||
// Copyright (c) 2026 Gordon Bolton. MIT License.
|
||||
let currentUser = null;
|
||||
let downloads = [];
|
||||
let downloadClients = []; // List of download clients from server (for ordering/filtering)
|
||||
let selectedDownloadClient = localStorage.getItem('sofarr-download-client') || 'all'; // Selected client filter
|
||||
let isAdmin = false;
|
||||
let showAll = false;
|
||||
let csrfToken = null; // double-submit CSRF token, sent as X-CSRF-Token on mutating requests
|
||||
@@ -30,6 +32,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
initThemeSwitcher();
|
||||
initTabs();
|
||||
initHistoryControls();
|
||||
initDownloadClientFilter();
|
||||
initWebhooks();
|
||||
loadAppVersion();
|
||||
|
||||
@@ -118,6 +121,11 @@ function startSSE() {
|
||||
currentUser = data.user;
|
||||
isAdmin = !!data.isAdmin;
|
||||
downloads = data.downloads;
|
||||
// Store download clients and update filter dropdown
|
||||
if (data.downloadClients) {
|
||||
downloadClients = data.downloadClients;
|
||||
updateDownloadClientFilter();
|
||||
}
|
||||
document.getElementById('currentUser').textContent = currentUser || '-';
|
||||
renderDownloads();
|
||||
hideError();
|
||||
@@ -352,28 +360,44 @@ function formatEpisodeInfo(episodes) {
|
||||
function renderDownloads() {
|
||||
const downloadsList = document.getElementById('downloads-list');
|
||||
const noDownloads = document.getElementById('no-downloads');
|
||||
|
||||
if (downloads.length === 0) {
|
||||
|
||||
// Filter downloads by selected client
|
||||
let filteredDownloads = downloads;
|
||||
if (selectedDownloadClient !== 'all') {
|
||||
filteredDownloads = downloads.filter(d => d.instanceId === selectedDownloadClient);
|
||||
}
|
||||
|
||||
// Sort downloads by client order (matching the order in downloadClients)
|
||||
if (downloadClients.length > 0) {
|
||||
const clientOrder = new Map(downloadClients.map((c, idx) => [c.id, idx]));
|
||||
filteredDownloads = [...filteredDownloads].sort((a, b) => {
|
||||
const orderA = clientOrder.get(a.instanceId) ?? Infinity;
|
||||
const orderB = clientOrder.get(b.instanceId) ?? Infinity;
|
||||
return orderA - orderB;
|
||||
});
|
||||
}
|
||||
|
||||
if (filteredDownloads.length === 0) {
|
||||
noDownloads.style.display = 'block';
|
||||
downloadsList.innerHTML = '';
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
noDownloads.style.display = 'none';
|
||||
|
||||
|
||||
// Get existing cards
|
||||
const existingCards = new Map();
|
||||
downloadsList.querySelectorAll('.download-card').forEach(card => {
|
||||
existingCards.set(card.dataset.id, card);
|
||||
});
|
||||
|
||||
|
||||
// Track which downloads we've processed
|
||||
const processedIds = new Set();
|
||||
|
||||
downloads.forEach(download => {
|
||||
|
||||
filteredDownloads.forEach(download => {
|
||||
const id = download.title;
|
||||
processedIds.add(id);
|
||||
|
||||
|
||||
const existingCard = existingCards.get(id);
|
||||
if (existingCard) {
|
||||
// Update existing card
|
||||
@@ -384,7 +408,7 @@ function renderDownloads() {
|
||||
downloadsList.appendChild(card);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Remove cards for downloads that no longer exist
|
||||
existingCards.forEach((card, id) => {
|
||||
if (!processedIds.has(id)) {
|
||||
@@ -1022,6 +1046,51 @@ function initHistoryControls() {
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Download Client Filter
|
||||
// =============================================================================
|
||||
|
||||
function initDownloadClientFilter() {
|
||||
const filterSelect = document.getElementById('download-client-filter');
|
||||
if (filterSelect) {
|
||||
// Set initial value from localStorage
|
||||
filterSelect.value = selectedDownloadClient;
|
||||
filterSelect.addEventListener('change', () => {
|
||||
selectedDownloadClient = filterSelect.value;
|
||||
localStorage.setItem('sofarr-download-client', selectedDownloadClient);
|
||||
renderDownloads();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function updateDownloadClientFilter() {
|
||||
const filterSelect = document.getElementById('download-client-filter');
|
||||
if (!filterSelect || downloadClients.length === 0) return;
|
||||
|
||||
// Save current selection
|
||||
const currentValue = filterSelect.value;
|
||||
|
||||
// Clear existing options (except "All clients")
|
||||
filterSelect.innerHTML = '<option value="all">All clients</option>';
|
||||
|
||||
// Add options for each download client
|
||||
downloadClients.forEach(client => {
|
||||
const option = document.createElement('option');
|
||||
option.value = client.id;
|
||||
option.textContent = client.name;
|
||||
filterSelect.appendChild(option);
|
||||
});
|
||||
|
||||
// Restore selection if still valid, otherwise default to 'all'
|
||||
if (currentValue && (currentValue === 'all' || downloadClients.some(c => c.id === currentValue))) {
|
||||
filterSelect.value = currentValue;
|
||||
} else {
|
||||
filterSelect.value = 'all';
|
||||
selectedDownloadClient = 'all';
|
||||
localStorage.setItem('sofarr-download-client', 'all');
|
||||
}
|
||||
}
|
||||
|
||||
function startHistoryRefresh() {
|
||||
stopHistoryRefresh();
|
||||
historyRefreshHandle = setInterval(() => loadHistory(), HISTORY_REFRESH_MS);
|
||||
|
||||
Reference in New Issue
Block a user