// DOM Elements
const uploadBox = document.getElementById('uploadBox');
const imageInput = document.getElementById('imageInput');
const denoiseBtn = document.getElementById('denoiseBtn');
const resultsSection = document.getElementById('resultsSection');
const loading = document.getElementById('loading');
const error = document.getElementById('error');
const originalImg = document.getElementById('originalImg');
const denoisedImg = document.getElementById('denoisedImg');
const samplesGrid = document.getElementById('samplesGrid');
let selectedFile = null;
// ── Load sample images on page load ──────────────────────────────────────────
async function loadSamples() {
try {
const res = await fetch('/api/samples');
const samples = await res.json();
samplesGrid.innerHTML = '';
samples.forEach(s => {
const card = document.createElement('div');
card.className = 'sample-card';
card.innerHTML = `
${s.label}
`;
card.addEventListener('click', () => denoiseSample(s.filename, card));
samplesGrid.appendChild(card);
});
} catch (e) {
samplesGrid.innerHTML = '
Could not load samples.
'; } } async function denoiseSample(filename, card) { // Highlight selected card document.querySelectorAll('.sample-card').forEach(c => c.classList.remove('active')); card.classList.add('active'); showLoading(); hideError(); try { const res = await fetch('/api/denoise-sample', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ filename }) }); const data = await res.json(); if (!res.ok) throw new Error(data.error || 'Failed'); showResults(data.original, data.denoised); } catch (err) { hideLoading(); showError(err.message); } } // ── Upload flow ─────────────────────────────────────────────────────────────── uploadBox.addEventListener('click', () => imageInput.click()); imageInput.addEventListener('change', (e) => handleFile(e.target.files[0])); uploadBox.addEventListener('dragover', (e) => { e.preventDefault(); uploadBox.classList.add('dragover'); }); uploadBox.addEventListener('dragleave', () => uploadBox.classList.remove('dragover')); uploadBox.addEventListener('drop', (e) => { e.preventDefault(); uploadBox.classList.remove('dragover'); handleFile(e.dataTransfer.files[0]); }); function handleFile(file) { if (!file) return; if (!file.type.startsWith('image/')) { showError('Please upload an image file'); return; } selectedFile = file; denoiseBtn.disabled = false; const uploadContent = uploadBox.querySelector('.upload-content'); uploadContent.innerHTML = `${file.name}
Click to change file `; hideError(); resultsSection.style.display = 'none'; } denoiseBtn.addEventListener('click', async () => { if (!selectedFile) return; showLoading(); hideError(); denoiseBtn.disabled = true; const formData = new FormData(); formData.append('image', selectedFile); try { const res = await fetch('/denoise', { method: 'POST', body: formData }); const data = await res.json(); if (!res.ok) throw new Error(data.error || 'Failed to denoise image'); showResults(data.original, data.denoised); denoiseBtn.disabled = false; } catch (err) { hideLoading(); showError(err.message); denoiseBtn.disabled = false; } }); // ── Helpers ─────────────────────────────────────────────────────────────────── function showResults(original, denoised) { originalImg.src = original; denoisedImg.src = denoised; hideLoading(); resultsSection.style.display = 'block'; resultsSection.scrollIntoView({ behavior: 'smooth' }); } function showLoading() { loading.style.display = 'block'; resultsSection.style.display = 'none'; } function hideLoading() { loading.style.display = 'none'; } function showError(message) { error.textContent = message; error.style.display = 'block'; setTimeout(hideError, 5000); } function hideError() { error.style.display = 'none'; } // Init loadSamples();