Gaurav vashistha commited on
Commit
7d2f112
·
1 Parent(s): 02b24fc

fix: init race condition and z-index safety

Browse files
Files changed (1) hide show
  1. stitch_continuity_dashboard/code.html +44 -74
stitch_continuity_dashboard/code.html CHANGED
@@ -260,37 +260,53 @@
260
  class="material-symbols-outlined">auto_fix_high</span> Generate Video</button>
261
  </div>
262
 
263
- <script>
264
- function savePreference(key, value) {
265
- localStorage.setItem('continuity_' + key, value);
266
- }
267
- function loadPreferences() { const s = localStorage.getItem('continuity_style'); const a = localStorage.getItem('continuity_audio'); if (s) document.getElementById('style-select').value = s; if (a) document.getElementById('audio-input').value = a; }
268
-
269
- // Init
270
- loadPreferences();
 
 
 
 
 
271
 
 
272
  function toggleDrawer(show) {
273
- const d = document.getElementById('gallery-drawer');
274
- const o = document.getElementById('drawer-overlay');
275
 
 
 
 
 
276
  if (show) {
277
- if (d && o) {
278
- d.classList.remove('drawer-closed');
279
- d.classList.add('drawer-open');
280
- o.classList.remove('hidden');
281
- fetchHistory();
282
- }
283
  } else {
284
- if (d && o) {
285
- d.classList.remove('drawer-open');
286
- d.classList.add('drawer-closed');
287
- o.classList.add('hidden');
288
- }
289
  }
290
  }
 
 
 
 
 
 
 
 
 
 
 
291
  async function fetchHistory() {
292
  const c = document.getElementById('gallery-content');
293
- if (!c) return;
294
  c.innerHTML = '<div class="text-center mt-10"><span class="material-symbols-outlined animate-spin">progress_activity</span></div>';
295
  try {
296
  const res = await fetch('/history');
@@ -304,12 +320,9 @@
304
  <video src="${i.url}" class="w-full aspect-video object-cover" controls></video>
305
  <div class="p-2 flex justify-between items-center">
306
  <span class="text-[10px] text-gray-400 truncate w-32">${i.name}</span>
307
- <a href="${i.url}" download class="text-gray-400 hover:text-white">
308
- <span class="material-symbols-outlined text-sm">download</span>
309
- </a>
310
  </div>
311
- </div>
312
- `).join('');
313
  } catch (e) {
314
  c.innerHTML = '<div class="text-center text-red-400 mt-10">Error loading history.</div>';
315
  }
@@ -324,44 +337,28 @@
324
  document.getElementById("analysis-panel").classList.remove("hidden");
325
  document.getElementById("review-panel").classList.add("hidden");
326
  document.getElementById("prompt-box").value = "";
327
- currentVideoAPath = "";
328
- currentVideoCPath = "";
329
-
330
- // Reset Bridge Display
331
- document.getElementById("bridge-content").innerHTML = `
332
- <div class="absolute inset-0 bg-cover bg-center opacity-20" style="background-image:url('https://images.unsplash.com/photo-1614850523060-8da1d56ae167')"></div>
333
- <div class="absolute inset-0 flex flex-col items-center justify-center">
334
- <span class="material-symbols-outlined text-3xl text-primary mb-2">auto_awesome</span>
335
- <p class="text-xs text-gray-400">Ready</p>
336
- </div>`;
337
  document.getElementById("bridge-card-outer").classList.replace("border-primary", "border-primary/20");
338
  document.getElementById("bridge-border").classList.replace("border-primary/50", "border-transparent");
339
  document.getElementById("merged-download-container").classList.add("hidden");
340
  }
341
- let currentVideoAPath = "";
342
- let currentVideoCPath = "";
343
-
344
  document.getElementById("analyze-btn").addEventListener("click", async () => {
345
  const fA = document.getElementById("video-upload-a").files[0];
346
  const fC = document.getElementById("video-upload-c").files[0];
347
  if (!fA || !fC) return alert("Upload both scenes.");
348
-
349
  const btn = document.getElementById("analyze-btn");
350
  btn.disabled = true;
351
  btn.innerHTML = `Analyzing...`;
352
-
353
  const fd = new FormData();
354
  fd.append("video_a", fA);
355
  fd.append("video_c", fC);
356
-
357
  try {
358
  const res = await fetch("/analyze", { method: "POST", body: fd });
359
  const data = await res.json();
360
- if (data.detail) throw new Error(data.detail);
361
  document.getElementById("prompt-box").value = data.prompt;
362
  currentVideoAPath = data.video_a_path;
363
  currentVideoCPath = data.video_c_path;
364
-
365
  document.getElementById("analysis-panel").classList.add("hidden");
366
  document.getElementById("review-panel").classList.remove("hidden");
367
  } catch (e) {
@@ -375,7 +372,6 @@
375
  const btn = document.getElementById("generate-btn");
376
  btn.disabled = true;
377
  btn.innerHTML = `Generating...`;
378
-
379
  try {
380
  const res = await fetch("/generate", {
381
  method: "POST",
@@ -391,39 +387,26 @@
391
  video_c_path: currentVideoCPath
392
  })
393
  });
394
-
395
  const data = await res.json();
396
  const poll = setInterval(async () => {
397
  const sRes = await fetch(`/status/${data.job_id}?t=${Date.now()}`);
398
  if (sRes.ok) {
399
  const s = await sRes.json();
400
-
401
  if (s.status === "completed") {
402
  clearInterval(poll);
403
-
404
- // 1. Show raw Bridge
405
- document.getElementById("bridge-content").innerHTML = `
406
- <video controls autoplay loop class="w-full h-full object-contain bg-black">
407
- <source src="${s.video_url}" type="video/mp4">
408
- </video>`;
409
-
410
- // UI State
411
  document.getElementById("bridge-card-outer").classList.replace("border-primary/20", "border-primary");
412
- document.getElementById("bridge-border").classList.replace("border-primary/50", "border-transparent");
413
-
414
- // 2. Show Merged Button if available
415
  if (s.merged_video_url) {
416
  const dlBtn = document.getElementById("merged-download-btn");
417
  dlBtn.href = s.merged_video_url;
418
  document.getElementById("merged-download-container").classList.remove("hidden");
419
  }
420
-
421
  btn.innerHTML = "Done!";
422
  setTimeout(() => {
423
  btn.disabled = false;
424
  btn.innerHTML = `<span class="material-symbols-outlined">auto_fix_high</span> Generate Video`;
425
  }, 3000);
426
-
427
  } else if (s.status === "error") {
428
  clearInterval(poll);
429
  alert(s.log);
@@ -440,19 +423,6 @@
440
  }
441
  });
442
  </script>
443
- <div id="drawer-overlay" class="fixed inset-0 bg-black/50 z-40 hidden" onclick="toggleDrawer(false)"></div>
444
- <div id="gallery-drawer"
445
- class="fixed right-0 top-0 h-full w-80 bg-surface-dark shadow-2xl z-[100] transform drawer-closed flex flex-col border-l border-white/10 transition-transform duration-300">
446
- <div class="p-6 border-b border-white/5 flex items-center justify-between bg-surface-dark">
447
- <h2 class="text-lg font-bold text-white flex items-center gap-2"><span
448
- class="material-symbols-outlined text-primary">history</span> History</h2>
449
- <button onclick="toggleDrawer(false)" class="text-gray-400 hover:text-white transition-colors"><span
450
- class="material-symbols-outlined">close</span></button>
451
- </div>
452
- <div id="gallery-content" class="flex-1 overflow-y-auto p-4 space-y-4">
453
- <div class="text-center text-gray-500 mt-10">Loading history...</div>
454
- </div>
455
- </div>
456
  </body>
457
 
458
  </html>
 
260
  class="material-symbols-outlined">auto_fix_high</span> Generate Video</button>
261
  </div>
262
 
263
+ <div id="drawer-overlay" class="fixed inset-0 bg-black/50 z-[90] hidden" onclick="toggleDrawer(false)"></div>
264
+ <div id="gallery-drawer"
265
+ class="fixed right-0 top-0 h-full w-80 bg-surface-dark shadow-2xl z-[100] transform drawer-closed flex flex-col border-l border-white/10 transition-transform duration-300">
266
+ <div class="p-6 border-b border-white/5 flex items-center justify-between bg-surface-dark">
267
+ <h2 class="text-lg font-bold text-white flex items-center gap-2"><span
268
+ class="material-symbols-outlined text-primary">history</span> History</h2>
269
+ <button onclick="toggleDrawer(false)" class="text-gray-400 hover:text-white transition-colors"><span
270
+ class="material-symbols-outlined">close</span></button>
271
+ </div>
272
+ <div id="gallery-content" class="flex-1 overflow-y-auto p-4 space-y-4">
273
+ <div class="text-center text-gray-500 mt-10">Loading history...</div>
274
+ </div>
275
+ </div>
276
 
277
+ <script>
278
  function toggleDrawer(show) {
279
+ const drawer = document.getElementById('gallery-drawer');
280
+ const overlay = document.getElementById('drawer-overlay');
281
 
282
+ if (!drawer || !overlay) {
283
+ console.error("Drawer elements not found! Check HTML structure.");
284
+ return;
285
+ }
286
  if (show) {
287
+ drawer.classList.remove('drawer-closed');
288
+ drawer.classList.add('drawer-open');
289
+ overlay.classList.remove('hidden');
290
+ fetchHistory();
 
 
291
  } else {
292
+ drawer.classList.remove('drawer-open');
293
+ drawer.classList.add('drawer-closed');
294
+ overlay.classList.add('hidden');
 
 
295
  }
296
  }
297
+ // --- APP LOGIC ---
298
+ let currentVideoAPath = "";
299
+ let currentVideoCPath = "";
300
+ function savePreference(key, value) { localStorage.setItem('continuity_' + key, value); }
301
+ function loadPreferences() {
302
+ const s = localStorage.getItem('continuity_style');
303
+ const a = localStorage.getItem('continuity_audio');
304
+ if (s) document.getElementById('style-select').value = s;
305
+ if (a) document.getElementById('audio-input').value = a;
306
+ }
307
+ loadPreferences(); // Safe to run here as inputs exist
308
  async function fetchHistory() {
309
  const c = document.getElementById('gallery-content');
 
310
  c.innerHTML = '<div class="text-center mt-10"><span class="material-symbols-outlined animate-spin">progress_activity</span></div>';
311
  try {
312
  const res = await fetch('/history');
 
320
  <video src="${i.url}" class="w-full aspect-video object-cover" controls></video>
321
  <div class="p-2 flex justify-between items-center">
322
  <span class="text-[10px] text-gray-400 truncate w-32">${i.name}</span>
323
+ <a href="${i.url}" download class="text-gray-400 hover:text-white"><span class="material-symbols-outlined text-sm">download</span></a>
 
 
324
  </div>
325
+ </div>`).join('');
 
326
  } catch (e) {
327
  c.innerHTML = '<div class="text-center text-red-400 mt-10">Error loading history.</div>';
328
  }
 
337
  document.getElementById("analysis-panel").classList.remove("hidden");
338
  document.getElementById("review-panel").classList.add("hidden");
339
  document.getElementById("prompt-box").value = "";
340
+ currentVideoAPath = ""; currentVideoCPath = "";
341
+ document.getElementById("bridge-content").innerHTML = `<div class="absolute inset-0 bg-cover bg-center opacity-20" style="background-image:url('https://images.unsplash.com/photo-1614850523060-8da1d56ae167')"></div><div class="absolute inset-0 flex flex-col items-center justify-center"><span class="material-symbols-outlined text-3xl text-primary mb-2">auto_awesome</span><p class="text-xs text-gray-400">Ready</p></div>`;
 
 
 
 
 
 
 
 
342
  document.getElementById("bridge-card-outer").classList.replace("border-primary", "border-primary/20");
343
  document.getElementById("bridge-border").classList.replace("border-primary/50", "border-transparent");
344
  document.getElementById("merged-download-container").classList.add("hidden");
345
  }
 
 
 
346
  document.getElementById("analyze-btn").addEventListener("click", async () => {
347
  const fA = document.getElementById("video-upload-a").files[0];
348
  const fC = document.getElementById("video-upload-c").files[0];
349
  if (!fA || !fC) return alert("Upload both scenes.");
 
350
  const btn = document.getElementById("analyze-btn");
351
  btn.disabled = true;
352
  btn.innerHTML = `Analyzing...`;
 
353
  const fd = new FormData();
354
  fd.append("video_a", fA);
355
  fd.append("video_c", fC);
 
356
  try {
357
  const res = await fetch("/analyze", { method: "POST", body: fd });
358
  const data = await res.json();
 
359
  document.getElementById("prompt-box").value = data.prompt;
360
  currentVideoAPath = data.video_a_path;
361
  currentVideoCPath = data.video_c_path;
 
362
  document.getElementById("analysis-panel").classList.add("hidden");
363
  document.getElementById("review-panel").classList.remove("hidden");
364
  } catch (e) {
 
372
  const btn = document.getElementById("generate-btn");
373
  btn.disabled = true;
374
  btn.innerHTML = `Generating...`;
 
375
  try {
376
  const res = await fetch("/generate", {
377
  method: "POST",
 
387
  video_c_path: currentVideoCPath
388
  })
389
  });
 
390
  const data = await res.json();
391
  const poll = setInterval(async () => {
392
  const sRes = await fetch(`/status/${data.job_id}?t=${Date.now()}`);
393
  if (sRes.ok) {
394
  const s = await sRes.json();
 
395
  if (s.status === "completed") {
396
  clearInterval(poll);
397
+ document.getElementById("bridge-content").innerHTML = `<video controls autoplay loop class="w-full h-full object-contain bg-black"><source src="${s.video_url}" type="video/mp4"></video>`;
 
 
 
 
 
 
 
398
  document.getElementById("bridge-card-outer").classList.replace("border-primary/20", "border-primary");
399
+ document.getElementById("bridge-border").classList.replace("border-transparent", "border-primary/50");
 
 
400
  if (s.merged_video_url) {
401
  const dlBtn = document.getElementById("merged-download-btn");
402
  dlBtn.href = s.merged_video_url;
403
  document.getElementById("merged-download-container").classList.remove("hidden");
404
  }
 
405
  btn.innerHTML = "Done!";
406
  setTimeout(() => {
407
  btn.disabled = false;
408
  btn.innerHTML = `<span class="material-symbols-outlined">auto_fix_high</span> Generate Video`;
409
  }, 3000);
 
410
  } else if (s.status === "error") {
411
  clearInterval(poll);
412
  alert(s.log);
 
423
  }
424
  });
425
  </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
426
  </body>
427
 
428
  </html>