Browse Source

feat: Isolate modal and theme logic into modules

Refactored the modal and theme-switching functionality out of the main script.

- Created src/modal.js to handle all logic for the confirmation modal.
- Created src/theme.js to manage the dark/light theme and canvas redraws.
- The main script now imports and initializes these modules, cleaning up the global scope.
refactor/modularize
RUSHIL AMBARISH KADU 9 months ago
parent
commit
ad6270583f
  1. 78
      steps/index.html
  2. 33
      steps/src/modal.js
  3. 48
      steps/src/theme.js

78
steps/index.html

@ -298,81 +298,22 @@
toggleClusterColor, toggleInlierColor, toggleStationaryColor, toggleVelocity, toggleClusterColor, toggleInlierColor, toggleStationaryColor, toggleVelocity,
toggleTracks, toggleEgoSpeed, toggleFrameNorm, toggleDebugOverlay, egoSpeedDisplay, toggleTracks, toggleEgoSpeed, toggleFrameNorm, toggleDebugOverlay, egoSpeedDisplay,
canSpeedDisplay, debugOverlay, snrMinInput, snrMaxInput, applySnrBtn, autoOffsetIndicator, canSpeedDisplay, debugOverlay, snrMinInput, snrMaxInput, applySnrBtn, autoOffsetIndicator,
clearCacheBtn, speedGraphContainer, speedGraphPlaceholder, modalContainer, modalOverlay,
modalContent, modalText, modalOkBtn, modalCancelBtn, toggleCloseUp,
clearCacheBtn, speedGraphContainer, speedGraphPlaceholder, toggleCloseUp,
//---UI Updaters---// //---UI Updaters---//
updateFrame, resetVisualization, updateCanDisplay, updateDebugOverlay updateFrame, resetVisualization, updateCanDisplay, updateDebugOverlay
} from './src/dom.js'; } from './src/dom.js';
// --- DARK MODE: Step 3 - Add the JavaScript Logic ---
const themeToggleBtn = document.getElementById('theme-toggle');
const darkIcon = document.getElementById('theme-toggle-dark-icon');
const lightIcon = document.getElementById('theme-toggle-light-icon');
function setTheme(theme) {
if (theme === 'dark') {
document.documentElement.classList.add('dark');
lightIcon.classList.remove('hidden');
darkIcon.classList.add('hidden');
localStorage.setItem('color-theme', 'dark');
} else {
document.documentElement.classList.remove('dark');
darkIcon.classList.remove('hidden');
lightIcon.classList.add('hidden');
localStorage.setItem('color-theme', 'light');
}
if (appState.p5_instance) appState.p5_instance.redraw();
if (appState.speedGraphInstance) {
if ((appState.canData.length > 0 || appState.vizData) && videoPlayer.duration) {
appState.speedGraphInstance.setData(appState.canData, appState.vizData, videoPlayer.duration);
}
appState.speedGraphInstance.redraw();
}
}
const savedTheme = localStorage.getItem('color-theme');
if (savedTheme) {
setTheme(savedTheme);
} else {
// Default to light mode if no theme is saved
setTheme('light');
}
// import modal dialog logic from './src/modal.js';
import {
showModal
} from './src/modal.js';
themeToggleBtn.addEventListener('click', () => {
if (document.documentElement.classList.contains('dark')) {
setTheme('light');
} else {
setTheme('dark');
}
});
// import initialize theme from './src/theme.js';
import {
initializeTheme
} from './src/theme.js';
// --- Custom Modal Logic --- //
let modalResolve = null;
function showModal(message, isConfirm = false) {
return new Promise(resolve => {
modalText.textContent = message;
modalCancelBtn.classList.toggle('hidden', !isConfirm);
modalContainer.classList.remove('hidden');
setTimeout(() => {
modalOverlay.classList.remove('opacity-0');
modalContent.classList.remove('scale-95');
}
, 10);
modalResolve = resolve;
});
}
function hideModal(value) {
modalOverlay.classList.add('opacity-0');
modalContent.classList.add('scale-95');
setTimeout(() => {
modalContainer.classList.add('hidden');
if (modalResolve) modalResolve(value);
}, 200);
}
modalOkBtn.addEventListener('click', () => hideModal(true));
modalCancelBtn.addEventListener('click', () => hideModal(false));
modalOverlay.addEventListener('click', () => hideModal(false));
// --- IndexedDB for Caching --- // --- IndexedDB for Caching ---
let db; function initDB(callback) { const request = indexedDB.open('visualizerDB', 1); request.onupgradeneeded = function (event) { const db = event.target.result; if (!db.objectStoreNames.contains('files')) { db.createObjectStore('files'); } }; request.onsuccess = function (event) { db = event.target.result; console.log("Database initialized"); if (callback) callback(); }; request.onerror = function (event) { console.error("IndexedDB error:", event.target.errorCode); }; } let db; function initDB(callback) { const request = indexedDB.open('visualizerDB', 1); request.onupgradeneeded = function (event) { const db = event.target.result; if (!db.objectStoreNames.contains('files')) { db.createObjectStore('files'); } }; request.onsuccess = function (event) { db = event.target.result; console.log("Database initialized"); if (callback) callback(); }; request.onerror = function (event) { console.error("IndexedDB error:", event.target.errorCode); }; }
@ -946,6 +887,7 @@
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
initializeTheme(); // Setup theme here as soon as DOM is loaded.
console.log("DEBUG: DOMContentLoaded fired. Starting session load."); console.log("DEBUG: DOMContentLoaded fired. Starting session load.");
initDB(() => { initDB(() => {
console.log("DEBUG: Database initialized."); console.log("DEBUG: Database initialized.");

33
steps/src/modal.js

@ -0,0 +1,33 @@
import { modalText, modalCancelBtn, modalContainer, modalOverlay, modalContent, modalOkBtn } from './dom.js';
// --- Custom Modal Logic --- //
let modalResolve = null;
export function showModal(message, isConfirm = false) {
return new Promise(resolve => {
modalText.textContent = message;
modalCancelBtn.classList.toggle('hidden', !isConfirm);
modalContainer.classList.remove('hidden');
setTimeout(() => {
modalOverlay.classList.remove('opacity-0');
modalContent.classList.remove('scale-95');
}
, 10);
modalResolve = resolve;
});
}
function hideModal(value) {
modalOverlay.classList.add('opacity-0');
modalContent.classList.add('scale-95');
setTimeout(() => {
modalContainer.classList.add('hidden');
if (modalResolve) modalResolve(value);
}, 200);
}
//----------------------Modal Event Listeners----------------------//
modalOkBtn.addEventListener('click', () => hideModal(true));
modalCancelBtn.addEventListener('click', () => hideModal(false));
modalOverlay.addEventListener('click', () => hideModal(false));

48
steps/src/theme.js

@ -0,0 +1,48 @@
import { appState } from './state.js';
// --- DARK MODE: Step 3 - Add the JavaScript Logic ---
const themeToggleBtn = document.getElementById('theme-toggle');
const darkIcon = document.getElementById('theme-toggle-dark-icon');
const lightIcon = document.getElementById('theme-toggle-light-icon');
function setTheme(theme) {
if (theme === 'dark') {
document.documentElement.classList.add('dark');
lightIcon.classList.remove('hidden');
darkIcon.classList.add('hidden');
localStorage.setItem('color-theme', 'dark');
} else {
document.documentElement.classList.remove('dark');
darkIcon.classList.remove('hidden');
lightIcon.classList.add('hidden');
localStorage.setItem('color-theme', 'light');
}
if (appState.p5_instance) appState.p5_instance.redraw();
if (appState.speedGraphInstance) {
if ((appState.canData.length > 0 || appState.vizData) && videoPlayer.duration) {
appState.speedGraphInstance.setData(appState.canData, appState.vizData, videoPlayer.duration);
}
appState.speedGraphInstance.redraw();
}
}
export function initializeTheme() {
const savedTheme = localStorage.getItem('color-theme');
if (savedTheme) {
setTheme(savedTheme);
} else {
// Default to light mode if no theme is saved
setTheme('light');
}
themeToggleBtn.addEventListener('click', () => {
if (document.documentElement.classList.contains('dark')) {
setTheme('light');
} else {
setTheme('dark');
}
});
}
Loading…
Cancel
Save