3 changed files with 0 additions and 1949 deletions
@ -1,423 +0,0 @@ |
|||
import { appState } from "./state.js"; |
|||
import { formatUTCTime } from "./utils.js"; |
|||
// Also import VIDEO_FPS from constants
|
|||
import { VIDEO_FPS } from "./constants.js"; |
|||
|
|||
// --- DOM Element References --- //
|
|||
|
|||
export const themeToggleBtn = document.getElementById("theme-toggle"); |
|||
export const canvasContainer = document.getElementById("canvas-container"); |
|||
export const canvasPlaceholder = document.getElementById("canvas-placeholder"); |
|||
export const videoPlayer = document.getElementById("video-player"); |
|||
export const videoPlaceholder = document.getElementById("video-placeholder"); |
|||
export const loadJsonBtn = document.getElementById("load-json-btn"); |
|||
export const loadVideoBtn = document.getElementById("load-video-btn"); |
|||
export const loadCanBtn = document.getElementById("load-can-btn"); |
|||
export const jsonFileInput = document.getElementById("json-file-input"); |
|||
export const videoFileInput = document.getElementById("video-file-input"); |
|||
export const canFileInput = document.getElementById("can-file-input"); |
|||
export const playPauseBtn = document.getElementById("play-pause-btn"); |
|||
export const stopBtn = document.getElementById("stop-btn"); |
|||
export const timelineSlider = document.getElementById("timeline-slider"); |
|||
export const frameCounter = document.getElementById("frame-counter"); |
|||
export const offsetInput = document.getElementById("offset-input"); |
|||
export const speedSlider = document.getElementById("speed-slider"); |
|||
export const speedDisplay = document.getElementById("speed-display"); |
|||
export const featureToggles = document.getElementById("feature-toggles"); |
|||
export const toggleSnrColor = document.getElementById("toggle-snr-color"); |
|||
export const toggleClusterColor = document.getElementById("toggle-cluster-color"); |
|||
export const toggleInlierColor = document.getElementById("toggle-inlier-color"); |
|||
export const toggleStationaryColor = document.getElementById("toggle-stationary-color"); |
|||
export const toggleVelocity = document.getElementById("toggle-velocity"); |
|||
export const toggleTracks = document.getElementById("toggle-tracks"); |
|||
export const toggleEgoSpeed = document.getElementById("toggle-ego-speed"); |
|||
export const toggleFrameNorm = document.getElementById("toggle-frame-norm"); |
|||
export const toggleDebugOverlay = document.getElementById("toggle-debug-overlay"); |
|||
export const egoSpeedDisplay = document.getElementById("ego-speed-display"); |
|||
export const canSpeedDisplay = document.getElementById("can-speed-display"); |
|||
export const debugOverlay = document.getElementById("debug-overlay"); |
|||
export const toggleDebug2Overlay = document.getElementById("toggle-debug2-overlay"); |
|||
export const snrMinInput = document.getElementById("snr-min-input"); |
|||
export const snrMaxInput = document.getElementById("snr-max-input"); |
|||
export const applySnrBtn = document.getElementById("apply-snr-btn"); |
|||
export const autoOffsetIndicator = document.getElementById("auto-offset-indicator"); |
|||
export const clearCacheBtn = document.getElementById("clear-cache-btn"); |
|||
export const speedGraphContainer = document.getElementById("speed-graph-container"); |
|||
export const speedGraphPlaceholder = document.getElementById("speed-graph-placeholder"); |
|||
export const modalContainer = document.getElementById("modal-container"); |
|||
export const modalOverlay = document.getElementById("modal-overlay"); |
|||
export const modalContent = document.getElementById("modal-content"); |
|||
export const modalText = document.getElementById("modal-text"); |
|||
export const modalOkBtn = document.getElementById("modal-ok-btn"); |
|||
export const modalCancelBtn = document.getElementById("modal-cancel-btn"); |
|||
export const toggleCloseUp = document.getElementById("toggle-close-up"); |
|||
export const togglePredictedPos = document.getElementById("toggle-predicted-pos"); |
|||
export const toggleCovariance = document.getElementById("toggle-covariance"); |
|||
export const modalProgressContainer = document.getElementById("modal-progress-container"); |
|||
export const modalProgressBar = document.getElementById("modal-progress-bar"); |
|||
export const modalProgressText = document.getElementById("modal-progress-text"); |
|||
export const timelineTooltip = document.getElementById("timeline-tooltip"); |
|||
export const radarInfoOverlay = document.getElementById("radar-info-overlay"); |
|||
export const videoInfoOverlay = document.getElementById("video-info-overlay"); |
|||
export const saveSessionBtn = document.getElementById("save-session-btn"); |
|||
export const loadSessionBtn = document.getElementById("load-session-btn"); |
|||
export const sessionFileInput = document.getElementById("session-file-input"); |
|||
export const ttcModeDefault = document.getElementById("ttc-mode-default"); |
|||
export const ttcModeCustom = document.getElementById("ttc-mode-custom"); |
|||
export const customTtcPanel = document.getElementById("custom-ttc-panel"); |
|||
export const ttcColorCritical = document.getElementById("ttc-color-critical"); |
|||
export const ttcTimeCritical = document.getElementById("ttc-time-critical"); |
|||
export const ttcColorHigh = document.getElementById("ttc-color-high"); |
|||
export const ttcTimeHigh = document.getElementById("ttc-time-high"); |
|||
export const ttcColorMedium = document.getElementById("ttc-color-medium"); |
|||
export const ttcTimeMedium = document.getElementById("ttc-time-medium"); |
|||
export const ttcColorLow = document.getElementById("ttc-color-low"); |
|||
export const collapsibleMenu = document.getElementById("collapsible-menu"); |
|||
export const toggleMenuBtn = document.getElementById("toggle-menu-btn"); |
|||
export const fullscreenBtn = document.getElementById("fullscreen-btn"); |
|||
export const mainContent = document.querySelector("main"); |
|||
export const closeMenuBtn = document.getElementById("close-menu-btn"); |
|||
export const fullscreenEnterIcon = document.getElementById("fullscreen-enter-icon"); |
|||
export const fullscreenExitIcon = document.getElementById("fullscreen-exit-icon"); |
|||
export const menuScrim = document.getElementById("menu-scrim"); |
|||
export const toggleConfirmedOnly = document.getElementById("toggle-confirmed-only"); |
|||
|
|||
|
|||
//----------------------UPDATE FRAME Function----------------------//
|
|||
// Updates the UI to reflect the current radar frame and synchronizes video playback.
|
|||
export function updateFrame(frame, forceVideoSeek) { |
|||
const startTime = performance.now(); //start emasuring timer of performance.
|
|||
if ( |
|||
!appState.vizData || |
|||
frame < 0 || |
|||
frame >= appState.vizData.radarFrames.length |
|||
) |
|||
// Exit if no visualization data or invalid frame.
|
|||
return; // Exit if no visualization data or invalid frame
|
|||
appState.currentFrame = frame; |
|||
timelineSlider.value = appState.currentFrame; |
|||
frameCounter.textContent = `Frame: ${appState.currentFrame + 1} / ${ |
|||
appState.vizData.radarFrames.length |
|||
}`;
|
|||
const frameData = appState.vizData.radarFrames[appState.currentFrame]; |
|||
if (toggleEgoSpeed.checked && frameData) { |
|||
// Update ego speed display if enabled.
|
|||
const egoVy_kmh = (frameData.egoVelocity[1] * 3.6).toFixed(1); // Convert m/s to km/h and format
|
|||
egoSpeedDisplay.textContent = `Ego: ${egoVy_kmh} km/h`; |
|||
egoSpeedDisplay.classList.remove("hidden"); |
|||
} else { |
|||
egoSpeedDisplay.classList.add("hidden"); // Hide ego speed display.
|
|||
} |
|||
|
|||
// --- ADD THIS NEW BLOCK ---
|
|||
if ( |
|||
frameData && |
|||
frameData.canVehSpeed_kmph !== null && |
|||
!isNaN(frameData.canVehSpeed_kmph) |
|||
) { |
|||
canSpeedDisplay.textContent = `CAN: ${frameData.canVehSpeed_kmph.toFixed( |
|||
1 |
|||
)} km/h`;
|
|||
canSpeedDisplay.classList.remove("hidden"); |
|||
} else { |
|||
canSpeedDisplay.classList.add("hidden"); |
|||
} |
|||
// --- END OF NEW BLOCK ---
|
|||
|
|||
let timeForUpdates = videoPlayer.currentTime; // NEW: Default to the video's current time
|
|||
|
|||
if ( |
|||
forceVideoSeek && |
|||
videoPlayer.src && |
|||
videoPlayer.readyState > 1 && |
|||
appState.videoStartDate && |
|||
frameData |
|||
) { |
|||
const offsetMs = parseFloat(offsetInput.value) || 0; |
|||
const targetRadarTimeMs = frameData.timestampMs; |
|||
const targetVideoTimeSec = (targetRadarTimeMs - offsetMs) / 1000; |
|||
if (targetVideoTimeSec >= 0 && targetVideoTimeSec <= videoPlayer.duration) { |
|||
// Ensure target time is within video duration
|
|||
if (Math.abs(videoPlayer.currentTime - targetVideoTimeSec) > 0.05) { |
|||
// Check for significant drift
|
|||
videoPlayer.currentTime = targetVideoTimeSec; // Seek video if drift is significant
|
|||
} |
|||
// MODIFIED: Use the calculated target time for our updates, not the stale videoPlayer.currentTime
|
|||
timeForUpdates = targetVideoTimeSec; // Update time for subsequent UI updates
|
|||
} |
|||
} // End of forceVideoSeek block
|
|||
|
|||
if (!appState.isPlaying) { |
|||
// MODIFIED: Use our new synchronized time variable
|
|||
updatePersistentOverlays(timeForUpdates); |
|||
} |
|||
// --- End of fix ---
|
|||
|
|||
if (appState.p5_instance) appState.p5_instance.redraw(); // Redraw radar sketch
|
|||
if (appState.speedGraphInstance && !appState.isPlaying) |
|||
// Redraw speed graph if not playing.
|
|||
appState.speedGraphInstance.redraw(); |
|||
const endTime = performance.now(); |
|||
appState.lastFrameRenderTime = endTime - startTime; // <-- End timer and update state
|
|||
|
|||
} |
|||
|
|||
//----------------------Reset UI for New file Load----------------------//
|
|||
// Resets the UI to make sure everything is clean before new files load.
|
|||
export function resetUIForNewLoad() { |
|||
console.log("Resetting UI for new file load."); |
|||
|
|||
// Hide feature toggles
|
|||
featureToggles.classList.add("hidden"); |
|||
|
|||
// Show placeholders
|
|||
canvasPlaceholder.style.display = 'flex'; |
|||
videoPlaceholder.classList.remove('hidden'); |
|||
|
|||
// Hide video player and overlays
|
|||
videoPlayer.classList.add('hidden'); |
|||
videoPlayer.src = ''; // Clear the video source
|
|||
radarInfoOverlay.classList.add('hidden'); |
|||
videoInfoOverlay.classList.add('hidden'); |
|||
|
|||
// Remove the p5 sketches completely
|
|||
if (appState.p5_instance) { |
|||
appState.p5_instance.remove(); |
|||
appState.p5_instance = null; |
|||
} |
|||
if (appState.rawP5_instance) { |
|||
appState.rawP5_instance.remove(); |
|||
appState.rawP5_instance = null; |
|||
} |
|||
if (appState.zoomSketchInstance) { |
|||
appState.zoomSketchInstance.remove(); |
|||
appState.zoomSketchInstance = null; |
|||
} |
|||
if (appState.speedGraphInstance) { |
|||
appState.speedGraphInstance.remove(); |
|||
appState.speedGraphInstance = null; |
|||
} |
|||
|
|||
// Reset the speed graph container
|
|||
speedGraphPlaceholder.classList.remove('hidden'); |
|||
} |
|||
|
|||
//----------------------RESET VISUALIZATION Function----------------------//
|
|||
// Resets the visualization to its initial state.
|
|||
export function resetVisualization() { |
|||
appState.isPlaying = false; |
|||
playPauseBtn.textContent = "Play"; |
|||
const numFrames = appState.vizData.radarFrames.length; |
|||
timelineSlider.max = numFrames > 0 ? numFrames - 1 : 0; |
|||
updateFrame(0, true); // Update to the first frame and force video seek
|
|||
} |
|||
|
|||
//----------------------CAN DISPLAY UPDATE Function----------------------//
|
|||
// Updates the CAN speed display based on the current media time.
|
|||
|
|||
//----------------------DEBUG OVERLAY UPDATE Function----------------------//
|
|||
// Updates the debug overlay with various synchronization and time information.
|
|||
export function updateDebugOverlay(currentMediaTime) { |
|||
// Check the state of both debug toggles
|
|||
const isDebug1Visible = toggleDebugOverlay.checked; |
|||
const isDebug2Visible = toggleDebug2Overlay.checked; |
|||
|
|||
// If neither is checked, hide the overlay and stop
|
|||
if (!isDebug1Visible && !isDebug2Visible) { |
|||
debugOverlay.classList.add("hidden"); // Hide debug overlay
|
|||
return; |
|||
} |
|||
// If at least one is checked, show the overlay
|
|||
debugOverlay.classList.remove("hidden"); // Show debug overlay.
|
|||
let content = []; |
|||
|
|||
// --- Logic for the original debug overlay ---
|
|||
if (isDebug1Visible) { |
|||
content.push(`--- Basic Info ---`); |
|||
if (appState.videoStartDate) { |
|||
const videoAbsoluteTimeMs = |
|||
appState.videoStartDate.getTime() + currentMediaTime * 1000; |
|||
content.push(`Media Time (s): ${currentMediaTime.toFixed(3)}`); |
|||
content.push(`Video Frame: ${Math.floor(currentMediaTime * VIDEO_FPS)}`); |
|||
content.push( |
|||
`Vid Abs Time: ${new Date(videoAbsoluteTimeMs) |
|||
.toISOString() |
|||
.split("T")[1] |
|||
.replace("Z", "")}`
|
|||
); // Format and display video absolute time
|
|||
} else { |
|||
content.push("Video not loaded..."); // Indicate video not loaded.
|
|||
} |
|||
if ( |
|||
appState.vizData && |
|||
appState.vizData.radarFrames[appState.currentFrame] |
|||
) { |
|||
content.push(`Radar Frame: ${appState.currentFrame + 1}`); |
|||
const frameTime = |
|||
appState.vizData.radarFrames[appState.currentFrame].timestampMs; |
|||
content.push( |
|||
`Radar Abs Time: ${new Date( |
|||
appState.videoStartDate.getTime() + frameTime |
|||
) |
|||
.toISOString() |
|||
.split("T")[1] |
|||
.replace("Z", "")}`
|
|||
); // Format and display radar absolute time
|
|||
} |
|||
} |
|||
|
|||
// --- Logic for the new advanced debug overlay ---
|
|||
if (isDebug2Visible) { |
|||
content.push(`--- Sync Diagnostics ---`); |
|||
if ( |
|||
appState.videoStartDate && |
|||
appState.vizData && |
|||
appState.vizData.radarFrames[appState.currentFrame] |
|||
) { |
|||
// --- START: Corrected Debug Logic ---
|
|||
const currentRadarFrame = |
|||
appState.vizData.radarFrames[appState.currentFrame]; |
|||
const targetRadarTimeMs = currentRadarFrame.timestampMs; |
|||
const offsetMs = parseFloat(offsetInput.value) || 0; // Read the current offset
|
|||
|
|||
// Make the drift calculation "offset-aware"
|
|||
const driftMs = currentMediaTime * 1000 + offsetMs - targetRadarTimeMs; |
|||
// --- END: Corrected Debug Logic ---
|
|||
|
|||
// Style the drift value to be green if sync is good, and red if it's off.
|
|||
const driftColor = Math.abs(driftMs) > 40 ? "#FF6347" : "#98FB98"; // Tomato red or Pale green
|
|||
|
|||
content.push(`Video Time (s): ${currentMediaTime.toFixed(3)}`); // Display current video time
|
|||
content.push(`Target Radar Time (ms): ${targetRadarTimeMs.toFixed(0)}`); |
|||
content.push(`Drift (ms): <b style="color: ${driftColor};">${driftMs.toFixed(0)}</b>`); |
|||
content.push(`Video Start Time: ${appState.videoStartDate.toISOString()}`); |
|||
content.push(`Radar Start Time: ${new Date(appState.radarStartTimeMs).toISOString()}`); |
|||
content.push(`Calculated Offset (ms): ${offsetInput.value}`); // Display calculated offset.
|
|||
const renderTime = appState.lastFrameRenderTime; |
|||
// Color is green if render time is under 33ms (~30fps budget), otherwise red
|
|||
const renderTimeColor = renderTime > 33 ? "#FF6347" : "#98FB98"; |
|||
content.push(`Frame Render Time: <b style="color: ${renderTimeColor};">${renderTime.toFixed(1)}ms</b>`); |
|||
const videoRenderTime = appState.videoFrameRenderTime; |
|||
// Color is green if render time is under 34ms (~30fps), otherwise red
|
|||
const videoRenderTimeColor = videoRenderTime > 34 ? "#FF6347" : "#98FB98"; |
|||
content.push(`Video Frame Time: <b style="color: ${videoRenderTimeColor};">${videoRenderTime.toFixed(1)}ms</b>`); |
|||
} else { |
|||
content.push("Load video and radar data to see sync info."); // Prompt to load data.
|
|||
} |
|||
} |
|||
|
|||
debugOverlay.innerHTML = content.join("<br>"); // Update debug overlay content.
|
|||
} |
|||
|
|||
// This function checks the state of the color toggles and returns the active mode.
|
|||
function getCurrentColorMode() { |
|||
if (toggleSnrColor.checked) return "Color by SNR (1)"; |
|||
if (toggleClusterColor.checked) return "Color by Cluster (2)"; |
|||
if (toggleInlierColor.checked) return "Color by Inlier (3)"; |
|||
if (toggleStationaryColor.checked) return "Color by Stationary (4)"; |
|||
return "Default"; // The default mode when no specific color toggle is checked
|
|||
} |
|||
|
|||
export function updatePersistentOverlays(currentMediaTime) { |
|||
// If we don't have the necessary data, hide the overlays and exit.
|
|||
const isDebug1Visible = toggleDebugOverlay.checked; |
|||
const isDebug2Visible = toggleDebug2Overlay.checked; |
|||
|
|||
if (!appState.vizData || !appState.videoStartDate) { |
|||
radarInfoOverlay.classList.add("hidden"); |
|||
videoInfoOverlay.classList.add("hidden"); |
|||
return; |
|||
} |
|||
if (isDebug1Visible && isDebug2Visible) { |
|||
radarInfoOverlay.classList.add("hidden"); |
|||
videoInfoOverlay.classList.add("hidden"); |
|||
return; |
|||
} |
|||
if(isDebug1Visible || isDebug2Visible){ |
|||
videoInfoOverlay.classList.add("hidden"); |
|||
return; |
|||
} |
|||
// Otherwise, make sure they are visible.
|
|||
radarInfoOverlay.classList.remove("hidden"); |
|||
videoInfoOverlay.classList.remove("hidden"); |
|||
|
|||
// --- Update Radar Overlay ---
|
|||
const currentRadarFrame = appState.vizData.radarFrames[appState.currentFrame]; |
|||
const frameData = appState.vizData.radarFrames[appState.currentFrame]; |
|||
const motionState = frameData.motionState; |
|||
if (currentRadarFrame) { |
|||
const absRadarTime = new Date( |
|||
appState.videoStartDate.getTime() + currentRadarFrame.timestampMs |
|||
); |
|||
const targetRadarTimeMs = currentRadarFrame.timestampMs; |
|||
const offsetMs = parseFloat(offsetInput.value) || 0; |
|||
const driftMs = currentMediaTime * 1000 + offsetMs - targetRadarTimeMs; |
|||
const driftColor = Math.abs(driftMs) > 50 ? "#FF6347" : "#98FB98"; // Tomato red or Pale green
|
|||
const colorMode = getCurrentColorMode(); |
|||
|
|||
radarInfoOverlay.innerHTML = `
|
|||
Frame: ${appState.currentFrame + 1} |
|||
Motion State: ${motionState} |
|||
| Abs Time: ${formatUTCTime(absRadarTime)} |
|||
| Color Mode: <b>${colorMode}</b> |
|||
| Drift: <b style="color: ${driftColor};">${driftMs.toFixed( |
|||
0 |
|||
)}ms </b> |
|||
`;
|
|||
} |
|||
|
|||
// --- Update Video Overlay ---
|
|||
const absVideoTime = new Date( |
|||
appState.videoStartDate.getTime() + currentMediaTime * 1000 |
|||
); |
|||
const videoFrame = Math.floor(currentMediaTime * VIDEO_FPS); |
|||
//console.warn('Could not load radarframes ', appState.vizData.radarFrames) console warning for reference
|
|||
|
|||
videoInfoOverlay.innerHTML = `
|
|||
Frame: ${videoFrame} |
|||
| Abs Time: ${formatUTCTime(absVideoTime)} |
|||
`;
|
|||
} |
|||
|
|||
const customTtcInputs = [ |
|||
ttcColorCritical, |
|||
ttcTimeCritical, |
|||
ttcColorHigh, |
|||
ttcTimeHigh, |
|||
ttcColorMedium, |
|||
ttcTimeMedium, |
|||
]; |
|||
|
|||
function updateCustomTtcScheme() { |
|||
appState.customTtcScheme.critical.time = parseFloat(ttcTimeCritical.value); |
|||
appState.customTtcScheme.critical.color = ttcColorCritical.value; |
|||
appState.customTtcScheme.high.time = parseFloat(ttcTimeHigh.value); |
|||
appState.customTtcScheme.high.color = ttcColorHigh.value; |
|||
appState.customTtcScheme.medium.time = parseFloat(ttcTimeMedium.value); |
|||
appState.customTtcScheme.medium.color = ttcColorMedium.value; |
|||
|
|||
if (appState.p5_instance) { |
|||
appState.p5_instance.redraw(); |
|||
} |
|||
} |
|||
|
|||
ttcModeDefault.addEventListener("change", () => { |
|||
if (ttcModeDefault.checked) { |
|||
appState.useCustomTtcScheme = false; |
|||
customTtcPanel.classList.add("hidden"); |
|||
if (appState.p5_instance) appState.p5_instance.redraw(); |
|||
} |
|||
}); |
|||
|
|||
ttcModeCustom.addEventListener("change", () => { |
|||
if (ttcModeCustom.checked) { |
|||
appState.useCustomTtcScheme = true; |
|||
customTtcPanel.classList.remove("hidden"); |
|||
updateCustomTtcScheme(); // Apply current custom values immediately
|
|||
} |
|||
}); |
|||
|
|||
// Add listeners to all custom inputs to update the scheme on the fly
|
|||
customTtcInputs.forEach((input) => { |
|||
input.addEventListener("input", updateCustomTtcScheme); |
|||
}); |
|||
1429
zoomsketch-issue/main.js
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1,97 +0,0 @@ |
|||
import { |
|||
modalCancelBtn, |
|||
modalContainer, |
|||
modalOverlay, |
|||
modalContent, |
|||
modalText, |
|||
modalOkBtn, |
|||
modalProgressContainer, |
|||
modalProgressBar, |
|||
modalProgressText, |
|||
} from "./dom.js"; |
|||
|
|||
let modalResolve = null; |
|||
|
|||
// The showModal function is now simpler.
|
|||
/* export function showModal(message, isConfirm = false) { |
|||
return new Promise((resolve) => { |
|||
modalText.textContent = message; |
|||
modalCancelBtn.classList.toggle("hidden"); |
|||
modalOkBtn.classList.toggle("hidden", isConfirm); |
|||
modalProgressContainer.classList.add("hidden"); // Hide progress by default
|
|||
|
|||
modalContainer.classList.remove("hidden"); |
|||
setTimeout(() => { |
|||
modalOverlay.classList.remove("opacity-0"); |
|||
modalContent.classList.remove("scale-95"); |
|||
}, 10); |
|||
modalResolve = resolve; |
|||
}); |
|||
} */ |
|||
|
|||
|
|||
|
|||
export function showModal(message, isConfirm = false) { |
|||
return new Promise((resolve) => { |
|||
modalText.textContent = message; |
|||
// This line correctly shows the "Cancel" button only when needed.
|
|||
modalCancelBtn.classList.toggle("hidden", !isConfirm); |
|||
|
|||
// --- THIS IS THE FIX ---
|
|||
// This ensures the "OK" button is always visible for this modal.
|
|||
modalOkBtn.classList.remove("hidden"); |
|||
|
|||
modalProgressContainer.classList.add("hidden"); |
|||
|
|||
modalContainer.classList.remove("hidden"); |
|||
setTimeout(() => { |
|||
modalOverlay.classList.remove("opacity-0"); |
|||
modalContent.classList.remove("scale-95"); |
|||
}, 10); |
|||
modalResolve = resolve; |
|||
}); |
|||
} |
|||
// A new function specifically for the loading modal
|
|||
export function showLoadingModal(message) { |
|||
modalText.textContent = message; |
|||
modalOkBtn.classList.add('hidden'); |
|||
modalCancelBtn.classList.add('hidden'); |
|||
modalProgressContainer.classList.remove('hidden'); |
|||
modalProgressBar.style.width = '0%'; |
|||
modalProgressText.textContent = 'Initializing...'; |
|||
|
|||
modalContainer.classList.remove("hidden"); |
|||
setTimeout(() => { |
|||
modalOverlay.classList.remove("opacity-0"); |
|||
modalContent.classList.remove("scale-95"); |
|||
}, 10); |
|||
} |
|||
|
|||
// A new function to update the progress bar and text
|
|||
export function updateLoadingModal(percent, message) { |
|||
if (modalProgressBar && modalProgressText) { |
|||
const p = Math.max(0, Math.min(100, Math.round(percent))); // Clamp between 0-100
|
|||
modalProgressBar.style.width = `${p}%`; |
|||
modalProgressText.textContent = message; |
|||
} |
|||
} |
|||
|
|||
// The hideModal function now also resets the progress bar
|
|||
export function hideModal(value) { |
|||
modalOverlay.classList.add("opacity-0"); |
|||
modalContent.classList.add("scale-95"); |
|||
setTimeout(() => { |
|||
modalContainer.classList.add("hidden"); |
|||
if (modalProgressContainer && modalProgressBar && modalProgressText) { |
|||
modalProgressContainer.classList.add("hidden"); |
|||
modalProgressBar.style.width = "0%"; |
|||
modalProgressText.textContent = ""; |
|||
} |
|||
if (modalResolve) modalResolve(value); |
|||
}, 200); |
|||
} |
|||
|
|||
// Event listeners remain the same
|
|||
modalOkBtn.addEventListener("click", () => hideModal(true)); |
|||
modalCancelBtn.addEventListener("click", () => hideModal(false)); |
|||
modalOverlay.addEventListener("click", () => hideModal(false)); |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue