Spaces:
Sleeping
Sleeping
Update src/components/LoadingScreen.tsx
Browse files
src/components/LoadingScreen.tsx
CHANGED
|
@@ -16,6 +16,7 @@ type Dot = {
|
|
| 16 |
pulse: number;
|
| 17 |
pulseSpeed: number;
|
| 18 |
};
|
|
|
|
| 19 |
export const LoadingScreen = ({
|
| 20 |
isLoading,
|
| 21 |
progress,
|
|
@@ -44,7 +45,7 @@ export const LoadingScreen = ({
|
|
| 44 |
const canvasRef = useRef<HTMLCanvasElement>(null);
|
| 45 |
const dropdownBtnRef = useRef<HTMLButtonElement>(null);
|
| 46 |
const dropdownRef = useRef<HTMLDivElement>(null);
|
| 47 |
-
const wrapperRef = useRef<HTMLDivElement>(null);
|
| 48 |
|
| 49 |
// For keyboard navigation
|
| 50 |
const [activeIndex, setActiveIndex] = useState(
|
|
@@ -54,7 +55,7 @@ export const LoadingScreen = ({
|
|
| 54 |
)
|
| 55 |
);
|
| 56 |
|
| 57 |
-
// Background Animation Effect
|
| 58 |
useEffect(() => {
|
| 59 |
const canvas = canvasRef.current;
|
| 60 |
if (!canvas) return;
|
|
@@ -198,7 +199,7 @@ export const LoadingScreen = ({
|
|
| 198 |
return () => window.removeEventListener("resize", onResize);
|
| 199 |
}, []);
|
| 200 |
|
| 201 |
-
// Compute portal style
|
| 202 |
const portalStyle = useMemo(() => {
|
| 203 |
if (typeof window === "undefined") return {};
|
| 204 |
const anchor = wrapperRef.current || dropdownBtnRef.current;
|
|
@@ -221,7 +222,7 @@ export const LoadingScreen = ({
|
|
| 221 |
// Flip up if not enough space below
|
| 222 |
const spaceBelow = window.innerHeight - rect.bottom;
|
| 223 |
const spaceAbove = rect.top;
|
| 224 |
-
const estimatedItemH = 56;
|
| 225 |
const estimatedPad = 16;
|
| 226 |
const estimatedHeight =
|
| 227 |
estimatedItemH * Math.min(MODEL_OPTIONS.length, 6) + estimatedPad;
|
|
@@ -234,7 +235,7 @@ export const LoadingScreen = ({
|
|
| 234 |
left: `${left}px`,
|
| 235 |
top: `${top}px`,
|
| 236 |
width: `${dropdownWidth}px`,
|
| 237 |
-
zIndex:
|
| 238 |
};
|
| 239 |
}, []);
|
| 240 |
|
|
@@ -343,7 +344,7 @@ export const LoadingScreen = ({
|
|
| 343 |
rel="noopener noreferrer"
|
| 344 |
className="text-indigo-400 hover:underline"
|
| 345 |
>
|
| 346 |
-
Liquid AI
|
| 347 |
</a>{" "}
|
| 348 |
LFM2 hybrid models, optimized for on-device deployment and edge AI
|
| 349 |
scenarios.
|
|
@@ -373,7 +374,7 @@ export const LoadingScreen = ({
|
|
| 373 |
|
| 374 |
<div className="relative">
|
| 375 |
<div
|
| 376 |
-
ref={wrapperRef}
|
| 377 |
className="flex rounded-2xl shadow-2xl overflow-hidden"
|
| 378 |
>
|
| 379 |
<button
|
|
@@ -461,7 +462,7 @@ export const LoadingScreen = ({
|
|
| 461 |
style={portalStyle}
|
| 462 |
role="menu"
|
| 463 |
aria-label="Model options"
|
| 464 |
-
className="bg-gray-800/95 border border-gray-600/50 rounded-2xl shadow-2xl overflow-hidden animate-in slide-in-from-top-2 duration-200
|
| 465 |
>
|
| 466 |
{MODEL_OPTIONS.map((option, index) => {
|
| 467 |
const selected = selectedModelId === option.id;
|
|
@@ -532,7 +533,7 @@ export const LoadingScreen = ({
|
|
| 532 |
{/* Click-away fallback for touch devices */}
|
| 533 |
{isModelDropdownOpen && (
|
| 534 |
<div
|
| 535 |
-
className="fixed inset-0 z-
|
| 536 |
onClick={(e) => {
|
| 537 |
const target = e.target as Node;
|
| 538 |
if (
|
|
|
|
| 16 |
pulse: number;
|
| 17 |
pulseSpeed: number;
|
| 18 |
};
|
| 19 |
+
|
| 20 |
export const LoadingScreen = ({
|
| 21 |
isLoading,
|
| 22 |
progress,
|
|
|
|
| 45 |
const canvasRef = useRef<HTMLCanvasElement>(null);
|
| 46 |
const dropdownBtnRef = useRef<HTMLButtonElement>(null);
|
| 47 |
const dropdownRef = useRef<HTMLDivElement>(null);
|
| 48 |
+
const wrapperRef = useRef<HTMLDivElement>(null);
|
| 49 |
|
| 50 |
// For keyboard navigation
|
| 51 |
const [activeIndex, setActiveIndex] = useState(
|
|
|
|
| 55 |
)
|
| 56 |
);
|
| 57 |
|
| 58 |
+
// Background Animation Effect
|
| 59 |
useEffect(() => {
|
| 60 |
const canvas = canvasRef.current;
|
| 61 |
if (!canvas) return;
|
|
|
|
| 199 |
return () => window.removeEventListener("resize", onResize);
|
| 200 |
}, []);
|
| 201 |
|
| 202 |
+
// Compute portal style
|
| 203 |
const portalStyle = useMemo(() => {
|
| 204 |
if (typeof window === "undefined") return {};
|
| 205 |
const anchor = wrapperRef.current || dropdownBtnRef.current;
|
|
|
|
| 222 |
// Flip up if not enough space below
|
| 223 |
const spaceBelow = window.innerHeight - rect.bottom;
|
| 224 |
const spaceAbove = rect.top;
|
| 225 |
+
const estimatedItemH = 56;
|
| 226 |
const estimatedPad = 16;
|
| 227 |
const estimatedHeight =
|
| 228 |
estimatedItemH * Math.min(MODEL_OPTIONS.length, 6) + estimatedPad;
|
|
|
|
| 235 |
left: `${left}px`,
|
| 236 |
top: `${top}px`,
|
| 237 |
width: `${dropdownWidth}px`,
|
| 238 |
+
zIndex: 9999,
|
| 239 |
};
|
| 240 |
}, []);
|
| 241 |
|
|
|
|
| 344 |
rel="noopener noreferrer"
|
| 345 |
className="text-indigo-400 hover:underline"
|
| 346 |
>
|
| 347 |
+
Liquid AI's
|
| 348 |
</a>{" "}
|
| 349 |
LFM2 hybrid models, optimized for on-device deployment and edge AI
|
| 350 |
scenarios.
|
|
|
|
| 374 |
|
| 375 |
<div className="relative">
|
| 376 |
<div
|
| 377 |
+
ref={wrapperRef}
|
| 378 |
className="flex rounded-2xl shadow-2xl overflow-hidden"
|
| 379 |
>
|
| 380 |
<button
|
|
|
|
| 462 |
style={portalStyle}
|
| 463 |
role="menu"
|
| 464 |
aria-label="Model options"
|
| 465 |
+
className="bg-gray-800/95 border border-gray-600/50 rounded-2xl shadow-2xl overflow-hidden animate-in slide-in-from-top-2 duration-200"
|
| 466 |
>
|
| 467 |
{MODEL_OPTIONS.map((option, index) => {
|
| 468 |
const selected = selectedModelId === option.id;
|
|
|
|
| 533 |
{/* Click-away fallback for touch devices */}
|
| 534 |
{isModelDropdownOpen && (
|
| 535 |
<div
|
| 536 |
+
className="fixed inset-0 z-[9998] bg-black/20"
|
| 537 |
onClick={(e) => {
|
| 538 |
const target = e.target as Node;
|
| 539 |
if (
|