All files / src App.jsx

58.33% Statements 7/12
81.81% Branches 9/11
50% Functions 2/4
70% Lines 7/10

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;