|
|
"use client"; |
|
|
import Loading from "@/components/loading"; |
|
|
import { useState, useEffect } from "react"; |
|
|
import { useInterval } from "react-use"; |
|
|
|
|
|
const TEXTS = [ |
|
|
"Teaching pixels to dance with style...", |
|
|
"AI is having a creative breakthrough...", |
|
|
"Channeling digital vibes into pure code...", |
|
|
"Summoning the website spirits...", |
|
|
"Brewing some algorithmic magic...", |
|
|
"Composing a symphony of divs and spans...", |
|
|
"Riding the wave of computational creativity...", |
|
|
"Aligning the stars for perfect design...", |
|
|
"Training circus animals to write CSS...", |
|
|
"Launching ideas into the digital stratosphere...", |
|
|
]; |
|
|
|
|
|
export const AiLoading = ({ |
|
|
text, |
|
|
className, |
|
|
}: { |
|
|
text?: string; |
|
|
className?: string; |
|
|
}) => { |
|
|
const [selectedText, setSelectedText] = useState( |
|
|
text ?? TEXTS[0] |
|
|
); |
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
if (!text) { |
|
|
setSelectedText(TEXTS[Math.floor(Math.random() * TEXTS.length)]); |
|
|
} |
|
|
}, [text]); |
|
|
|
|
|
useInterval(() => { |
|
|
if (!text) { |
|
|
if (selectedText === TEXTS[TEXTS.length - 1]) { |
|
|
setSelectedText(TEXTS[0]); |
|
|
} else { |
|
|
setSelectedText(TEXTS[TEXTS.indexOf(selectedText) + 1]); |
|
|
} |
|
|
} |
|
|
}, 12000); |
|
|
return ( |
|
|
<div className={`flex items-center justify-start gap-2 ${className}`}> |
|
|
<Loading overlay={false} className="!size-5 opacity-50" /> |
|
|
<p className="text-neutral-400 text-sm"> |
|
|
<span className="inline-flex"> |
|
|
{selectedText.split("").map((char, index) => ( |
|
|
<span |
|
|
key={index} |
|
|
className="bg-gradient-to-r from-neutral-100 to-neutral-300 bg-clip-text text-transparent animate-pulse" |
|
|
style={{ |
|
|
animationDelay: `${index * 0.1}s`, |
|
|
animationDuration: "1.3s", |
|
|
animationIterationCount: "infinite", |
|
|
}} |
|
|
> |
|
|
{char === " " ? "\u00A0" : char} |
|
|
</span> |
|
|
))} |
|
|
</span> |
|
|
</p> |
|
|
</div> |
|
|
); |
|
|
}; |
|
|
|