Browse Source

feat(ui): implement universal drag-and-drop and expanded start screen

- Expanded start screen card and drop zone visuals for better accessibility.

- Implemented a global #global-drag-overlay that appears on drag over the entire window.

- Attached drag-and-drop listeners to document.body for universal file loading.

- Refined dragCounter logic to prevent overlay flickering during child element transit.
refactor/sync-centralize
RUSHIL AMBARISH KADU 2 months ago
parent
commit
3d775be7b0
  1. 20
      steps/index.html
  2. 1
      steps/src/dom.js
  3. 36
      steps/src/main.js

20
steps/index.html

@ -264,11 +264,11 @@
</button>
</div>
<div class="bg-white dark:bg-gray-800 rounded-2xl shadow-[0_0_50px_rgba(0,0,0,0.2)] p-10 w-full max-w-2xl text-center border border-gray-200 dark:border-gray-700">
<div class="bg-white dark:bg-gray-800 rounded-2xl shadow-[0_0_50px_rgba(0,0,0,0.2)] p-10 w-full max-w-4xl text-center border border-gray-200 dark:border-gray-700 relative z-10">
<h1 class="text-4xl font-bold text-gray-900 dark:text-white mb-2 tracking-tight">Data Synchronizer</h1>
<p class="text-gray-500 dark:text-gray-400 mb-8 text-lg">Provide radar dataset and video parameters to initialize workspace</p>
<div id="start-drop-zone" class="border-4 border-dashed border-gray-300 dark:border-gray-600 rounded-xl p-12 mb-8 hover:border-blue-500 hover:bg-blue-50 dark:hover:bg-gray-700 transition-colors cursor-pointer group">
<div id="start-drop-zone" class="border-4 border-dashed border-gray-300 dark:border-gray-600 rounded-xl p-20 mb-8 hover:border-blue-500 hover:bg-blue-50 dark:hover:bg-gray-700 transition-colors cursor-pointer group">
<svg class="mx-auto h-16 w-16 text-gray-400 group-hover:text-blue-500 transition-colors mb-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" />
</svg>
@ -299,6 +299,8 @@
<div id="start-progress-text" class="text-sm font-medium text-gray-700 dark:text-gray-300 mt-2 text-center animate-pulse">Initializing...</div>
</div>
</div>
</div>
</div>
<header class="bg-white dark:bg-gray-800 shadow-md pt-0 px-4 pb-4 z-20 relative">
<h1 class="text-2xl font-bold text-gray-900 dark:text-white">
@ -774,6 +776,20 @@
<input type="file" id="json-file-input" class="hidden" accept=".json" />
<input type="file" id="video-file-input" class="hidden" accept="video/*" />
<input type="file" id="session-file-input" class="hidden" accept=".json" />
<!-- Global drag-and-drop overlay -->
<div id="global-drag-overlay" class="fixed inset-0 z-[60] flex items-center justify-center bg-blue-600/30 backdrop-blur-sm border-8 border-dashed border-blue-500 rounded-3xl m-4 pointer-events-none opacity-0 transition-opacity duration-300">
<div class="bg-blue-600 text-white px-10 py-5 rounded-2xl shadow-2xl flex items-center gap-6 border-4 border-blue-400">
<svg class="h-16 w-16 animate-bounce" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" />
</svg>
<div class="text-left">
<span class="text-4xl font-extrabold block">Drop to Load Data</span>
<span class="text-lg font-medium opacity-90">Updating session with new files...</span>
</div>
</div>
</div>
<script type="module" src="./src/main.js"></script>
</body>

1
steps/src/dom.js

@ -38,6 +38,7 @@ export const startChangelogBtn = document.getElementById("start-changelog-btn");
export const startThemeToggleBtn = document.getElementById("start-theme-toggle");
export const startThemeToggleDarkIcon = document.getElementById("start-theme-toggle-dark-icon");
export const startThemeToggleLightIcon = document.getElementById("start-theme-toggle-light-icon");
export const globalDragOverlay = document.getElementById("global-drag-overlay");
export const themeToggleBtn = document.getElementById("theme-toggle");
export const canvasContainer = document.getElementById("canvas-container");

36
steps/src/main.js

@ -58,6 +58,7 @@ import {
startLoadJsonBtn,
startLoadVideoBtn,
startClearCacheBtn,
globalDragOverlay,
} from "./dom.js";
import { initializeTheme } from "./theme.js";
@ -74,27 +75,36 @@ videoFileInput.addEventListener("change", (event) =>
handleFiles(event.target.files)
);
// Wire up the drag-and-drop functionality for the start screen
startDropZone.addEventListener("dragover", (event) => {
// Wire up the universal drag-and-drop functionality
let dragCounter = 0;
document.body.addEventListener("dragenter", (event) => {
event.preventDefault();
startDropZone.classList.add("border-blue-500", "bg-blue-50", "dark:bg-gray-700");
});
startDropZone.addEventListener("dragleave", () => {
startDropZone.classList.remove("border-blue-500", "bg-blue-50", "dark:bg-gray-700");
dragCounter++;
if (dragCounter === 1) {
globalDragOverlay.classList.remove("opacity-0");
globalDragOverlay.classList.add("opacity-100");
}
});
startDropZone.addEventListener("drop", (event) => {
document.body.addEventListener("dragover", (event) => {
event.preventDefault();
startDropZone.classList.remove("border-blue-500", "bg-blue-50", "dark:bg-gray-700");
handleFiles(event.dataTransfer.files);
});
// Also keep the main body as a backup drop zone for modifying active sessions
const mainDropZone = document.querySelector("main");
mainDropZone.addEventListener("dragover", (event) => {
document.body.addEventListener("dragleave", (event) => {
event.preventDefault();
dragCounter--;
if (dragCounter === 0) {
globalDragOverlay.classList.remove("opacity-100");
globalDragOverlay.classList.add("opacity-0");
}
});
mainDropZone.addEventListener("drop", (event) => {
document.body.addEventListener("drop", (event) => {
event.preventDefault();
dragCounter = 0;
globalDragOverlay.classList.remove("opacity-100");
globalDragOverlay.classList.add("opacity-0");
handleFiles(event.dataTransfer.files);
});

Loading…
Cancel
Save