/** * Dashboard.js * Este arquivo gerencia toda a interatividade do painel de controle, * incluindo atualizações de status, gerenciamento de velocidades e * controles em massa dos torrents. */ // Aguarda o DOM carregar completamente antes de inicializar document.addEventListener('DOMContentLoaded', function() { // Inicializa os componentes principais initializeClientSelector(); initializeMassControls(); setupSpeedControls(); setupAutoRefresh(); }); /** * Gerenciamento de Clientes * Controla a seleção de clientes e suas versões disponíveis */ function initializeClientSelector() { const clientSelect = document.getElementById('clientSelect'); const versionSelect = document.getElementById('versionSelect'); // Armazena as versões disponíveis para cada cliente const clientVersions = JSON.parse(document.getElementById('client-versions-data').textContent); function updateVersions() { // Limpa as opções atuais versionSelect.innerHTML = ''; const selectedClient = clientSelect.value; if (selectedClient && clientVersions[selectedClient]) { // Adiciona as versões do cliente selecionado clientVersions[selectedClient].versions.forEach(version => { const option = document.createElement('option'); option.value = version; option.textContent = version; versionSelect.appendChild(option); }); // Restaura a versão salva anteriormente, se existir if (window.savedClientVersion) { versionSelect.value = window.savedClientVersion; } } else { // Opção padrão quando nenhum cliente está selecionado const option = document.createElement('option'); option.value = ''; option.textContent = 'Selecione um cliente primeiro'; versionSelect.appendChild(option); } } // Atualiza as versões quando o cliente é alterado clientSelect.addEventListener('change', updateVersions); // Inicialização inicial updateVersions(); } /** * Controles em Massa * Gerencia a seleção e atualização em massa dos torrents */ function initializeMassControls() { const toggleAll = document.getElementById('toggle-all'); if (toggleAll) { toggleAll.addEventListener('change', function(e) { const checkboxes = document.querySelectorAll('.torrent-active'); checkboxes.forEach(checkbox => { checkbox.checked = e.target.checked; updateTorrentStatus(checkbox); }); }); } } /** * Atualização de Status * Gerencia as atualizações individuais de status dos torrents */ function updateTorrentStatus(checkbox) { const hash = checkbox.dataset.hash; const active = checkbox.checked; // Envia atualização para o servidor fetch('/api/update-status.php', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ hash: hash, active: active }) }) .then(response => response.json()) .then(data => { if (data.success) { showNotification('Status atualizado com sucesso', 'success'); } else { showNotification('Erro ao atualizar status', 'error'); // Reverte o checkbox em caso de erro checkbox.checked = !active; } }) .catch(error => { console.error('Erro:', error); showNotification('Erro de conexão', 'error'); checkbox.checked = !active; }); } /** * Controle de Velocidade * Gerencia as atualizações de velocidade dos torrents */ function setupSpeedControls() { document.querySelectorAll('.speed-input').forEach(input => { let originalValue = input.value; input.addEventListener('change', function() { const newValue = this.value; const hash = this.closest('tr').querySelector('.torrent-active').dataset.hash; updateSpeed(hash, newValue) .then(success => { if (success) { originalValue = newValue; showNotification('Velocidade atualizada', 'success'); } else { this.value = originalValue; showNotification('Erro ao atualizar velocidade', 'error'); } }); }); }); } /** * Atualização de Velocidade * Envia a nova velocidade para o servidor */ async function updateSpeed(hash, speed) { try { const response = await fetch('/api/update-speed.php', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ hash: hash, speed: speed }) }); const data = await response.json(); return data.success; } catch (error) { console.error('Erro:', error); return false; } } /** * Sistema de Notificações * Gerencia o feedback visual para o usuário */ function showNotification(message, type = 'info') { const notification = document.createElement('div'); notification.className = `notification ${type}`; notification.textContent = message; document.body.appendChild(notification); // Remove a notificação após 3 segundos setTimeout(() => { notification.classList.add('fade-out'); setTimeout(() => notification.remove(), 300); }, 3000); } /** * Atualização Automática * Atualiza periodicamente as informações do painel */ function setupAutoRefresh() { setInterval(() => { refreshTorrentData(); }, 30000); // Atualiza a cada 30 segundos } /** * Atualização dos Dados * Busca dados atualizados dos torrents */ async function refreshTorrentData() { try { const response = await fetch('/api/get-torrents.php'); const data = await response.json(); if (data.success) { updateTorrentTable(data.torrents); } } catch (error) { console.error('Erro ao atualizar dados:', error); } } /** * Atualização da Tabela * Atualiza a interface com os novos dados */ function updateTorrentTable(torrents) { const tbody = document.querySelector('.torrents-table tbody'); if (!tbody) return; Object.entries(torrents).forEach(([hash, torrent]) => { const row = tbody.querySelector(`tr[data-hash="${hash}"]`); if (row) { // Atualiza os valores existentes row.querySelector('.torrent-upload').textContent = formatBytes(torrent.uploaded); row.querySelector('.torrent-seeders').textContent = torrent.seeders || 0; row.querySelector('.torrent-leechers').textContent = torrent.leechers || 0; } }); } /** * Formatação de Bytes * Converte bytes em formato legível */ function formatBytes(bytes, decimals = 2) { if (bytes === 0) return '0 B'; const k = 1024; const dm = decimals < 0 ? 0 : decimals; const sizes = ['B', 'KB', 'MB', 'GB', 'TB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; }