import { ComponentPropsWithoutRef, useEffect, useRef, useState } from "react"; import { MessageSquareQuote, SendIcon, X } from "lucide-react"; import furinaImg from "@/assets/furina.webp"; import hydroElement from "@/assets/hydro.svg"; import dotPattern from "@/assets/dotpattern.svg"; import logo from "@/assets/logo.svg"; import furinaAvatar from "@/assets/furina-avatar.webp"; import { cn } from "./utils"; import { useIsMobile } from "./hooks/useScreen"; const ParallaxView = ({ depth, style, ...props }: ComponentPropsWithoutRef<"div"> & { depth: number }) => { const ref = useRef(null); const isMobile = useIsMobile(); useEffect(() => { const el = ref.current; if (!el || isMobile) { return; } const onMouseMove = (e: MouseEvent) => { const x = e.clientX * -depth; const y = e.clientY * -depth; el.style.transform = `${ style?.transform || "" } translateX(${x}px) translateY(${y}px)`; }; document.addEventListener("mousemove", onMouseMove); return () => { document.removeEventListener("mousemove", onMouseMove); }; }, [isMobile]); return
; }; const App = () => { return (
{/*
*/}
); }; type ChatMessage = { name: string; role: "assistant" | "user"; text: string; }; const ChatWindow = () => { const containerRef = useRef(null); const moveWindowStateRef = useRef({ isMoving: false, x: 0, y: 0, startX: 0, startY: 0, }); const isMobile = useIsMobile(); const [isOpen, setOpen] = useState(false); const [messages, setMessages] = useState([ { name: "Furina", role: "assistant", text: "Ah, akhirnya seseorang yang mengerti betapa pentingnya kehadiranku! Tapi, hmm... Kau ingin apa dariku? Jangan bilang ini hanya sapaan biasa!", }, ]); const onMouseDown = (e: React.MouseEvent) => { if (isMobile) { if (isOpen) { setOpen(false); } return; } if (moveWindowStateRef.current.isMoving) { return; } e.preventDefault(); e.stopPropagation(); moveWindowStateRef.current.isMoving = true; moveWindowStateRef.current.startX = e.clientX - moveWindowStateRef.current.x; moveWindowStateRef.current.startY = e.clientY - moveWindowStateRef.current.y; }; const onMouseMove = (e: MouseEvent) => { const container = containerRef.current; if (isMobile || !moveWindowStateRef.current.isMoving || !container) { return; } const x = e.clientX - moveWindowStateRef.current.startX; const y = e.clientY - moveWindowStateRef.current.startY; moveWindowStateRef.current.x = x; moveWindowStateRef.current.y = y; container.style.transform = `translate(${x}px, ${y}px)`; }; const onMouseUp = () => { moveWindowStateRef.current.isMoving = false; }; const onSubmit = (e: React.FormEvent) => { e.preventDefault(); const form = e.target as HTMLFormElement; const data = new FormData(form); try { setMessages([ { name: "Furina", role: "assistant", text: "...?", }, { name: "Me", role: "user", text: data.get("text") as string, }, ...messages, ]); form.reset(); } catch (err) { console.log(err); } }; useEffect(() => { document.addEventListener("mousemove", onMouseMove); document.addEventListener("mouseup", onMouseUp); document.addEventListener("pointermove", onMouseMove); document.addEventListener("pointerup", onMouseUp); return () => { document.removeEventListener("mousemove", onMouseMove); document.removeEventListener("mouseup", onMouseUp); document.removeEventListener("pointermove", onMouseMove); document.removeEventListener("pointerup", onMouseUp); }; }, []); return ( <>
{messages.map((msg, idx) => { const isMe = msg.role === "user"; return (
{msg.role === "assistant" && (
)}

{msg.name}

{msg.text}

); })}
); }; export default App;