Maincoder-1B-WebGPU / src /components /LoadingScreen.tsx
shreyask's picture
Upload folder using huggingface_hub
7ac2545 verified
import { useEffect, useRef } from "react";
interface Dot {
x: number;
y: number;
vx: number;
vy: number;
radius: number;
opacity: number;
}
export const LoadingScreen = ({
isLoading,
progress,
error,
onLoad,
}: {
isLoading: boolean;
progress: number;
error: string | null;
onLoad: () => void;
}) => {
const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() => {
const canvas = canvasRef.current;
if (!canvas) return;
const ctx = canvas.getContext("2d");
if (!ctx) return;
let animationFrameId: number;
let dots: Dot[] = [];
const setup = () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
dots = [];
const numDots = Math.floor((canvas.width * canvas.height) / 22000);
for (let i = 0; i < numDots; ++i) {
dots.push({
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
vx: (Math.random() - 0.5) * 0.3,
vy: (Math.random() - 0.5) * 0.3,
radius: Math.random() * 1.5 + 0.5,
opacity: Math.random() * 0.4 + 0.15,
});
}
};
const draw = () => {
if (!ctx) return;
ctx.clearRect(0, 0, canvas.width, canvas.height);
dots.forEach((dot) => {
dot.x += dot.vx;
dot.y += dot.vy;
if (dot.x <= 0 || dot.x >= canvas.width) dot.vx *= -1;
if (dot.y <= 0 || dot.y >= canvas.height) dot.vy *= -1;
ctx.beginPath();
ctx.arc(dot.x, dot.y, dot.radius, 0, Math.PI * 2);
ctx.fillStyle = `rgba(74, 222, 128, ${dot.opacity})`;
ctx.fill();
});
const maxDist = 120;
ctx.lineWidth = 0.5;
for (let i = 0; i < dots.length; i++) {
for (let j = i + 1; j < dots.length; j++) {
const dx = dots[i].x - dots[j].x;
const dy = dots[i].y - dots[j].y;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance < maxDist) {
const opacity = 1 - distance / maxDist;
ctx.strokeStyle = `rgba(74, 222, 128, ${opacity * 0.2})`;
ctx.beginPath();
ctx.moveTo(dots[i].x, dots[i].y);
ctx.lineTo(dots[j].x, dots[j].y);
ctx.stroke();
}
}
}
animationFrameId = requestAnimationFrame(draw);
};
const handleResize = () => {
cancelAnimationFrame(animationFrameId);
setup();
draw();
};
setup();
draw();
window.addEventListener("resize", handleResize);
return () => {
window.removeEventListener("resize", handleResize);
cancelAnimationFrame(animationFrameId);
};
}, []);
return (
<div className="relative flex flex-col items-center justify-center h-screen bg-gradient-to-br from-[#0a0f1a] via-[#0d1520] to-[#060a12] text-gray-100 p-8 overflow-hidden">
<canvas
ref={canvasRef}
className="absolute top-0 left-0 w-full h-full z-0"
/>
<div className="absolute top-0 left-0 w-full h-full z-10 bg-[radial-gradient(ellipse_at_center,_rgba(10,15,26,0)_30%,_rgba(6,10,18,0.9)_95%)]" />
<div className="relative z-20 max-w-2xl w-full flex flex-col items-center bg-white/5 border border-white/10 backdrop-blur-xl rounded-3xl p-10 shadow-[0_35px_65px_rgba(0,0,0,0.5)] space-y-8">
<div className="flex flex-col items-center gap-3">
<div className="text-6xl">💻</div>
<h1 className="text-4xl md:text-5xl font-bold text-white tracking-tight">
Maincoder <span className="text-emerald-400">1B</span>
</h1>
<p className="text-lg text-emerald-300/80">
In-browser code generation, powered by WebGPU
</p>
</div>
<div className="w-full text-left text-gray-300 space-y-3 text-base">
<p>
Run{" "}
<a
href="https://huggingface.co/Maincode/Maincoder-1B-ONNX"
target="_blank"
rel="noopener noreferrer"
className="text-emerald-400 hover:underline font-medium"
>
Maincoder-1B
</a>{" "}
entirely in your browser using{" "}
<a
href="https://huggingface.co/docs/transformers.js"
target="_blank"
rel="noopener noreferrer"
className="text-emerald-400 hover:underline font-medium"
>
Transformers.js
</a>{" "}
and WebGPU. No server, no data leaves your device.
</p>
<p className="text-sm text-gray-400">
A 1B-parameter code generation model achieving 76.2% on HumanEval
(~600MB download, int4 quantized). Requires a WebGPU-capable browser
(Chrome 113+).
</p>
</div>
<div className="w-full max-w-md">
<button
onClick={isLoading ? undefined : onLoad}
disabled={isLoading}
className={`w-full flex items-center justify-center font-semibold transition-all text-lg rounded-2xl border ${
isLoading
? "bg-white/5 text-gray-400 cursor-not-allowed border-white/10"
: "bg-emerald-600 hover:bg-emerald-500 text-white border-emerald-500/50 shadow-[0_15px_35px_rgba(16,185,129,0.25)]"
}`}
>
<div className="px-6 py-3.5">
{isLoading ? (
<div className="flex items-center">
<span className="inline-block w-5 h-5 border-2 border-emerald-400/80 border-t-transparent rounded-full animate-spin" />
<span className="ml-3 text-md font-medium text-emerald-300">
Downloading model... ({progress}%)
</span>
</div>
) : (
"Load Maincoder-1B"
)}
</div>
</button>
{isLoading && (
<div className="mt-4 w-full bg-white/10 rounded-full h-2 overflow-hidden">
<div
className="h-full bg-gradient-to-r from-emerald-500 to-emerald-400 rounded-full transition-all duration-300"
style={{ width: `${progress}%` }}
/>
</div>
)}
</div>
{error && (
<div className="bg-red-900/30 border border-red-500/40 rounded-2xl p-4 w-full text-center">
<p className="text-sm text-red-300">Error: {error}</p>
<button
onClick={onLoad}
className="mt-3 text-sm px-4 py-2 rounded-full bg-white/15 hover:bg-white/25 border border-white/20 text-white font-semibold transition-all"
>
Retry
</button>
</div>
)}
</div>
</div>
);
};