Add a thinking visual feedback

This commit is contained in:
maumruiz
2025-02-12 17:36:44 -06:00
parent 69e89f3300
commit 3e158e77b4
4 changed files with 37 additions and 0 deletions

View File

@@ -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")) || "{}");

View File

@@ -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() {
{/* <Canvas shadows camera={{ position: [0, 0, 1], fov: 30 }}> */}
<Canvas shadows camera={{ position: [0, 0, 1], fov: 30 }}>
<Environment preset="warehouse" />
<Thinking />
<Avatar />
</Canvas>
</>

View File

@@ -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 (
<mesh ref={haloRef} position={[0, 0.1, -1]}>
<ringGeometry args={[0.3, 0.4, 16]} />
<meshBasicMaterial color="#00FFFF" transparent opacity={0.7} side={2} />
</mesh>
);
}
export default Thinking;

View File

@@ -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<ConversationState>()((set) => ({
messageResult: null,
messages: [],
thinking: false,
setMessageResult: (messageResult) => set({ messageResult }),
addMessage: (message) => set((state) => ({ messages: [...state.messages, message] })),
setThinking: (thinking) => set({ thinking }),
}));