Upload templates/index.html
Browse files- templates/index.html +37 -2
templates/index.html
CHANGED
|
@@ -205,8 +205,8 @@
|
|
| 205 |
|
| 206 |
<div class="upload-area" id="uploadArea">
|
| 207 |
<div class="upload-icon">🔮</div>
|
| 208 |
-
<div class="upload-text">Drop your images here
|
| 209 |
-
<div class="upload-subtext">Supports PNG, JPG, JPEG
|
| 210 |
<input type="file" id="fileInput" class="file-input" accept=".png,.jpg,.jpeg" multiple>
|
| 211 |
</div>
|
| 212 |
|
|
@@ -272,6 +272,7 @@
|
|
| 272 |
});
|
| 273 |
uploadArea.addEventListener('drop', handleDrop, false);
|
| 274 |
analyzeButton.addEventListener('click', analyzeImages);
|
|
|
|
| 275 |
|
| 276 |
function preventDefaults(e) {
|
| 277 |
e.preventDefault();
|
|
@@ -285,6 +286,40 @@
|
|
| 285 |
function handleFileSelect(e) {
|
| 286 |
handleFiles(e.target.files);
|
| 287 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 288 |
|
| 289 |
// --- UPDATED: Reads files and generates data URLs for previews ---
|
| 290 |
async function handleFiles(files) {
|
|
|
|
| 205 |
|
| 206 |
<div class="upload-area" id="uploadArea">
|
| 207 |
<div class="upload-icon">🔮</div>
|
| 208 |
+
<div class="upload-text">Drop your images here, click to upload, or press Ctrl+V</div>
|
| 209 |
+
<div class="upload-subtext">Pasted images start analysis immediately • Supports PNG, JPG, JPEG</div>
|
| 210 |
<input type="file" id="fileInput" class="file-input" accept=".png,.jpg,.jpeg" multiple>
|
| 211 |
</div>
|
| 212 |
|
|
|
|
| 272 |
});
|
| 273 |
uploadArea.addEventListener('drop', handleDrop, false);
|
| 274 |
analyzeButton.addEventListener('click', analyzeImages);
|
| 275 |
+
document.addEventListener('paste', handlePaste);
|
| 276 |
|
| 277 |
function preventDefaults(e) {
|
| 278 |
e.preventDefault();
|
|
|
|
| 286 |
function handleFileSelect(e) {
|
| 287 |
handleFiles(e.target.files);
|
| 288 |
}
|
| 289 |
+
|
| 290 |
+
async function handlePaste(e) {
|
| 291 |
+
const clipboardItems = Array.from(e.clipboardData?.items || []);
|
| 292 |
+
const imageFiles = clipboardItems
|
| 293 |
+
.filter(item => item.kind === 'file' && item.type.startsWith('image/'))
|
| 294 |
+
.map((item, index) => {
|
| 295 |
+
const blob = item.getAsFile();
|
| 296 |
+
if (!blob) return null;
|
| 297 |
+
|
| 298 |
+
const extension = blob.type === 'image/jpeg' ? 'jpg'
|
| 299 |
+
: blob.type === 'image/png' ? 'png'
|
| 300 |
+
: blob.type === 'image/webp' ? 'webp'
|
| 301 |
+
: 'png';
|
| 302 |
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
| 303 |
+
return new File(
|
| 304 |
+
[blob],
|
| 305 |
+
`clipboard-${timestamp}-${index + 1}.${extension}`,
|
| 306 |
+
{ type: blob.type || `image/${extension}`, lastModified: Date.now() }
|
| 307 |
+
);
|
| 308 |
+
})
|
| 309 |
+
.filter(Boolean);
|
| 310 |
+
|
| 311 |
+
if (imageFiles.length === 0) return;
|
| 312 |
+
|
| 313 |
+
e.preventDefault();
|
| 314 |
+
|
| 315 |
+
if (analyzeButton.disabled) {
|
| 316 |
+
showError('An analysis is already in progress.');
|
| 317 |
+
return;
|
| 318 |
+
}
|
| 319 |
+
|
| 320 |
+
await handleFiles(imageFiles);
|
| 321 |
+
await analyzeImages();
|
| 322 |
+
}
|
| 323 |
|
| 324 |
// --- UPDATED: Reads files and generates data URLs for previews ---
|
| 325 |
async function handleFiles(files) {
|