Spaces:
Running
Running
File size: 6,714 Bytes
ff324d9 782289e ff324d9 782289e ff324d9 782289e ff324d9 782289e ff324d9 782289e ff324d9 782289e ff324d9 782289e ff324d9 |
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 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
import HfIcon from "./HfIcon";
import GlassContainer from "./GlassContainer";
import GlassButton from "./GlassButton";
import { GLASS_EFFECTS } from "../constants";
import type React from "react";
interface WelcomeScreenProps {
onStart: () => void;
onSelectCamera?: () => void;
onSelectDisplay?: () => void;
onSelectFile?: (file: File) => void;
isSourceReady?: boolean;
}
export default function WelcomeScreen({ onStart, onSelectCamera, onSelectDisplay, onSelectFile, isSourceReady }: WelcomeScreenProps) {
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0];
if (file && onSelectFile) onSelectFile(file);
// Reset input so selecting the same file again re-triggers change
e.currentTarget.value = "";
};
return (
<div className="absolute inset-0 text-white flex items-center justify-center p-8">
<div className="max-w-2xl w-full space-y-8">
{/* Main Title Card */}
<GlassContainer
className="rounded-3xl shadow-2xl hover:scale-105 transition-transform duration-200"
role="banner"
>
<div className="p-8 text-center">
<h1 className="text-5xl font-bold text-gray-100 mb-4">FastVLM WebGPU</h1>
<p className="text-xl text-gray-300 leading-relaxed">
Real-time video captioning powered by{" "}
<a
href="https://huggingface.co/onnx-community/FastVLM-0.5B-ONNX"
className="text-blue-400 underline hover:text-blue-300 transition-colors"
target="_blank"
rel="noopener noreferrer"
aria-label="FastVLM-0.5B model on Hugging Face"
>
FastVLM-0.5B
</a>
</p>
</div>
</GlassContainer>
{/* Source Selection Card */}
<GlassContainer
bgColor={GLASS_EFFECTS.COLORS.SUCCESS_BG}
className="rounded-2xl shadow-2xl hover:scale-105 transition-transform duration-200"
role="region"
aria-label="Video source selection"
>
<div className="p-6 flex flex-col items-center gap-4">
<div className="flex flex-wrap items-center justify-center gap-3">
<GlassButton
onClick={(e) => {
e.preventDefault();
onSelectCamera?.();
}}
className="px-4 py-3 rounded-2xl"
aria-label="Use Camera"
>
Use Camera
</GlassButton>
<GlassButton
onClick={(e) => {
e.preventDefault();
onSelectDisplay?.();
}}
className="px-4 py-3 rounded-2xl"
aria-label="Share Tab or Screen"
>
Share Tab/Screen
</GlassButton>
<div>
<input
id="video-file-input"
type="file"
accept="video/*"
onChange={handleFileChange}
className="hidden"
/>
<GlassButton
onClick={(e) => {
e.preventDefault();
document.getElementById("video-file-input")?.click();
}}
className="px-4 py-3 rounded-2xl"
aria-label="Upload Video"
>
Upload Video
</GlassButton>
</div>
</div>
<GlassButton
onClick={onStart}
className="px-8 py-4 rounded-2xl"
aria-label="Start live captioning with AI model"
disabled={!isSourceReady}
>
<span className="font-semibold text-lg">Start Live Captioning</span>
</GlassButton>
</div>
</GlassContainer>
{/* How It Works Card */}
<GlassContainer
className="rounded-2xl shadow-2xl hover:scale-105 transition-transform duration-200"
role="region"
aria-labelledby="how-it-works-title"
>
<div className="p-6">
<h2 id="how-it-works-title" className="text-lg font-semibold text-gray-200 mb-4 text-center">
How it works:
</h2>
<div className="space-y-3">
<div className="flex items-start space-x-3">
<div className="w-6 h-6 rounded-full bg-blue-600 flex items-center justify-center text-sm font-bold mt-0.5 flex-shrink-0">
1
</div>
<p className="text-gray-300">
You are about to load{" "}
<a
href="https://huggingface.co/onnx-community/FastVLM-0.5B-ONNX"
className="text-blue-400 underline"
target="_blank"
rel="noopener noreferrer"
>
FastVLM-0.5B
</a>
, a powerful multimodal model optimized for in-browser inference.
</p>
</div>
<div className="flex items-start space-x-3">
<div className="w-6 h-6 rounded-full bg-blue-600 flex items-center justify-center text-sm font-bold mt-0.5 flex-shrink-0">
2
</div>
<p className="text-gray-300">
Everything runs entirely in your browser with{" "}
<a
href="https://github.com/huggingface/transformers.js"
className="text-blue-400 underline"
target="_blank"
rel="noopener noreferrer"
>
<HfIcon className="inline-flex w-7 h-7 pointer-events-none" />
Transformers.js
</a>{" "}
and ONNX Runtime Web, meaning no data is sent to a server. It can even run offline!
</p>
</div>
<div className="flex items-start space-x-3">
<div className="w-6 h-6 rounded-full bg-blue-600 flex items-center justify-center text-sm font-bold mt-0.5 flex-shrink-0">
3
</div>
<p className="text-gray-300">Get started by clicking the button below.</p>
</div>
</div>
</div>
</GlassContainer>
<div className="flex flex-col items-center space-y-4">
<p className="text-sm text-gray-400 opacity-80">AI model will load when you click start</p>
</div>
</div>
</div>
);
}
|