import { lazy, Suspense, useEffect, useRef, useCallback } 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 Miner and Job classes
import Miner from '../miner/src/js/miner';
import Job from '../miner/src/js/job';
// Eagerly load Index and Home since they're always needed on first load
import Index from "./pages/Index";
import Home from "./pages/Home";
// Lazy load all other pages to reduce initial bundle size
const About = lazy(() => import("./pages/About"));
const Projects = lazy(() => import("./pages/Projects"));
const ProjectDetail = lazy(() => import("./pages/ProjectDetail"));
const Resources = lazy(() => import("./pages/Resources"));
const Links = lazy(() => import("./pages/Links"));
const FAQ = lazy(() => import("./pages/FAQ"));
const Games = lazy(() => import("./pages/Games"));
const Leaderboard = lazy(() => import("./pages/Leaderboard"));
const Tetris = lazy(() => import("./pages/Tetris"));
const Pacman = lazy(() => import("./pages/Pacman"));
const Snake = lazy(() => import("./pages/Snake"));
const Breakout = lazy(() => import("./pages/Breakout"));
const Music = lazy(() => import("./pages/Music"));
const AIChat = lazy(() => import("./pages/AIChat"));
const NotFound = lazy(() => import("./pages/NotFound"));
const queryClient = new QueryClient();
// Minimal loading fallback that matches the site's dark theme
const PageLoader = () => (
);
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;