Spaces:
Runtime error
Runtime error
File size: 4,374 Bytes
0ae8ecd | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | document.addEventListener("DOMContentLoaded", () => {
// 1. Exact DOM Elements matching your index.html
const imageInput = document.getElementById("imageInput");
const analyzeBtn = document.getElementById("analyzeBtn");
const removeBtn = document.getElementById("removeBtn");
const imagePreview = document.getElementById("imagePreview");
const uploadState = document.getElementById("uploadState");
const previewState = document.getElementById("previewState");
const resultCard = document.getElementById("resultCard");
const predictionOutput = document.getElementById("predictionOutput");
const detectorForm = document.getElementById("detectorForm");
// 2. Image Selection & UI Toggling Logic
imageInput.addEventListener("change", function() {
const file = this.files[0];
if (file) {
const reader = new FileReader();
reader.onload = function(e) {
// Show the preview, hide the upload button
imagePreview.src = e.target.result;
uploadState.classList.add("hidden");
previewState.classList.remove("hidden");
// Enable the Analyze button
analyzeBtn.disabled = false;
// Hide any previous results
resultCard.classList.add("hidden");
}
reader.readAsDataURL(file);
}
});
// 3. Remove Image Logic
removeBtn.addEventListener("click", function(e) {
e.preventDefault();
// Reset the input
imageInput.value = "";
imagePreview.src = "";
// Swap the UI back to upload mode
previewState.classList.add("hidden");
uploadState.classList.remove("hidden");
// Disable the Analyze button again
analyzeBtn.disabled = true;
// Hide results
resultCard.classList.add("hidden");
});
// 4. API Communication (The Core Connection)
detectorForm.addEventListener("submit", async function(e) {
e.preventDefault();
if (!imageInput.files || imageInput.files.length === 0) {
alert("Please select an image first.");
return;
}
const file = imageInput.files[0];
const formData = new FormData();
// 'image' key exactly matches app.py
formData.append("image", file);
// UI Loading State
const originalText = analyzeBtn.innerText;
analyzeBtn.innerText = "Extracting Frequencies...";
analyzeBtn.disabled = true;
try {
const response = await fetch("/api/v1/detect", {
method: "POST",
body: formData
});
if (!response.ok) {
throw new Error(`Server returned ${response.status}`);
}
const data = await response.json();
if (data.status === "success") {
// Show the result card
resultCard.classList.remove("hidden");
// Format the output elegantly
const confPercentage = (data.confidence * 100).toFixed(2);
predictionOutput.innerHTML = `
<strong>Detected Class:</strong> ${data.prediction} <br>
<strong>Confidence:</strong> ${confPercentage}% <br>
<hr style="border: 0; border-top: 1px solid #ccc; margin: 10px 0;">
<small>
Clean: ${(data.distribution.Clean * 100).toFixed(1)}% |
Marked: ${(data.distribution.Marked * 100).toFixed(1)}% |
Scrubbed: ${(data.distribution.Scrubbed * 100).toFixed(1)}%
</small>
`;
} else {
throw new Error(data.error);
}
} catch (error) {
console.error("Detection Failed:", error);
alert("Failed to connect to backend. Make sure app.py is running!");
} finally {
// Restore button state
analyzeBtn.innerText = originalText;
analyzeBtn.disabled = false;
}
});
}); |