diff --git a/src/App.tsx b/src/App.tsx
index acec25d..803b84c 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -2,6 +2,7 @@ import { Routes, Route, Link } from 'react-router'
import './App.css'
import TemplatePage from './pages/TemplatePage/Template.tsx'
import Home from './pages/Home/Home.tsx'
+import Robot from './pages/Robot/Robot.tsx';
function App(){
return (
@@ -13,6 +14,7 @@ function App(){
} />
} />
+ } />
diff --git a/src/pages/Home/Home.tsx b/src/pages/Home/Home.tsx
index 71f6b96..cb70de0 100644
--- a/src/pages/Home/Home.tsx
+++ b/src/pages/Home/Home.tsx
@@ -11,6 +11,7 @@ function Home() {
+ Robot Interaction →
Template →
diff --git a/src/pages/Robot/Robot.tsx b/src/pages/Robot/Robot.tsx
new file mode 100644
index 0000000..0038dd9
--- /dev/null
+++ b/src/pages/Robot/Robot.tsx
@@ -0,0 +1,94 @@
+import { useState, useEffect, useRef } from 'react'
+
+export default function Robot() {
+ const [message, setMessage] = useState('');
+
+ const [listening, setListening] = useState(false);
+ const [conversation, setConversation] = useState<{"role": "user" | "assistant", "content": string}[]>([])
+ const conversationRef = useRef(null);
+ const [conversationIndex, setConversationIndex] = useState(0);
+
+ const sendMessage = async () => {
+ try {
+ const response = await fetch("http://localhost:8000/message", {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({ message }),
+ });
+ const data = await response.json();
+ console.log(data);
+ } catch (error) {
+ console.error("Error sending message: ", error);
+ }
+ };
+
+ useEffect(() => {
+ const eventSource = new EventSource("http://localhost:8000/sse");
+
+ eventSource.onmessage = (event) => {
+ try {
+ const data = JSON.parse(event.data);
+ if ("voice_active" in data) setListening(data.voice_active);
+ if ("speech" in data) setConversation(conversation => [...conversation, {"role": "user", "content": data.speech}]);
+ if ("llm_response" in data) setConversation(conversation => [...conversation, {"role": "assistant", "content": data.llm_response}]);
+ } catch {
+ console.log("Unparsable SSE message:", event.data);
+ }
+ };
+
+ return () => {
+ eventSource.close();
+ };
+ }, [conversationIndex]);
+
+ useEffect(() => {
+ if (!conversationRef || !conversationRef.current) return;
+ conversationRef.current.scrollTop = conversationRef.current.scrollHeight;
+ }, [conversation]);
+
+ return (
+ <>
+ Robot interaction
+ Force robot speech
+
+ setMessage(e.target.value)}
+ onKeyDown={(e) => e.key === "Enter" && sendMessage().then(() => setMessage(""))}
+ placeholder="Enter a message"
+ />
+
+
+
+
Conversation
+
Listening {listening ? "🟢" : "🔴"}
+
+ {conversation.map((item, i) => (
+
{item["content"]}
+ ))}
+
+
+
+
+
+
+ >
+ );
+}
diff --git a/src/pages/ServerComms/ServerComms.css b/src/pages/ServerComms/ServerComms.css
deleted file mode 100644
index e69de29..0000000
diff --git a/src/pages/ServerComms/ServerComms.tsx b/src/pages/ServerComms/ServerComms.tsx
deleted file mode 100644
index c16ec81..0000000
--- a/src/pages/ServerComms/ServerComms.tsx
+++ /dev/null
@@ -1,80 +0,0 @@
-import { useState, useEffect } from 'react'
-import { Link } from 'react-router'
-//import Counter from '../../components/components.tsx'
-
-
-//this is your css file where you can style your buttons and such
-//you can still use css parts from App.css, but also overwrite them
-
-function ServerComms() {
- const [message, setMessage] = useState('');
- const [sseMessage, setSseMessage] = useState('');
- const [spoken, setSpoken] = useState("");
-
- const sendMessage = async () => {
- try {
- const response = await fetch("http://localhost:8000/message", {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- },
- body: JSON.stringify({ message }),
- });
- const data = await response.json();
- console.log(data);
- } catch (error) {
- console.error("Error sending message: ", error);
- }
- };
-
- useEffect(() => {
- const eventSource = new EventSource("http://localhost:8000/sse");
-
- eventSource.onmessage = (event) => {
- setSseMessage(event.data);
-
- try {
- const data = JSON.parse(event.data);
- if (data.speech) setSpoken(data.speech);
- } catch {}
- };
-
- return () => {
- eventSource.close();
- };
- }, []);
-
- return (
-
-
- setMessage(e.target.value)}
- onKeyDown={(e) => e.key === "Enter" && sendMessage().then(() => setMessage(""))}
- placeholder="Enter a message"
- />
-
-
-
-
Message from Server (SSE):
-
{sseMessage}
-
-
-
Spoken text (SSE):
-
{spoken}
-
-
- {/* here you link to the homepage, in App.tsx you can link new pages */}
-
-
-
-
-
-
- );
-}
-
-export default ServerComms
\ No newline at end of file