Spaces:
Running
Running
| document.addEventListener('DOMContentLoaded', () => { | |
| const dropZone = document.getElementById('drop-zone'); | |
| const fileInput = document.getElementById('file-input'); | |
| const analyzeBtn = document.getElementById('analyze-btn'); | |
| const fileInfo = document.getElementById('file-info'); | |
| const filenameDisplay = document.getElementById('filename-display'); | |
| const removeFileBtn = document.getElementById('remove-file'); | |
| const uploadContent = document.querySelector('.upload-content'); | |
| const loading = document.getElementById('loading'); | |
| const results = document.getElementById('results'); | |
| const resultImg = document.getElementById('result-img'); | |
| const resultVid = document.getElementById('result-vid'); | |
| const totalCount = document.getElementById('total-count'); | |
| const objectList = document.getElementById('object-list'); | |
| const downloadBtn = document.getElementById('download-btn'); | |
| let selectedFile = null; | |
| // Handle Click to Upload | |
| dropZone.addEventListener('click', () => fileInput.click()); | |
| fileInput.addEventListener('change', (e) => { | |
| if (e.target.files.length > 0) { | |
| handleFile(e.target.files[0]); | |
| } | |
| }); | |
| // Handle Drag & Drop | |
| dropZone.addEventListener('dragover', (e) => { | |
| e.preventDefault(); | |
| dropZone.classList.add('dragover'); | |
| }); | |
| dropZone.addEventListener('dragleave', () => { | |
| dropZone.classList.remove('dragover'); | |
| }); | |
| dropZone.addEventListener('drop', (e) => { | |
| e.preventDefault(); | |
| dropZone.classList.remove('dragover'); | |
| if (e.dataTransfer.files.length > 0) { | |
| handleFile(e.dataTransfer.files[0]); | |
| } | |
| }); | |
| function handleFile(file) { | |
| selectedFile = file; | |
| filenameDisplay.textContent = file.name; | |
| fileInfo.style.display = 'flex'; | |
| uploadContent.style.display = 'none'; | |
| analyzeBtn.disabled = false; | |
| // Reset results display | |
| results.style.display = 'none'; | |
| resultImg.style.display = 'none'; | |
| resultVid.style.display = 'none'; | |
| } | |
| removeFileBtn.addEventListener('click', (e) => { | |
| e.stopPropagation(); | |
| selectedFile = null; | |
| fileInput.value = ''; | |
| fileInfo.style.display = 'none'; | |
| uploadContent.style.display = 'block'; | |
| analyzeBtn.disabled = true; | |
| }); | |
| analyzeBtn.addEventListener('click', async () => { | |
| if (!selectedFile) return; | |
| const formData = new FormData(); | |
| formData.append('file', selectedFile); | |
| // Show loading | |
| loading.style.display = 'block'; | |
| analyzeBtn.disabled = true; | |
| results.style.display = 'none'; | |
| try { | |
| const response = await fetch('/detect', { | |
| method: 'POST', | |
| body: formData | |
| }); | |
| const data = await response.json(); | |
| if (data.success) { | |
| displayResults(data); | |
| } else { | |
| alert('Analysis failed: ' + (data.error || 'Unknown error')); | |
| } | |
| } catch (error) { | |
| console.error('Error:', error); | |
| alert('An error occurred during analysis.'); | |
| } finally { | |
| loading.style.display = 'none'; | |
| analyzeBtn.disabled = false; | |
| } | |
| }); | |
| function displayResults(data) { | |
| results.style.display = 'block'; | |
| // Show Image or Video preview | |
| if (data.type === 'image') { | |
| resultImg.src = data.result_url + '?t=' + new Date().getTime(); // Prevent caching | |
| resultImg.style.display = 'block'; | |
| resultVid.style.display = 'none'; | |
| totalCount.textContent = data.total_count; | |
| // Build object list | |
| objectList.innerHTML = ''; | |
| for (const [name, count] of Object.entries(data.counts)) { | |
| const item = document.createElement('div'); | |
| item.className = 'object-item'; | |
| item.innerHTML = ` | |
| <span class="obj-name">${name}</span> | |
| <span class="obj-count">${count}</span> | |
| `; | |
| objectList.innerHTML += item.outerHTML; | |
| } | |
| } else { | |
| resultVid.src = data.result_url; | |
| resultVid.style.display = 'block'; | |
| resultImg.style.display = 'none'; | |
| totalCount.textContent = '-'; // Video counts are harder to aggregate simply | |
| objectList.innerHTML = '<p style="color: var(--text-dim)">Summary detection for video complete. Check video for visual bounding boxes.</p>'; | |
| } | |
| downloadBtn.href = data.result_url; | |
| // Scroll to results | |
| results.scrollIntoView({ behavior: 'smooth' }); | |
| } | |
| }); | |