akhaliq HF Staff commited on
Commit
d504f24
·
1 Parent(s): ca24842

Add inline media preview inside center prompt input card

Browse files

- Visual inputs (images/videos) now display directly inside the input box
- Preview shows between task badge and textarea with 220px max-height
- Remove button (X) overlaid on preview to clear attachment
- Synced with file uploads, example selections, and clearSelectedFile
- Auto-hidden in output mode for clean layout

Files changed (1) hide show
  1. index.html +113 -2
index.html CHANGED
@@ -299,6 +299,10 @@
299
  display: none;
300
  }
301
 
 
 
 
 
302
  /* Hide branding when output is showing */
303
  .viewport-bottom.output-hidden {
304
  opacity: 0;
@@ -355,6 +359,67 @@
355
  width: 100%;
356
  }
357
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
358
  .center-prompt-body textarea.prompt-textarea {
359
  width: 100%;
360
  height: 44px;
@@ -1497,6 +1562,15 @@
1497
  <span class="active-task-pill" id="center-task-badge">Text to Video</span>
1498
  </div>
1499
  <div class="center-prompt-body">
 
 
 
 
 
 
 
 
 
1500
  <textarea class="prompt-textarea" id="prompt-input" placeholder="Describe what you want to generate..."></textarea>
1501
  </div>
1502
  <div class="center-prompt-footer">
@@ -2066,6 +2140,36 @@
2066
  }
2067
  }
2068
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2069
  // --- Handle Uploaded Files locally ---
2070
  function handleSelectedFile(file) {
2071
  if (!file) return;
@@ -2078,14 +2182,16 @@
2078
  // Build visual thumbnail preview
2079
  previewMediaWrapper.innerHTML = "";
2080
  const fileType = selectedFile.type;
 
2081
 
2082
  if (fileType.startsWith("image/")) {
2083
  const img = document.createElement("img");
2084
- img.src = URL.createObjectURL(selectedFile);
2085
  previewMediaWrapper.appendChild(img);
 
2086
  } else if (fileType.startsWith("video/")) {
2087
  const video = document.createElement("video");
2088
- video.src = URL.createObjectURL(selectedFile);
2089
  video.muted = true;
2090
  video.playsInline = true;
2091
  previewMediaWrapper.appendChild(video);
@@ -2094,12 +2200,14 @@
2094
  video.addEventListener("loadeddata", () => {
2095
  video.currentTime = 0.5;
2096
  });
 
2097
  } else {
2098
  const docIcon = document.createElement("div");
2099
  docIcon.style.color = "var(--text-secondary)";
2100
  docIcon.innerHTML = '<i data-lucide="file"></i>';
2101
  previewMediaWrapper.appendChild(docIcon);
2102
  lucide.createIcons();
 
2103
  }
2104
 
2105
  dragDropZone.style.display = "none";
@@ -2112,6 +2220,7 @@
2112
  uploadedFileReference = null;
2113
  fileSelector.value = "";
2114
  filePreviewCard.style.display = "none";
 
2115
 
2116
  const isEdit = activeTask === "image_edit" || activeTask === "video_edit";
2117
  const isUnderstanding = activeTask === "x2t_video" || activeTask === "x2t_image";
@@ -2170,6 +2279,7 @@
2170
  filePreviewCard.style.display = "flex";
2171
 
2172
  uploadedFileReference = hasVideo;
 
2173
  } else if (hasImage && (activeTask === "image_edit" || activeTask === "x2t_image")) {
2174
  previewFilename.textContent = hasImage.split("/").pop();
2175
  previewFilesize.textContent = "Example Asset";
@@ -2183,6 +2293,7 @@
2183
  filePreviewCard.style.display = "flex";
2184
 
2185
  uploadedFileReference = hasImage;
 
2186
  }
2187
 
2188
  // Trigger reset of viewer output
 
299
  display: none;
300
  }
301
 
302
+ .viewport-center-trigger.output-mode .center-inline-preview {
303
+ display: none;
304
+ }
305
+
306
  /* Hide branding when output is showing */
307
  .viewport-bottom.output-hidden {
308
  opacity: 0;
 
359
  width: 100%;
360
  }
361
 
362
+ /* Inline media attachment preview inside center prompt card */
363
+ .center-inline-preview {
364
+ display: none;
365
+ width: 100%;
366
+ border-radius: 10px;
367
+ overflow: hidden;
368
+ background: rgba(0, 0, 0, 0.25);
369
+ border: 1px solid rgba(255, 255, 255, 0.08);
370
+ position: relative;
371
+ margin-bottom: 6px;
372
+ }
373
+
374
+ .center-inline-preview.visible {
375
+ display: block;
376
+ }
377
+
378
+ .center-inline-preview-media {
379
+ width: 100%;
380
+ max-height: 220px;
381
+ display: flex;
382
+ align-items: center;
383
+ justify-content: center;
384
+ overflow: hidden;
385
+ }
386
+
387
+ .center-inline-preview-media img,
388
+ .center-inline-preview-media video {
389
+ width: 100%;
390
+ max-height: 220px;
391
+ object-fit: contain;
392
+ }
393
+
394
+ .center-inline-preview-remove {
395
+ position: absolute;
396
+ top: 8px;
397
+ right: 8px;
398
+ width: 26px;
399
+ height: 26px;
400
+ border-radius: 50%;
401
+ background: rgba(0, 0, 0, 0.6);
402
+ border: 1px solid rgba(255, 255, 255, 0.15);
403
+ color: #fff;
404
+ display: flex;
405
+ align-items: center;
406
+ justify-content: center;
407
+ cursor: pointer;
408
+ transition: var(--transition-fast);
409
+ backdrop-filter: blur(8px);
410
+ -webkit-backdrop-filter: blur(8px);
411
+ }
412
+
413
+ .center-inline-preview-remove:hover {
414
+ background: rgba(239, 68, 68, 0.7);
415
+ border-color: rgba(239, 68, 68, 0.5);
416
+ }
417
+
418
+ .center-inline-preview-remove i {
419
+ width: 13px;
420
+ height: 13px;
421
+ }
422
+
423
  .center-prompt-body textarea.prompt-textarea {
424
  width: 100%;
425
  height: 44px;
 
1562
  <span class="active-task-pill" id="center-task-badge">Text to Video</span>
1563
  </div>
1564
  <div class="center-prompt-body">
1565
+ <!-- Inline media attachment preview -->
1566
+ <div class="center-inline-preview" id="center-inline-preview">
1567
+ <div class="center-inline-preview-media" id="center-inline-preview-media">
1568
+ <!-- JS injects img/video here -->
1569
+ </div>
1570
+ <button class="center-inline-preview-remove" id="center-inline-preview-remove" title="Remove attachment">
1571
+ <i data-lucide="x"></i>
1572
+ </button>
1573
+ </div>
1574
  <textarea class="prompt-textarea" id="prompt-input" placeholder="Describe what you want to generate..."></textarea>
1575
  </div>
1576
  <div class="center-prompt-footer">
 
2140
  }
2141
  }
2142
 
2143
+ // --- Inline preview element caches ---
2144
+ const centerInlinePreview = document.getElementById("center-inline-preview");
2145
+ const centerInlinePreviewMedia = document.getElementById("center-inline-preview-media");
2146
+ const centerInlinePreviewRemove = document.getElementById("center-inline-preview-remove");
2147
+
2148
+ // Bind inline preview remove button
2149
+ centerInlinePreviewRemove.addEventListener("click", () => clearSelectedFile());
2150
+
2151
+ // --- Sync inline preview inside center prompt card ---
2152
+ function updateCenterInlinePreview(src, type) {
2153
+ centerInlinePreviewMedia.innerHTML = "";
2154
+ if (!src) {
2155
+ centerInlinePreview.classList.remove("visible");
2156
+ return;
2157
+ }
2158
+ if (type === "video") {
2159
+ const video = document.createElement("video");
2160
+ video.src = src;
2161
+ video.muted = true;
2162
+ video.playsInline = true;
2163
+ video.addEventListener("loadeddata", () => { video.currentTime = 0.5; });
2164
+ centerInlinePreviewMedia.appendChild(video);
2165
+ } else {
2166
+ const img = document.createElement("img");
2167
+ img.src = src;
2168
+ centerInlinePreviewMedia.appendChild(img);
2169
+ }
2170
+ centerInlinePreview.classList.add("visible");
2171
+ }
2172
+
2173
  // --- Handle Uploaded Files locally ---
2174
  function handleSelectedFile(file) {
2175
  if (!file) return;
 
2182
  // Build visual thumbnail preview
2183
  previewMediaWrapper.innerHTML = "";
2184
  const fileType = selectedFile.type;
2185
+ const objectUrl = URL.createObjectURL(selectedFile);
2186
 
2187
  if (fileType.startsWith("image/")) {
2188
  const img = document.createElement("img");
2189
+ img.src = objectUrl;
2190
  previewMediaWrapper.appendChild(img);
2191
+ updateCenterInlinePreview(objectUrl, "image");
2192
  } else if (fileType.startsWith("video/")) {
2193
  const video = document.createElement("video");
2194
+ video.src = objectUrl;
2195
  video.muted = true;
2196
  video.playsInline = true;
2197
  previewMediaWrapper.appendChild(video);
 
2200
  video.addEventListener("loadeddata", () => {
2201
  video.currentTime = 0.5;
2202
  });
2203
+ updateCenterInlinePreview(objectUrl, "video");
2204
  } else {
2205
  const docIcon = document.createElement("div");
2206
  docIcon.style.color = "var(--text-secondary)";
2207
  docIcon.innerHTML = '<i data-lucide="file"></i>';
2208
  previewMediaWrapper.appendChild(docIcon);
2209
  lucide.createIcons();
2210
+ updateCenterInlinePreview(null, null);
2211
  }
2212
 
2213
  dragDropZone.style.display = "none";
 
2220
  uploadedFileReference = null;
2221
  fileSelector.value = "";
2222
  filePreviewCard.style.display = "none";
2223
+ updateCenterInlinePreview(null, null);
2224
 
2225
  const isEdit = activeTask === "image_edit" || activeTask === "video_edit";
2226
  const isUnderstanding = activeTask === "x2t_video" || activeTask === "x2t_image";
 
2279
  filePreviewCard.style.display = "flex";
2280
 
2281
  uploadedFileReference = hasVideo;
2282
+ updateCenterInlinePreview(hasVideo, "video");
2283
  } else if (hasImage && (activeTask === "image_edit" || activeTask === "x2t_image")) {
2284
  previewFilename.textContent = hasImage.split("/").pop();
2285
  previewFilesize.textContent = "Example Asset";
 
2293
  filePreviewCard.style.display = "flex";
2294
 
2295
  uploadedFileReference = hasImage;
2296
+ updateCenterInlinePreview(hasImage, "image");
2297
  }
2298
 
2299
  // Trigger reset of viewer output