Spaces:
Running
Running
Improve report form: video support, expanded reasons with detail fields, professional disclaimer wording, motion blur limitation
Browse files- app/main.py +11 -8
- app/static/index.html +102 -39
app/main.py
CHANGED
|
@@ -136,24 +136,25 @@ async def report(
|
|
| 136 |
is_real: str = Form(...),
|
| 137 |
reason: str = Form(...),
|
| 138 |
reason_other: str = Form(""),
|
|
|
|
| 139 |
comment: str = Form(""),
|
| 140 |
p_fake: float = Form(...),
|
| 141 |
consent: str = Form(...),
|
| 142 |
):
|
| 143 |
-
"""Save an error report (form answers +
|
| 144 |
if consent != "true":
|
| 145 |
-
raise HTTPException(400, "
|
| 146 |
|
| 147 |
if not HF_TOKEN:
|
| 148 |
raise HTTPException(
|
| 149 |
503, "Reporting is not configured (missing HF_TOKEN)."
|
| 150 |
)
|
| 151 |
|
| 152 |
-
# Read the uploaded
|
| 153 |
raw = await file.read()
|
| 154 |
content_type = (file.content_type or "").lower()
|
| 155 |
-
if content_type not in IMAGE_TYPES:
|
| 156 |
-
raise HTTPException(415, "
|
| 157 |
|
| 158 |
# Build report payload
|
| 159 |
ts = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H-%M-%S")
|
|
@@ -165,8 +166,10 @@ async def report(
|
|
| 165 |
"is_real": is_real,
|
| 166 |
"reason": reason,
|
| 167 |
"reason_other": reason_other if reason == "other" else "",
|
|
|
|
| 168 |
"comment": comment,
|
| 169 |
"p_fake": p_fake,
|
|
|
|
| 170 |
"original_filename": file.filename or "unknown",
|
| 171 |
}
|
| 172 |
|
|
@@ -180,9 +183,9 @@ async def report(
|
|
| 180 |
json.dumps(report_data, indent=2, ensure_ascii=False)
|
| 181 |
)
|
| 182 |
|
| 183 |
-
# Save
|
| 184 |
-
ext = Path(file.filename or "
|
| 185 |
-
(report_dir / f"
|
| 186 |
|
| 187 |
# Upload to HF dataset repo
|
| 188 |
try:
|
|
|
|
| 136 |
is_real: str = Form(...),
|
| 137 |
reason: str = Form(...),
|
| 138 |
reason_other: str = Form(""),
|
| 139 |
+
reason_details: str = Form(""),
|
| 140 |
comment: str = Form(""),
|
| 141 |
p_fake: float = Form(...),
|
| 142 |
consent: str = Form(...),
|
| 143 |
):
|
| 144 |
+
"""Save an error report (form answers + media file) to a Hugging Face dataset repo."""
|
| 145 |
if consent != "true":
|
| 146 |
+
raise HTTPException(400, "Consent to save the file is required.")
|
| 147 |
|
| 148 |
if not HF_TOKEN:
|
| 149 |
raise HTTPException(
|
| 150 |
503, "Reporting is not configured (missing HF_TOKEN)."
|
| 151 |
)
|
| 152 |
|
| 153 |
+
# Read the uploaded file
|
| 154 |
raw = await file.read()
|
| 155 |
content_type = (file.content_type or "").lower()
|
| 156 |
+
if content_type not in IMAGE_TYPES | VIDEO_TYPES:
|
| 157 |
+
raise HTTPException(415, "Unsupported file type for reporting.")
|
| 158 |
|
| 159 |
# Build report payload
|
| 160 |
ts = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H-%M-%S")
|
|
|
|
| 166 |
"is_real": is_real,
|
| 167 |
"reason": reason,
|
| 168 |
"reason_other": reason_other if reason == "other" else "",
|
| 169 |
+
"reason_details": reason_details,
|
| 170 |
"comment": comment,
|
| 171 |
"p_fake": p_fake,
|
| 172 |
+
"content_type": content_type,
|
| 173 |
"original_filename": file.filename or "unknown",
|
| 174 |
}
|
| 175 |
|
|
|
|
| 183 |
json.dumps(report_data, indent=2, ensure_ascii=False)
|
| 184 |
)
|
| 185 |
|
| 186 |
+
# Save media file with original extension
|
| 187 |
+
ext = Path(file.filename or "file.bin").suffix or ".bin"
|
| 188 |
+
(report_dir / f"media{ext}").write_bytes(raw)
|
| 189 |
|
| 190 |
# Upload to HF dataset repo
|
| 191 |
try:
|
app/static/index.html
CHANGED
|
@@ -152,12 +152,13 @@
|
|
| 152 |
</svg>
|
| 153 |
<div class="text-sm text-gray-500 space-y-2">
|
| 154 |
<p data-i18n="privacy_note">Files are processed in memory and not stored.</p>
|
| 155 |
-
<p class="font-medium text-gray-600" data-i18n="disclaimer_mistakes">
|
| 156 |
<p class="font-medium text-gray-600" data-i18n="disclaimer_known_issues_title">Known limitations:</p>
|
| 157 |
<ul class="list-disc list-inside space-y-1 text-gray-500">
|
| 158 |
-
<li data-i18n="
|
| 159 |
-
<li data-i18n="
|
| 160 |
-
<li data-i18n="
|
|
|
|
| 161 |
</ul>
|
| 162 |
</div>
|
| 163 |
</div>
|
|
@@ -188,9 +189,9 @@
|
|
| 188 |
<p class="mt-2 text-sm text-gray-500" data-i18n="report_description">Help us improve by reporting an incorrect result.</p>
|
| 189 |
|
| 190 |
<form id="report-form" class="mt-6 space-y-6">
|
| 191 |
-
<!-- Is the
|
| 192 |
<fieldset>
|
| 193 |
-
<legend class="text-sm font-semibold text-gray-900" data-i18n="report_is_real_label">Is this
|
| 194 |
<div class="mt-3 space-y-2">
|
| 195 |
<label class="flex items-center gap-2 cursor-pointer">
|
| 196 |
<input type="radio" name="is_real" value="real" class="w-4 h-4 text-blue-600" required />
|
|
@@ -209,15 +210,27 @@
|
|
| 209 |
<div class="mt-3 space-y-2">
|
| 210 |
<label class="flex items-center gap-2 cursor-pointer">
|
| 211 |
<input type="radio" name="reason" value="self_made" class="w-4 h-4 text-blue-600" required />
|
| 212 |
-
<span data-i18n="report_reason_self">I
|
| 213 |
</label>
|
| 214 |
<label class="flex items-center gap-2 cursor-pointer">
|
| 215 |
<input type="radio" name="reason" value="evidence" class="w-4 h-4 text-blue-600" />
|
| 216 |
-
<span data-i18n="report_reason_evidence">
|
| 217 |
</label>
|
| 218 |
<label class="flex items-center gap-2 cursor-pointer">
|
| 219 |
<input type="radio" name="reason" value="known_source" class="w-4 h-4 text-blue-600" />
|
| 220 |
-
<span data-i18n="report_reason_source">Known
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 221 |
</label>
|
| 222 |
<label class="flex items-center gap-2 cursor-pointer">
|
| 223 |
<input type="radio" name="reason" value="other" class="w-4 h-4 text-blue-600" />
|
|
@@ -228,6 +241,11 @@
|
|
| 228 |
<input id="reason-other-input" type="text" placeholder="" data-i18n-placeholder="report_reason_other_placeholder"
|
| 229 |
class="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none" />
|
| 230 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 231 |
</fieldset>
|
| 232 |
|
| 233 |
<!-- Comment -->
|
|
@@ -240,7 +258,7 @@
|
|
| 240 |
<!-- Consent -->
|
| 241 |
<label class="flex items-start gap-3 cursor-pointer">
|
| 242 |
<input id="report-consent" type="checkbox" class="w-4 h-4 mt-0.5 text-blue-600 rounded" />
|
| 243 |
-
<span class="text-sm text-gray-700" data-i18n="report_consent">I allow saving this
|
| 244 |
</label>
|
| 245 |
|
| 246 |
<!-- Error / success banners -->
|
|
@@ -298,30 +316,41 @@
|
|
| 298 |
how_calculated_body: "We use a Swin Transformer V2 model fine-tuned to distinguish real photographs from AI-generated images. For videos, we sample 5 frames evenly across the duration and average the model's confidence. The score shown is the model's estimated probability that the content was generated by AI.",
|
| 299 |
close: "Close",
|
| 300 |
privacy_note: "Files are processed in memory and not stored.",
|
| 301 |
-
disclaimer_mistakes: "
|
| 302 |
disclaimer_known_issues_title: "Known limitations:",
|
| 303 |
-
|
| 304 |
-
|
| 305 |
-
|
|
|
|
| 306 |
report_error: "Signal an error",
|
| 307 |
report_title: "Signal an error",
|
| 308 |
report_description: "Help us improve by reporting an incorrect result.",
|
| 309 |
-
report_is_real_label: "Is this
|
| 310 |
report_real: "Real (authentic)",
|
| 311 |
report_ai: "AI-generated or manipulated",
|
| 312 |
report_reason_label: "How do you know?",
|
| 313 |
-
report_reason_self: "I
|
| 314 |
-
report_reason_evidence: "
|
| 315 |
-
report_reason_source: "Known
|
|
|
|
|
|
|
|
|
|
| 316 |
report_reason_other: "Other",
|
| 317 |
report_reason_other_placeholder: "Please specify…",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 318 |
report_comment_label: "Additional comments (optional)",
|
| 319 |
-
report_consent: "I allow saving this
|
| 320 |
report_cancel: "Cancel",
|
| 321 |
report_submit: "Submit report",
|
| 322 |
report_submitting: "Submitting...",
|
| 323 |
report_success: "Thank you! Your report has been submitted.",
|
| 324 |
-
report_error_consent: "You must allow saving the
|
| 325 |
report_error_fields: "Please fill in all required fields.",
|
| 326 |
report_error_generic: "Failed to submit the report. Please try again.",
|
| 327 |
},
|
|
@@ -359,30 +388,41 @@
|
|
| 359 |
how_calculated_body: "Nous utilisons un modèle Swin Transformer V2 entraîné pour distinguer les vraies photographies des images générées par IA. Pour les vidéos, nous échantillonnons 5 images réparties uniformément sur la durée et faisons la moyenne de la confiance du modèle. Le score affiché correspond à la probabilité estimée que le contenu ait été généré par IA.",
|
| 360 |
close: "Fermer",
|
| 361 |
privacy_note: "Les fichiers sont traités en mémoire et ne sont pas conservés.",
|
| 362 |
-
disclaimer_mistakes: "
|
| 363 |
disclaimer_known_issues_title: "Limitations connues :",
|
| 364 |
-
|
| 365 |
-
|
| 366 |
-
|
|
|
|
| 367 |
report_error: "Signaler une erreur",
|
| 368 |
report_title: "Signaler une erreur",
|
| 369 |
report_description: "Aidez-nous à nous améliorer en signalant un résultat incorrect.",
|
| 370 |
-
report_is_real_label: "
|
| 371 |
-
report_real: "
|
| 372 |
-
report_ai: "
|
| 373 |
report_reason_label: "Comment le savez-vous ?",
|
| 374 |
-
report_reason_self: "J'ai
|
| 375 |
-
report_reason_evidence: "
|
| 376 |
-
report_reason_source: "Source connue
|
|
|
|
|
|
|
|
|
|
| 377 |
report_reason_other: "Autre",
|
| 378 |
report_reason_other_placeholder: "Veuillez préciser…",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 379 |
report_comment_label: "Commentaires supplémentaires (optionnel)",
|
| 380 |
-
report_consent: "J'autorise la sauvegarde de
|
| 381 |
report_cancel: "Annuler",
|
| 382 |
report_submit: "Envoyer le signalement",
|
| 383 |
report_submitting: "Envoi en cours...",
|
| 384 |
report_success: "Merci ! Votre signalement a été soumis.",
|
| 385 |
-
report_error_consent: "Vous devez autoriser la sauvegarde
|
| 386 |
report_error_fields: "Veuillez remplir tous les champs obligatoires.",
|
| 387 |
report_error_generic: "Échec de l'envoi du signalement. Veuillez réessayer.",
|
| 388 |
},
|
|
@@ -667,10 +707,37 @@
|
|
| 667 |
}
|
| 668 |
|
| 669 |
/* --- Report modal --- */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 670 |
function openReportModal() {
|
| 671 |
// Reset the form
|
| 672 |
$("report-form").reset();
|
| 673 |
$("reason-other-wrap").classList.add("hidden");
|
|
|
|
| 674 |
$("report-error").classList.add("hidden");
|
| 675 |
$("report-success").classList.add("hidden");
|
| 676 |
$("report-submit").disabled = false;
|
|
@@ -726,6 +793,7 @@
|
|
| 726 |
formData.append("is_real", isRealRadio.value);
|
| 727 |
formData.append("reason", reasonValue);
|
| 728 |
formData.append("reason_other", reasonOther);
|
|
|
|
| 729 |
formData.append("comment", $("report-comment").value.trim());
|
| 730 |
formData.append("p_fake", state.result ? state.result.p_fake : 0);
|
| 731 |
formData.append("consent", "true");
|
|
@@ -808,15 +876,10 @@
|
|
| 808 |
$("report-backdrop").addEventListener("click", closeReportModal);
|
| 809 |
$("report-form").addEventListener("submit", submitReport);
|
| 810 |
|
| 811 |
-
// Toggle
|
| 812 |
document.querySelectorAll('input[name="reason"]').forEach((radio) => {
|
| 813 |
radio.addEventListener("change", () => {
|
| 814 |
-
|
| 815 |
-
if (radio.value === "other" && radio.checked) {
|
| 816 |
-
wrap.classList.remove("hidden");
|
| 817 |
-
} else {
|
| 818 |
-
wrap.classList.add("hidden");
|
| 819 |
-
}
|
| 820 |
});
|
| 821 |
});
|
| 822 |
|
|
|
|
| 152 |
</svg>
|
| 153 |
<div class="text-sm text-gray-500 space-y-2">
|
| 154 |
<p data-i18n="privacy_note">Files are processed in memory and not stored.</p>
|
| 155 |
+
<p class="font-medium text-gray-600" data-i18n="disclaimer_mistakes">Results are probabilistic and should not be treated as definitive.</p>
|
| 156 |
<p class="font-medium text-gray-600" data-i18n="disclaimer_known_issues_title">Known limitations:</p>
|
| 157 |
<ul class="list-disc list-inside space-y-1 text-gray-500">
|
| 158 |
+
<li data-i18n="disclaimer_full_gen">Performance is strongest on fully AI-generated images.</li>
|
| 159 |
+
<li data-i18n="disclaimer_lipsync">Subtle manipulations such as lip sync and localized inpainting may not be reliably detected.</li>
|
| 160 |
+
<li data-i18n="disclaimer_text_overlay">Images with text overlays are frequently misclassified as AI-generated.</li>
|
| 161 |
+
<li data-i18n="disclaimer_motion_blur">Video analysis may be less accurate in scenes with heavy motion blur.</li>
|
| 162 |
</ul>
|
| 163 |
</div>
|
| 164 |
</div>
|
|
|
|
| 189 |
<p class="mt-2 text-sm text-gray-500" data-i18n="report_description">Help us improve by reporting an incorrect result.</p>
|
| 190 |
|
| 191 |
<form id="report-form" class="mt-6 space-y-6">
|
| 192 |
+
<!-- Is the content real or AI? -->
|
| 193 |
<fieldset>
|
| 194 |
+
<legend class="text-sm font-semibold text-gray-900" data-i18n="report_is_real_label">Is this content real or AI-generated?</legend>
|
| 195 |
<div class="mt-3 space-y-2">
|
| 196 |
<label class="flex items-center gap-2 cursor-pointer">
|
| 197 |
<input type="radio" name="is_real" value="real" class="w-4 h-4 text-blue-600" required />
|
|
|
|
| 210 |
<div class="mt-3 space-y-2">
|
| 211 |
<label class="flex items-center gap-2 cursor-pointer">
|
| 212 |
<input type="radio" name="reason" value="self_made" class="w-4 h-4 text-blue-600" required />
|
| 213 |
+
<span data-i18n="report_reason_self">I created or captured this content myself</span>
|
| 214 |
</label>
|
| 215 |
<label class="flex items-center gap-2 cursor-pointer">
|
| 216 |
<input type="radio" name="reason" value="evidence" class="w-4 h-4 text-blue-600" />
|
| 217 |
+
<span data-i18n="report_reason_evidence">Visible evidence of manipulation (e.g. artifacts, distortions)</span>
|
| 218 |
</label>
|
| 219 |
<label class="flex items-center gap-2 cursor-pointer">
|
| 220 |
<input type="radio" name="reason" value="known_source" class="w-4 h-4 text-blue-600" />
|
| 221 |
+
<span data-i18n="report_reason_source">Known and verifiable original source</span>
|
| 222 |
+
</label>
|
| 223 |
+
<label class="flex items-center gap-2 cursor-pointer">
|
| 224 |
+
<input type="radio" name="reason" value="professional" class="w-4 h-4 text-blue-600" />
|
| 225 |
+
<span data-i18n="report_reason_professional">Professional or domain expertise</span>
|
| 226 |
+
</label>
|
| 227 |
+
<label class="flex items-center gap-2 cursor-pointer">
|
| 228 |
+
<input type="radio" name="reason" value="forensic" class="w-4 h-4 text-blue-600" />
|
| 229 |
+
<span data-i18n="report_reason_forensic">Metadata or forensic analysis</span>
|
| 230 |
+
</label>
|
| 231 |
+
<label class="flex items-center gap-2 cursor-pointer">
|
| 232 |
+
<input type="radio" name="reason" value="reverse_search" class="w-4 h-4 text-blue-600" />
|
| 233 |
+
<span data-i18n="report_reason_reverse_search">Reverse image/video search</span>
|
| 234 |
</label>
|
| 235 |
<label class="flex items-center gap-2 cursor-pointer">
|
| 236 |
<input type="radio" name="reason" value="other" class="w-4 h-4 text-blue-600" />
|
|
|
|
| 241 |
<input id="reason-other-input" type="text" placeholder="" data-i18n-placeholder="report_reason_other_placeholder"
|
| 242 |
class="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none" />
|
| 243 |
</div>
|
| 244 |
+
<div id="reason-details-wrap" class="hidden mt-3">
|
| 245 |
+
<label class="text-xs font-medium text-gray-600" id="reason-details-label" data-i18n="report_details_label">Please provide details</label>
|
| 246 |
+
<input id="reason-details-input" type="text" placeholder="" data-i18n-placeholder="report_details_placeholder"
|
| 247 |
+
class="mt-1 w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none" />
|
| 248 |
+
</div>
|
| 249 |
</fieldset>
|
| 250 |
|
| 251 |
<!-- Comment -->
|
|
|
|
| 258 |
<!-- Consent -->
|
| 259 |
<label class="flex items-start gap-3 cursor-pointer">
|
| 260 |
<input id="report-consent" type="checkbox" class="w-4 h-4 mt-0.5 text-blue-600 rounded" />
|
| 261 |
+
<span class="text-sm text-gray-700" data-i18n="report_consent">I allow saving this file for research purposes. This is required to submit the report.</span>
|
| 262 |
</label>
|
| 263 |
|
| 264 |
<!-- Error / success banners -->
|
|
|
|
| 316 |
how_calculated_body: "We use a Swin Transformer V2 model fine-tuned to distinguish real photographs from AI-generated images. For videos, we sample 5 frames evenly across the duration and average the model's confidence. The score shown is the model's estimated probability that the content was generated by AI.",
|
| 317 |
close: "Close",
|
| 318 |
privacy_note: "Files are processed in memory and not stored.",
|
| 319 |
+
disclaimer_mistakes: "Results are probabilistic and should not be treated as definitive.",
|
| 320 |
disclaimer_known_issues_title: "Known limitations:",
|
| 321 |
+
disclaimer_full_gen: "Performance is strongest on fully AI-generated images.",
|
| 322 |
+
disclaimer_lipsync: "Subtle manipulations such as lip sync and localized inpainting may not be reliably detected.",
|
| 323 |
+
disclaimer_text_overlay: "Images with text overlays are frequently misclassified as AI-generated.",
|
| 324 |
+
disclaimer_motion_blur: "Video analysis may be less accurate in scenes with heavy motion blur.",
|
| 325 |
report_error: "Signal an error",
|
| 326 |
report_title: "Signal an error",
|
| 327 |
report_description: "Help us improve by reporting an incorrect result.",
|
| 328 |
+
report_is_real_label: "Is this content real or AI-generated?",
|
| 329 |
report_real: "Real (authentic)",
|
| 330 |
report_ai: "AI-generated or manipulated",
|
| 331 |
report_reason_label: "How do you know?",
|
| 332 |
+
report_reason_self: "I created or captured this content myself",
|
| 333 |
+
report_reason_evidence: "Visible evidence of manipulation (e.g. artifacts, distortions)",
|
| 334 |
+
report_reason_source: "Known and verifiable original source",
|
| 335 |
+
report_reason_professional: "Professional or domain expertise",
|
| 336 |
+
report_reason_forensic: "Metadata or forensic analysis",
|
| 337 |
+
report_reason_reverse_search: "Reverse image/video search",
|
| 338 |
report_reason_other: "Other",
|
| 339 |
report_reason_other_placeholder: "Please specify…",
|
| 340 |
+
report_details_label: "Please provide details",
|
| 341 |
+
report_details_placeholder: "e.g. source URL, description of artifacts, tool used…",
|
| 342 |
+
report_details_label_evidence: "Describe the evidence you observed",
|
| 343 |
+
report_details_label_source: "Provide the source URL or reference",
|
| 344 |
+
report_details_label_professional: "Describe your area of expertise",
|
| 345 |
+
report_details_label_forensic: "Describe the analysis performed",
|
| 346 |
+
report_details_label_reverse_search: "Provide the search tool or URL used",
|
| 347 |
report_comment_label: "Additional comments (optional)",
|
| 348 |
+
report_consent: "I allow saving this file for research purposes. This is required to submit the report.",
|
| 349 |
report_cancel: "Cancel",
|
| 350 |
report_submit: "Submit report",
|
| 351 |
report_submitting: "Submitting...",
|
| 352 |
report_success: "Thank you! Your report has been submitted.",
|
| 353 |
+
report_error_consent: "You must allow saving the file to submit a report.",
|
| 354 |
report_error_fields: "Please fill in all required fields.",
|
| 355 |
report_error_generic: "Failed to submit the report. Please try again.",
|
| 356 |
},
|
|
|
|
| 388 |
how_calculated_body: "Nous utilisons un modèle Swin Transformer V2 entraîné pour distinguer les vraies photographies des images générées par IA. Pour les vidéos, nous échantillonnons 5 images réparties uniformément sur la durée et faisons la moyenne de la confiance du modèle. Le score affiché correspond à la probabilité estimée que le contenu ait été généré par IA.",
|
| 389 |
close: "Fermer",
|
| 390 |
privacy_note: "Les fichiers sont traités en mémoire et ne sont pas conservés.",
|
| 391 |
+
disclaimer_mistakes: "Les résultats sont probabilistes et ne doivent pas être considérés comme définitifs.",
|
| 392 |
disclaimer_known_issues_title: "Limitations connues :",
|
| 393 |
+
disclaimer_full_gen: "Les performances sont optimales sur les images entièrement générées par IA.",
|
| 394 |
+
disclaimer_lipsync: "Les manipulations subtiles telles que la synchronisation labiale et l'inpainting localisé peuvent ne pas être détectées de manière fiable.",
|
| 395 |
+
disclaimer_text_overlay: "Les images comportant du texte superposé sont fréquemment classées à tort comme générées par IA.",
|
| 396 |
+
disclaimer_motion_blur: "L'analyse vidéo peut être moins précise dans les scènes présentant un fort flou de mouvement.",
|
| 397 |
report_error: "Signaler une erreur",
|
| 398 |
report_title: "Signaler une erreur",
|
| 399 |
report_description: "Aidez-nous à nous améliorer en signalant un résultat incorrect.",
|
| 400 |
+
report_is_real_label: "Ce contenu est-il réel ou généré par IA ?",
|
| 401 |
+
report_real: "Réel (authentique)",
|
| 402 |
+
report_ai: "Généré par IA ou manipulé",
|
| 403 |
report_reason_label: "Comment le savez-vous ?",
|
| 404 |
+
report_reason_self: "J'ai créé ou capturé ce contenu moi-même",
|
| 405 |
+
report_reason_evidence: "Preuves visibles de manipulation (ex. : artefacts, distorsions)",
|
| 406 |
+
report_reason_source: "Source originale connue et vérifiable",
|
| 407 |
+
report_reason_professional: "Expertise professionnelle ou de domaine",
|
| 408 |
+
report_reason_forensic: "Analyse des métadonnées ou analyse forensique",
|
| 409 |
+
report_reason_reverse_search: "Recherche inversée d'image ou de vidéo",
|
| 410 |
report_reason_other: "Autre",
|
| 411 |
report_reason_other_placeholder: "Veuillez préciser…",
|
| 412 |
+
report_details_label: "Veuillez fournir des détails",
|
| 413 |
+
report_details_placeholder: "ex. : URL source, description des artefacts, outil utilisé…",
|
| 414 |
+
report_details_label_evidence: "Décrivez les preuves observées",
|
| 415 |
+
report_details_label_source: "Fournissez l'URL source ou la référence",
|
| 416 |
+
report_details_label_professional: "Décrivez votre domaine d'expertise",
|
| 417 |
+
report_details_label_forensic: "Décrivez l'analyse effectuée",
|
| 418 |
+
report_details_label_reverse_search: "Indiquez l'outil ou l'URL de recherche utilisé",
|
| 419 |
report_comment_label: "Commentaires supplémentaires (optionnel)",
|
| 420 |
+
report_consent: "J'autorise la sauvegarde de ce fichier à des fins de recherche. Ceci est requis pour soumettre le signalement.",
|
| 421 |
report_cancel: "Annuler",
|
| 422 |
report_submit: "Envoyer le signalement",
|
| 423 |
report_submitting: "Envoi en cours...",
|
| 424 |
report_success: "Merci ! Votre signalement a été soumis.",
|
| 425 |
+
report_error_consent: "Vous devez autoriser la sauvegarde du fichier pour soumettre un signalement.",
|
| 426 |
report_error_fields: "Veuillez remplir tous les champs obligatoires.",
|
| 427 |
report_error_generic: "Échec de l'envoi du signalement. Veuillez réessayer.",
|
| 428 |
},
|
|
|
|
| 707 |
}
|
| 708 |
|
| 709 |
/* --- Report modal --- */
|
| 710 |
+
// Reasons that should show the contextual detail input
|
| 711 |
+
const REASONS_WITH_DETAILS = ["evidence", "known_source", "professional", "forensic", "reverse_search"];
|
| 712 |
+
|
| 713 |
+
function updateReasonUI(selectedValue) {
|
| 714 |
+
const otherWrap = $("reason-other-wrap");
|
| 715 |
+
const detailsWrap = $("reason-details-wrap");
|
| 716 |
+
|
| 717 |
+
// "Other" free-text
|
| 718 |
+
if (selectedValue === "other") {
|
| 719 |
+
otherWrap.classList.remove("hidden");
|
| 720 |
+
} else {
|
| 721 |
+
otherWrap.classList.add("hidden");
|
| 722 |
+
}
|
| 723 |
+
|
| 724 |
+
// Contextual detail input
|
| 725 |
+
if (REASONS_WITH_DETAILS.includes(selectedValue)) {
|
| 726 |
+
detailsWrap.classList.remove("hidden");
|
| 727 |
+
const T = t();
|
| 728 |
+
const labelKey = "report_details_label_" + selectedValue;
|
| 729 |
+
const label = T[labelKey] || T.report_details_label;
|
| 730 |
+
$("reason-details-label").textContent = label;
|
| 731 |
+
} else {
|
| 732 |
+
detailsWrap.classList.add("hidden");
|
| 733 |
+
}
|
| 734 |
+
}
|
| 735 |
+
|
| 736 |
function openReportModal() {
|
| 737 |
// Reset the form
|
| 738 |
$("report-form").reset();
|
| 739 |
$("reason-other-wrap").classList.add("hidden");
|
| 740 |
+
$("reason-details-wrap").classList.add("hidden");
|
| 741 |
$("report-error").classList.add("hidden");
|
| 742 |
$("report-success").classList.add("hidden");
|
| 743 |
$("report-submit").disabled = false;
|
|
|
|
| 793 |
formData.append("is_real", isRealRadio.value);
|
| 794 |
formData.append("reason", reasonValue);
|
| 795 |
formData.append("reason_other", reasonOther);
|
| 796 |
+
formData.append("reason_details", $("reason-details-input").value.trim());
|
| 797 |
formData.append("comment", $("report-comment").value.trim());
|
| 798 |
formData.append("p_fake", state.result ? state.result.p_fake : 0);
|
| 799 |
formData.append("consent", "true");
|
|
|
|
| 876 |
$("report-backdrop").addEventListener("click", closeReportModal);
|
| 877 |
$("report-form").addEventListener("submit", submitReport);
|
| 878 |
|
| 879 |
+
// Toggle reason sub-fields (other text input + contextual details)
|
| 880 |
document.querySelectorAll('input[name="reason"]').forEach((radio) => {
|
| 881 |
radio.addEventListener("change", () => {
|
| 882 |
+
if (radio.checked) updateReasonUI(radio.value);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 883 |
});
|
| 884 |
});
|
| 885 |
|