Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | 7x 7x 7x 7x 7x 7x 7x | import { Suspense, useState, useRef, useEffect } from 'react';
import { SimulationProvider } from './context/SimulationContext';
import { ParametersProvider } from './context/ParametersContext';
import { ThemeProvider } from './context/ThemeContext';
import { ToastProvider } from './components/Toast';
import { ContextMenuProvider } from './components/ContextMenu';
import SimulationCanvas from './components/SimulationCanvas';
import ControlPanel from './components/ControlPanel';
import EnergyGraph from './components/EnergyGraph';
import SimulationInfo from './components/SimulationInfo';
import HeaderControls from './components/HeaderControls';
import HamburgerMenu from './components/HamburgerMenu';
import ThemeToggle from './components/ThemeToggle';
import FPSCounter from './components/FPSCounter';
import AtomLegend from './components/AtomLegend';
import ZoomControls from './components/ZoomControls';
import FullscreenButton from './components/FullscreenButton';
import KeyboardShortcuts from './components/KeyboardShortcuts';
import LoadingSpinner from './components/LoadingSpinner';
import AutoSaveManager from './components/AutoSaveManager';
import './styles/App.css';
/**
* Main Application Component
* Molecular Dynamics Simulation with ReaxFF Force Field
*/
function App({ skipLoading = false }) {
// Skip loading animation in test environment
const isTestEnv = typeof process !== 'undefined' && process.env?.NODE_ENV === 'test';
const [isLoading, setIsLoading] = useState(!skipLoading && !isTestEnv);
const canvasContainerRef = useRef(null);
// Simulate initial load
useEffect(() => {
Iif (!skipLoading && !isTestEnv) {
const timer = setTimeout(() => setIsLoading(false), 1500);
return () => clearTimeout(timer);
}
}, [skipLoading, isTestEnv]);
Iif (isLoading) {
return <LoadingSpinner message="Initializing simulation..." />;
}
return (
<ThemeProvider>
<ToastProvider>
<ContextMenuProvider>
<ParametersProvider>
<SimulationProvider>
<div className="app">
<header className="app-header">
<div className="header-content">
<div className="header-actions">
<HamburgerMenu />
</div>
<div className="header-title">
<h1>
Molecular Dynamics Simulation
</h1>
<p className="subtitle">ReaxFF Reactive Force Field</p>
</div>
<div className="header-right">
<ThemeToggle />
<HeaderControls />
</div>
</div>
</header>
<main className="app-main">
<div className="simulation-container" ref={canvasContainerRef}>
<SimulationInfo />
<div className="canvas-wrapper">
<FPSCounter />
<AtomLegend />
<SimulationCanvas />
<ZoomControls />
<div className="canvas-bottom-right">
<FullscreenButton targetRef={canvasContainerRef} />
</div>
</div>
</div>
<aside className="sidebar">
<ControlPanel />
<EnergyGraph />
</aside>
</main>
<footer className="app-footer">
<p>Use arrow keys to control the player atom • Press <kbd>Shift</kbd> + <kbd>?</kbd> for shortcuts</p>
</footer>
<KeyboardShortcuts />
<AutoSaveManager />
</div>
</SimulationProvider>
</ParametersProvider>
</ContextMenuProvider>
</ToastProvider>
</ThemeProvider>
);
}
export default App;
|