/* ============================================ CONFIG (vem do PHP via window.FM_CONFIG) ============================================ */ const BASE_URL = window.FM_CONFIG?.baseUrl || '?dir='; /* ============================================ ESTADO GLOBAL ============================================ */ let selectedItems = new Set(); let currentCopyAction = 'copy_to'; let editorOriginalContent = ''; /* ============================================ NAVEGAÇÃO ENTRE TABS ============================================ */ function showTab(id, btn) { document.querySelectorAll('.tab-content').forEach(t => t.classList.remove('active')); document.querySelectorAll('.tab-button').forEach(b => b.classList.remove('active')); document.getElementById(id).classList.add('active'); if (btn) btn.classList.add('active'); } /* ============================================ MODAIS ============================================ */ function openModal(id) { document.getElementById(id).classList.add('active'); } function closeModal(id) { document.getElementById(id).classList.remove('active'); } document.addEventListener('click', function(e) { if (e.target.classList.contains('modal')) { e.target.classList.remove('active'); } }); document.addEventListener('keydown', function(e) { if (e.key === 'Escape') { document.querySelectorAll('.modal.active').forEach(m => m.classList.remove('active')); } }); /* ============================================ SELEÇÃO MÚLTIPLA ============================================ */ function toggleSelectAll(src) { document.querySelectorAll('.item-checkbox').forEach(cb => { cb.checked = src.checked; if (src.checked) selectedItems.add(cb.value); else selectedItems.delete(cb.value); }); updateSelectionBar(); updateRowHighlight(); } function toggleItem(cb) { if (cb.checked) selectedItems.add(cb.value); else selectedItems.delete(cb.value); updateSelectionBar(); updateRowHighlight(); updateSelectAll(); } function updateSelectAll() { const all = document.querySelectorAll('.item-checkbox'); const sa = document.getElementById('select-all'); if (!sa) return; sa.checked = all.length > 0 && selectedItems.size === all.length; sa.indeterminate = selectedItems.size > 0 && selectedItems.size < all.length; } function updateSelectionBar() { const bar = document.getElementById('selection-bar'); const counter = document.getElementById('selection-count'); if (!bar) return; if (counter) counter.textContent = selectedItems.size; bar.classList.toggle('active', selectedItems.size > 0); } function updateRowHighlight() { document.querySelectorAll('.file-row').forEach(row => { const cb = row.querySelector('.item-checkbox'); row.classList.toggle('selected', cb && cb.checked); }); } /* ============================================ AÇÕES EM LOTE ============================================ */ function downloadSelected() { if (selectedItems.size === 0) return alert('Selecione itens'); document.getElementById('download-items-input').value = Array.from(selectedItems).join(','); document.getElementById('download-form').submit(); } function compressSelected() { if (selectedItems.size === 0) return alert('Selecione itens'); if (!confirm('Compactar ' + selectedItems.size + ' item(ns)?')) return; document.getElementById('compress-items-input').value = Array.from(selectedItems).join(','); document.getElementById('compress-form').submit(); } function deleteSelected() { if (selectedItems.size === 0) return alert('Selecione itens'); if (!confirm('Deletar ' + selectedItems.size + ' item(ns)? Esta ação não pode ser desfeita!')) return; document.getElementById('delete-items-input').value = Array.from(selectedItems).join(','); document.getElementById('delete-form').submit(); } /* ============================================ COPIAR / MOVER ============================================ */ function openCopyModal(action) { if (selectedItems.size === 0) return alert('Selecione itens'); currentCopyAction = action; document.getElementById('copy-modal-title').textContent = action === 'copy_to' ? '📋 Copiar para' : '📦 Mover para'; document.getElementById('copy-action-input').value = action; document.getElementById('copy-items-input').value = Array.from(selectedItems).join(','); document.getElementById('copy-dest-field').value = ''; document.getElementById('copy-selected').textContent = '/'; openModal('modal-copy'); } function pickTreeDir(path, el) { document.getElementById('copy-dest-field').value = path; document.getElementById('copy-selected').textContent = path || '/'; } function submitCopy() { const dest = document.getElementById('copy-dest-field').value.trim(); document.getElementById('copy-dest-input').value = dest; document.getElementById('copy-form').submit(); } /* ============================================ RENOMEAR ============================================ */ function renameItem(name) { document.getElementById('rename-old').value = name; document.getElementById('rename-new').value = name; openModal('modal-rename'); setTimeout(() => { const inp = document.getElementById('rename-new'); inp.focus(); const dot = name.lastIndexOf('.'); if (dot > 0) inp.setSelectionRange(0, dot); else inp.select(); }, 100); } /* ============================================ CHMOD ============================================ */ function chmodItem(name, current) { document.getElementById('chmod-item').value = name; document.getElementById('chmod-mode').value = current; openModal('modal-chmod'); } /* ============================================ VISUALIZAR IMAGEM ============================================ */ function openImage(name) { document.getElementById('image-title').textContent = '🖼️ ' + name; document.getElementById('image-preview').src = BASE_URL + '&raw=' + encodeURIComponent(name); openModal('modal-image'); } /* ============================================ EDITOR DE CÓDIGO ============================================ */ function openEditor(name) { document.getElementById('editor-title').textContent = '✏️ ' + name; document.getElementById('editor-filename').value = name; document.getElementById('editor-textarea').value = 'Carregando...'; document.getElementById('editor-info').textContent = ''; openModal('modal-editor'); fetch(BASE_URL + '&raw=' + encodeURIComponent(name) + '&_t=' + Date.now()) .then(r => { if (!r.ok) throw new Error('HTTP ' + r.status); return r.text(); }) .then(text => { editorOriginalContent = text; const ta = document.getElementById('editor-textarea'); ta.value = text; updateLineNumbers(); document.getElementById('editor-info').textContent = 'Linhas: ' + text.split('\n').length + ' | Caracteres: ' + text.length; }) .catch(err => { document.getElementById('editor-textarea').value = '// Erro ao carregar arquivo: ' + err.message; document.getElementById('editor-info').textContent = '❌ Falha ao carregar'; }); } function updateLineNumbers() { const ta = document.getElementById('editor-textarea'); const lines = ta.value.split('\n').length; let html = ''; for (let i = 1; i <= lines; i++) html += i + '\n'; document.getElementById('line-numbers').textContent = html; } function syncScroll() { const ta = document.getElementById('editor-textarea'); const ln = document.getElementById('line-numbers'); if (ln) ln.scrollTop = ta.scrollTop; } document.addEventListener('DOMContentLoaded', function() { const ta = document.getElementById('editor-textarea'); if (!ta) return; ta.addEventListener('keydown', function(e) { if ((e.ctrlKey || e.metaKey) && e.key === 's') { e.preventDefault(); document.getElementById('editor-form').submit(); } if (e.key === 'Tab') { e.preventDefault(); const start = this.selectionStart; const end = this.selectionEnd; this.value = this.value.substring(0, start) + '\t' + this.value.substring(end); this.selectionStart = this.selectionEnd = start + 1; updateLineNumbers(); } }); }); /* ============================================ UTILITÁRIOS ============================================ */ function copyPath(path) { navigator.clipboard.writeText(path).then(() => { const btn = event.target; const old = btn.textContent; btn.textContent = '✅'; setTimeout(() => btn.textContent = old, 1000); }); } function filterRows(query) { query = query.toLowerCase().trim(); document.querySelectorAll('.file-row').forEach(row => { const name = row.getAttribute('data-name') || ''; row.style.display = (!query || name.includes(query)) ? '' : 'none'; }); } function toggleTreeNode(el) { const div = el.nextElementSibling; if (div && div.tagName === 'DIV' && div.classList.contains('tree-children')) { div.style.display = div.style.display === 'none' ? 'block' : 'none'; } } /* ============================================ INICIALIZAÇÃO ============================================ */ window.addEventListener('load', function() { updateSelectionBar(); updateSelectAll(); });