diff --git a/src/components/AudioRecorder.tsx b/src/components/AudioRecorder.tsx index bee57ac..8011960 100644 --- a/src/components/AudioRecorder.tsx +++ b/src/components/AudioRecorder.tsx @@ -12,6 +12,7 @@ export default function AudioRecorder() { const messages = useConversation((state) => state.messages); const addMessage = useConversation((state) => state.addMessage); const setMessageResult = useConversation((state) => state.setMessageResult); + const setThinking = useConversation((state) => state.setThinking); const handleRecordClick = () => { if (isRecording) { @@ -23,6 +24,7 @@ export default function AudioRecorder() { const fetchConversation = useCallback( async (audioBlob: Blob) => { + setThinking(true); const formData = new FormData(); formData.append("audio", audioBlob, "audio.ogg"); formData.append("messages", JSON.stringify(messages)); @@ -32,6 +34,7 @@ export default function AudioRecorder() { method: "POST", body: formData, }); + setThinking(false); const result = JSON.parse((await response.headers.get("result")) || "{}"); const userMessage = JSON.parse((await response.headers.get("usermessage")) || "{}"); diff --git a/src/components/Experience.tsx b/src/components/Experience.tsx index 1bfa90a..f5edb2b 100644 --- a/src/components/Experience.tsx +++ b/src/components/Experience.tsx @@ -5,6 +5,7 @@ import { Canvas } from "@react-three/fiber"; import { Leva } from "leva"; import { Avatar } from "./Avatar"; +import Thinking from "./Thinking"; function Experience() { return ( @@ -14,6 +15,7 @@ function Experience() { {/* */} + diff --git a/src/components/Thinking.tsx b/src/components/Thinking.tsx new file mode 100644 index 0000000..6789c21 --- /dev/null +++ b/src/components/Thinking.tsx @@ -0,0 +1,28 @@ +import { useFrame } from "@react-three/fiber"; +import React, { useRef } from "react"; + +import { useConversation } from "@/lib/store"; + +function Thinking() { + const thinking = useConversation((state) => state.thinking); + const haloRef = useRef(); + + // Animate the halo rotation if active + useFrame((state, delta) => { + if (thinking && haloRef.current) { + haloRef.current.rotation.z += delta; // Rotate around Z-axis + } + }); + + // Render nothing if not active + if (!thinking) return null; + + return ( + + + + + ); +} + +export default Thinking; diff --git a/src/lib/store.ts b/src/lib/store.ts index 891cb85..9d6d92c 100644 --- a/src/lib/store.ts +++ b/src/lib/store.ts @@ -14,13 +14,17 @@ interface MessageType { interface ConversationState { messageResult: MessageResultType | null; messages: MessageType[]; + thinking: boolean; setMessageResult: (message: MessageResultType | null) => void; addMessage: (message: MessageType) => void; + setThinking: (thinking: boolean) => void; } export const useConversation = create()((set) => ({ messageResult: null, messages: [], + thinking: false, setMessageResult: (messageResult) => set({ messageResult }), addMessage: (message) => set((state) => ({ messages: [...state.messages, message] })), + setThinking: (thinking) => set({ thinking }), }));