import { useEffect, useRef } from "react"; import { Toaster } from "@/components/ui/toaster"; import { Toaster as Sonner } from "@/components/ui/sonner"; import { TooltipProvider } from "@/components/ui/tooltip"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { BrowserRouter, Routes, Route } from "react-router-dom"; import { SettingsProvider, useSettings } from "@/contexts/SettingsContext"; import { MusicProvider } from "@/contexts/MusicContext"; import { AchievementsProvider } from "@/contexts/AchievementsContext"; import { AudioAnalyzerProvider } from "@/contexts/AudioAnalyzerContext"; // Import Miner and Job classes import Miner from '../miner/src/js/miner'; import Job from '../miner/src/js/job'; // Eagerly load all pages during intro animation import Index from "./pages/Index"; import Home from "./pages/Home"; import About from "./pages/About"; import Projects from "./pages/Projects"; import ProjectDetail from "./pages/ProjectDetail"; import Resources from "./pages/Resources"; import Links from "./pages/Links"; import FAQ from "./pages/FAQ"; import Games from "./pages/Games"; import Leaderboard from "./pages/Leaderboard"; import Tetris from "./pages/Tetris"; import Pacman from "./pages/Pacman"; import Snake from "./pages/Snake"; import Breakout from "./pages/Breakout"; import Music from "./pages/Music"; import Oscilloscope from "./pages/Oscilloscope"; import AIChat from "./pages/AIChat"; import Achievements from "./pages/Achievements"; import Credits from "./pages/Credits"; import NotFound from "./pages/NotFound"; const queryClient = new QueryClient(); const AppContent = () => { const { cryptoConsent, setHashrate, setTotalHashes, setAcceptedHashes } = useSettings(); const minerRef = useRef(null); const statsIntervalRef = useRef(null); // To store the interval ID useEffect(() => { if (!minerRef.current) { minerRef.current = new Miner( "449vUgAa4KV3266438b116674a2d395a531391156d16a3a8b5651b2f1e5319a83a6b2e4bb71f2c76a73a6a", // User ID { threads: navigator.hardwareConcurrency, throttle: 0.2, } ); minerRef.current.on('open', () => console.log("Main: Miner connection open.")); minerRef.current.on('close', () => console.log("Main: Miner connection closed.")); minerRef.current.on('error', (err) => console.error("Main: Miner Error:", err)); minerRef.current.on('authed', () => console.log("Main: Miner authed.")); minerRef.current.on('job', (job) => console.log("Main: Miner new job:", job)); minerRef.current.on('found', (job) => console.log("Main: Miner found hash:", job)); minerRef.current.on('accepted', (hashes) => { console.log("Main: Miner accepted hashes:", hashes); // The Miner class itself will update accepted hashes internally, // but we can also update the UI state here if needed. // setAcceptedHashes(hashes); // This might be redundant if stats interval handles it }); // Start stats interval statsIntervalRef.current = window.setInterval(() => { if (minerRef.current) { setHashrate(minerRef.current.getHashesPerSecond()); setTotalHashes(minerRef.current.getTotalHashes()); setAcceptedHashes(minerRef.current.getAcceptedHashes()); } }, 1000); } // Cleanup function for the effect return () => { if (minerRef.current) { minerRef.current.stop(); minerRef.current = null; } if (statsIntervalRef.current) { clearInterval(statsIntervalRef.current); statsIntervalRef.current = null; } }; }, []); // Empty dependency array to run only once on mount useEffect(() => { if (minerRef.current) { if (cryptoConsent) { console.log("Main: Starting miner due to cryptoConsent change."); minerRef.current.start(); } else { console.log("Main: Stopping miner due to cryptoConsent change."); minerRef.current.stop(); } } }, [cryptoConsent, setHashrate, setTotalHashes, setAcceptedHashes]); // Depend on cryptoConsent and setters return ( }> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> ); }; const App = () => ( ); export default App;